protected override void OnStart(string[] args) { RunningLoop = Task.Run( () => { try { bool stopping; WriteInfo("Starting Actions Runner Service"); TimeSpan timeBetweenRetries = TimeSpan.FromSeconds(5); lock (ServiceLock) { stopping = Stopping; } while (!stopping) { WriteInfo("Starting Actions Runner listener"); lock (ServiceLock) { RunnerListener = CreateRunnerListener(); RunnerListener.OutputDataReceived += RunnerListener_OutputDataReceived; RunnerListener.ErrorDataReceived += RunnerListener_ErrorDataReceived; RunnerListener.Start(); RunnerListener.BeginOutputReadLine(); RunnerListener.BeginErrorReadLine(); } RunnerListener.WaitForExit(); int exitCode = RunnerListener.ExitCode; // exit code 0 and 1 need stop service // exit code 2 and 3 need restart runner switch (exitCode) { case 0: Stopping = true; WriteInfo(Resource.RunnerExitWithoutError); break; case 1: Stopping = true; WriteInfo(Resource.RunnerExitWithTerminatedError); break; case 2: WriteInfo(Resource.RunnerExitWithError); break; case 3: WriteInfo(Resource.RunnerUpdateInProcess); var updateResult = HandleRunnerUpdate(); if (updateResult == RunnerUpdateResult.Succeed) { WriteInfo(Resource.RunnerUpdateSucceed); } else if (updateResult == RunnerUpdateResult.Failed) { WriteInfo(Resource.RunnerUpdateFailed); Stopping = true; } else if (updateResult == RunnerUpdateResult.SucceedNeedRestart) { WriteInfo(Resource.RunnerUpdateRestartNeeded); _restart = true; ExitCode = int.MaxValue; Stop(); } break; default: WriteInfo(Resource.RunnerExitWithUndefinedReturnCode); break; } if (Stopping) { ExitCode = exitCode; Stop(); } else { // wait for few seconds before restarting the process Thread.Sleep(timeBetweenRetries); } lock (ServiceLock) { RunnerListener.OutputDataReceived -= RunnerListener_OutputDataReceived; RunnerListener.ErrorDataReceived -= RunnerListener_ErrorDataReceived; RunnerListener.Dispose(); RunnerListener = null; stopping = Stopping; } } } catch (Exception exception) { WriteException(exception); ExitCode = 99; Stop(); } }); }