public void AttachProcessWorker(object?owner, IProcessWorker worker, ProcessOptions options) { if (worker == null) { throw new ArgumentNullException(nameof(worker)); } worker.ProcessStarted += (s, e) => { if (options.DisplayMode == ProcessDisplayMode.Interface) { Display(owner, worker); } }; worker.ProcessCompleted += (s, e) => { if ((e.Status == CompletionStatus.Failed || e.Status == CompletionStatus.Timeout) && (options.DisplayMode == ProcessDisplayMode.ErrorOnly || options.DisplayMode == ProcessDisplayMode.Interface)) { DisplayError(owner, worker); } }; }
/// <summary> /// Runs specified process with specified arguments. /// </summary> /// <param name="fileName">The process to start.</param> /// <param name="arguments">The set of arguments to use when starting the process.</param> /// <returns>The process completion status.</returns> /// <exception cref="System.IO.FileNotFoundException">Occurs when the file to run is not found.</exception> /// <exception cref="InvalidOperationException">Occurs when this class instance is already running another process.</exception> public virtual CompletionStatus Run(string fileName, string arguments) { fileName.CheckNotNullOrEmpty(nameof(fileName)); IProcess p; lock (LockToken) { if (WorkProcess != null) { throw new InvalidOperationException(Resources.ProcessWorkerBusy); } p = _factory.Create(); WorkProcess = p; } _output.Clear(); _cancelWork = new CancellationTokenSource(); if (Options == null) { Options = new ProcessOptions(); } p.StartInfo.FileName = fileName; p.StartInfo.Arguments = arguments; CommandWithArgs = $@"""{fileName}"" {arguments}".TrimEnd(); if (OutputType == ProcessOutput.Output) { p.OutputDataReceived += OnDataReceived; } else if (OutputType == ProcessOutput.Error) { p.ErrorDataReceived += OnDataReceived; } if (Options.DisplayMode != ProcessDisplayMode.Native) { //if (Options.DisplayMode == ProcessDisplayMode.Interface && Config.UserInterfaceManager != null) //{ // Config.UserInterfaceManager.Display(Owner, this); //} p.StartInfo.CreateNoWindow = true; p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; if (OutputType == ProcessOutput.Output) { p.StartInfo.RedirectStandardOutput = true; } else if (OutputType == ProcessOutput.Error) { p.StartInfo.RedirectStandardError = true; } p.StartInfo.UseShellExecute = false; } ProcessStarted?.Invoke(this, new ProcessStartedEventArgs(this)); p.Start(); try { if (!p.HasExited) { p.PriorityClass = Options.Priority; } } catch (System.ComponentModel.Win32Exception) { } catch (InvalidOperationException) { } if (Options.DisplayMode != ProcessDisplayMode.Native) { if (OutputType == ProcessOutput.Output) { p.BeginOutputReadLine(); } else if (OutputType == ProcessOutput.Error) { p.BeginErrorReadLine(); } } var timeout = Wait(); // ExitCode is 0 for normal exit. Different value when closing the console. var result = timeout ? CompletionStatus.Timeout : _cancelWork.IsCancellationRequested ? CompletionStatus.Cancelled : p.ExitCode == 0 ? CompletionStatus.Success : CompletionStatus.Failed; _cancelWork = null; // Allow changing CompletionStatus in ProcessCompleted. var completedArgs = new ProcessCompletedEventArgs(result); ProcessCompleted?.Invoke(this, completedArgs); result = completedArgs.Status; LastCompletionStatus = result; //if ((result == CompletionStatus.Failed || result == CompletionStatus.Timeout) && Options.DisplayMode == ProcessDisplayMode.ErrorOnly) //{ // Config.UserInterfaceManager?.DisplayError(Owner, this); //} WorkProcess = null; return(result); }