private void ThreadDisplayError(PatcherErrorMessage error, CancellationToken cancellationToken) { PatcherStatistics.DispatchSendEvent(PatcherStatistics.Event.PatcherFailed); try { _state.Value = PatcherState.DisplayingError; DebugLogger.Log(string.Format("Displaying patcher error {0}...", error.Message)); ErrorDialog.Display(error, cancellationToken); DebugLogger.Log(string.Format("Patcher error {0} displayed.", error.Message)); } catch (OperationCanceledException) { DebugLogger.Log(string.Format("Displaying patcher error {0} cancelled.", _userDecision)); } catch (ThreadInterruptedException) { DebugLogger.Log(string.Format("Displaying patcher error {0} interrupted: thread has been interrupted. Rethrowing exception.", error.Message)); throw; } catch (ThreadAbortException) { DebugLogger.Log(string.Format("Displaying patcher error {0} aborted: thread has been aborted. Rethrowing exception.", error.Message)); throw; } catch (Exception) { DebugLogger.LogWarning(string.Format("Error while displaying patcher error {}: an exception has occured. Rethrowing exception.", error.Message)); throw; } }
private void ThreadExecuteUserDecision(CancellationToken cancellationToken) { bool displayWarningInsteadOfError = false; try { _warning.Value = string.Empty; DebugLogger.Log(string.Format("Executing user decision {0}...", _userDecision)); switch (_userDecision) { case UserDecision.None: break; case UserDecision.RepairApp: break; case UserDecision.StartAppAutomatically: case UserDecision.StartApp: ThreadStartApp(); break; case UserDecision.InstallAppAutomatically: displayWarningInsteadOfError = _app.IsFullyInstalled(); ThreadUpdateApp(true, cancellationToken); break; case UserDecision.InstallApp: ThreadUpdateApp(false, cancellationToken); break; case UserDecision.CheckForAppUpdatesAutomatically: displayWarningInsteadOfError = _app.IsFullyInstalled(); ThreadUpdateApp(true, cancellationToken); break; case UserDecision.CheckForAppUpdates: ThreadUpdateApp(false, cancellationToken); break; } DebugLogger.Log(string.Format("User decision {0} execution done.", _userDecision)); } catch (OperationCanceledException) { DebugLogger.Log(string.Format("User decision {0} execution cancelled.", _userDecision)); } catch (UnauthorizedAccessException e) { DebugLogger.Log(string.Format("User decision {0} execution issue: permissions failure.", _userDecision)); DebugLogger.LogException(e); if (ThreadTryRestartWithRequestForPermissions()) { UnityDispatcher.Invoke(Quit); } else { ThreadDisplayError(PatcherErrorMessage.NoPermissions(), cancellationToken); } } catch (ApiConnectionException e) { DebugLogger.LogException(e); if (displayWarningInsteadOfError) { _warning.Value = "Unable to check for updates. Please check your internet connection."; } else { ThreadDisplayError(PatcherErrorMessage.NoInternetConnection(), cancellationToken); } } catch (NotEnoughtDiskSpaceException e) { DebugLogger.LogException(e); ThreadDisplayError(PatcherErrorMessage.NotEnoughDiskSpace(e.RequiredSpace - e.AvailableSpace), cancellationToken); } catch (ThreadInterruptedException) { DebugLogger.Log(string.Format( "User decision {0} execution interrupted: thread has been interrupted. Rethrowing exception.", _userDecision)); throw; } catch (ThreadAbortException) { DebugLogger.Log(string.Format( "User decision {0} execution aborted: thread has been aborted. Rethrowing exception.", _userDecision)); throw; } catch (Exception exception) { DebugLogger.LogWarning(string.Format( "Error while executing user decision {0}: an exception has occured.", _userDecision)); DebugLogger.LogException(exception); if (displayWarningInsteadOfError) { _warning.Value = "Unable to check for updates. Please check your internet connection."; } else { ThreadDisplayError(PatcherErrorMessage.Other(), cancellationToken); } } }
private void ThreadExecution(CancellationToken cancellationToken) { try { _state.Value = PatcherState.None; DebugLogger.Log("Patcher thread started."); try { ThreadLoadPatcherData(); } catch (NonLauncherExecutionException) { try { LauncherUtilities.ExecuteLauncher(); return; } catch (ApplicationException) { ThreadDisplayError(PatcherErrorMessage.NonLauncherExecution(), cancellationToken); return; } finally { Quit(); } } EnsureSingleInstance(); ThreadLoadPatcherConfiguration(); UnityDispatcher.Invoke(() => _app = new App(_data.Value.AppDataPath, _data.Value.AppSecret, _data.Value.OverrideLatestVersionId, _requestTimeoutCalculator)).WaitOne(); PatcherStatistics.TryDispatchSendEvent(PatcherStatistics.Event.PatcherStarted); while (true) { cancellationToken.ThrowIfCancellationRequested(); ThreadWaitForUserDecision(cancellationToken); cancellationToken.ThrowIfCancellationRequested(); ThreadExecuteUserDecision(cancellationToken); } } catch (OperationCanceledException) { DebugLogger.Log("Patcher thread finished: thread has been cancelled."); } catch (ThreadInterruptedException) { DebugLogger.Log("Patcher thread finished: thread has been interrupted."); } catch (ThreadAbortException) { DebugLogger.Log("Patcher thread finished: thread has been aborted."); } catch (MultipleInstancesException exception) { DebugLogger.LogException(exception); Quit(); } catch (Exception exception) { DebugLogger.LogError("Patcher thread failed: an exception has occured."); DebugLogger.LogException(exception); } finally { _state.Value = PatcherState.None; } }