/// <exception cref="InvalidOperationException"></exception> /// <exception cref="FileNotFoundException"></exception> private void StartImpl() { if (State != NonInteractiveProcessState.Ready) { throw new InvalidOperationException("NonInteractiveProcess.Start() cannot be called more than once."); } if (!File.Exists(ExePath)) { throw new FileNotFoundException(string.Format("Unable to Start NonInteractiveProcess: File \"{0}\" does not exist", ExePath)); } using (var process = CreateProcess()) { using (var jobObject = _jobObjectManager.CreateJobObject()) { process.StartInfo.FileName = ExePath; process.StartInfo.Arguments = Arguments.ToString(); process.EnableRaisingEvents = true; process.Exited += ProcessExitedAsync; OnBeforeStart(process); if (BeforeStart != null) { BeforeStart(this, EventArgs.Empty); } process.OutputDataReceived += (sender, args) => HandleStdOut(args.Data); process.ErrorDataReceived += (sender, args) => HandleStdErr(args.Data); Logger.Info(FullCommand); process.Start(); _hasStarted = true; Id = process.Id; Name = process.ProcessName; State = NonInteractiveProcessState.Running; if (_jobObjectManager.IsAssignedToJob(process)) { Logger.Warn("WARNING: Child process already belongs to a Job Object. If the parent process crashes, the child process will continue to run in the background until it finishes executing."); } else { jobObject.Assign(process); jobObject.KillOnClose(); } _stopwatch.Start(); process.BeginOutputReadLine(); process.BeginErrorReadLine(); Logger.InfoFormat("Waiting for process \"{0}\" w/ PID = {1} to exit...", ExePath, Id); OnStart(process); process.WaitForExit(); _hasExited = true; Logger.InfoFormat("Process \"{0}\" w/ PID = {1} exited", ExePath, Id); ExitCode = process.ExitCode; } } }