public static bool WaitForExit([NotNull] this Process thisValue, int millisecondsTimeout, bool exitContext, CancellationToken token = default(CancellationToken)) { if (millisecondsTimeout < TimeSpanHelper.INFINITE) { throw new ArgumentOutOfRangeException(nameof(millisecondsTimeout)); } token.ThrowIfCancellationRequested(); if (!IsAwaitable(thisValue)) { return(true); } using (SafeWaitHandle waitHandle = new SafeWaitHandle(thisValue.Handle, false)) { if (!waitHandle.IsAwaitable()) { return(false); } using (ManualResetEvent processFinishedEvent = new ManualResetEvent(false) { SafeWaitHandle = waitHandle }) { return(processFinishedEvent.WaitOne(millisecondsTimeout, true, exitContext, token)); } } }
public static Task <bool> WaitForProcessExitAsync(int pid, WaitHandle awaitableHandle) { if (pid == Win32.INVALID_HANDLE_VALUE.ToInt32()) { return(Task.FromResult(false)); } SafeWaitHandle waitHandle = null; ManualResetEvent processFinishedEvent = null; try { Process process = Process.GetProcessById(pid); if (!process.IsAwaitable()) { return(Task.FromResult(false)); } if (!awaitableHandle.IsAwaitable()) { process.WaitForExit(); return(Task.FromResult(true)); } waitHandle = new SafeWaitHandle(process.Handle, false); if (!waitHandle.IsAwaitable()) { return(Task.FromResult(false)); } processFinishedEvent = new ManualResetEvent(false) { SafeWaitHandle = waitHandle }; if (!awaitableHandle.IsAwaitable()) { return(Task.FromResult(false)); } WaitHandle[] waitHandles = { processFinishedEvent, awaitableHandle }; bool processReallyExited = false; process.Exited += (_, _) => processReallyExited = true; int ndx = waitHandles.WaitAny(); if (ndx != 0) { return(Task.FromResult(false)); } if (!processReallyExited && process.IsAwaitable()) { if (!process.WaitForExit(TimeSpanHelper.HALF)) { ndx = -1; } } return(Task.FromResult(ndx == 0)); } finally { processFinishedEvent?.Close(); ObjectHelper.Dispose(ref processFinishedEvent); waitHandle?.Close(); ObjectHelper.Dispose(ref waitHandle); } }
public static RunOutput RunAndGetOutput([NotNull] string execName, string arguments, RunSettingsBase settings, WaitHandle awaitableHandle) { settings ??= RunSettingsBase.Default; settings.RedirectOutput = true; settings.RedirectError = true; RunOutput output = new RunOutput(); using (Process process = CreateForRun(execName, arguments, settings)) { bool processReallyExited = false; process.Exited += (sender, _) => { Process p = (Process)sender; if (p.IsAssociated()) { try { output.ExitTime = p.ExitTime; output.ExitCode = p.ExitCode; } catch { // ignored } } processReallyExited = true; settings.OnExit?.Invoke(execName, output.ExitTime, output.ExitCode); }; try { bool result = process.Start(); if (!result) { return(null); } if (!settings.JobHandle.IsInvalidHandle()) { ProcessJob.AddProcess(settings.JobHandle, process); } output.StartTime = process.StartTime; settings.OnStart?.Invoke(execName, output.StartTime); AsyncStreamReader outputReader = new AsyncStreamReader(process, process.StandardOutput.BaseStream, data => { if (data == null) { return; } output.Output.Append(data); output.OutputBuilder.Append(data); }, process.StandardOutput.CurrentEncoding); outputReader.BeginRead(); AsyncStreamReader errorReader = new AsyncStreamReader(process, process.StandardError.BaseStream, data => { if (data == null) { return; } output.Error.Append(data); output.OutputBuilder.Append(data); }, process.StandardOutput.CurrentEncoding); errorReader.BeginRead(); if (!awaitableHandle.IsAwaitable()) { process.WaitForExit(); return(output); } SafeWaitHandle waitHandle = null; ManualResetEvent processFinishedEvent = null; try { waitHandle = new SafeWaitHandle(process.Handle, false); if (!waitHandle.IsAwaitable()) { return(null); } processFinishedEvent = new ManualResetEvent(false) { SafeWaitHandle = waitHandle }; if (!awaitableHandle.IsAwaitable()) { return(null); } WaitHandle[] waitHandles = { processFinishedEvent, awaitableHandle }; int ndx = waitHandles.WaitAny(); if (ndx != 0) { return(null); } if (!processReallyExited && process.IsAwaitable()) { if (!process.WaitForExit(TimeSpanHelper.HALF)) { ndx = -1; } } process.Die(); return(ndx != 0 ? null : output); } finally { processFinishedEvent?.Close(); ObjectHelper.Dispose(ref processFinishedEvent); waitHandle?.Close(); ObjectHelper.Dispose(ref waitHandle); } } catch (Win32Exception e) { throw new InvalidOperationException(e.CollectMessages(), e); } } }
public static bool ShellExecAndWaitFor([NotNull] string fileName, string arguments, ShellSettings settings, WaitHandle awaitableHandle) { fileName = fileName.Trim(); if (string.IsNullOrEmpty(fileName)) { throw new ArgumentNullException(nameof(fileName)); } settings ??= ShellSettings.Default; SHELLEXECUTEINFO info = GetShellExecuteInfo(fileName, arguments, settings); using (Process process = InternalShellExec(info)) { if (process == null) { return(false); } if (!settings.JobHandle.IsInvalidHandle()) { ProcessJob.AddProcess(settings.JobHandle, process); } if (!awaitableHandle.IsAwaitable()) { process.WaitForExit(); return(true); } bool processReallyExited = false; process.Exited += (_, _) => processReallyExited = true; SafeWaitHandle waitHandle = null; ManualResetEvent processFinishedEvent = null; try { waitHandle = new SafeWaitHandle(process.Handle, false); if (!waitHandle.IsAwaitable()) { return(false); } processFinishedEvent = new ManualResetEvent(false) { SafeWaitHandle = waitHandle }; if (!awaitableHandle.IsAwaitable()) { return(false); } WaitHandle[] waitHandles = { processFinishedEvent, awaitableHandle }; int ndx = waitHandles.WaitAny(); if (ndx != 0) { return(false); } if (!processReallyExited && process.IsAwaitable()) { if (!process.WaitForExit(TimeSpanHelper.HALF)) { ndx = -1; } } process.Die(); return(ndx == 0); } finally { processFinishedEvent?.Close(); ObjectHelper.Dispose(ref processFinishedEvent); waitHandle?.Close(); ObjectHelper.Dispose(ref waitHandle); } } }