private void pause() { _started.Wait(); // ensure that the process is not yet in the start-up phase, immediately after the call to Start(). foreach (var childProcess in _process.ChildProcessIds(true).Select(pid => Process.GetProcessById(pid)).Concat(_process)) { foreach (ProcessThread thr in childProcess.Threads) { IntPtr pThread = WinAPI.OpenThread(WinAPI.ThreadAccess.SUSPEND_RESUME, false, (uint)thr.Id); if (pThread == IntPtr.Zero) { continue; } WinAPI.SuspendThread(pThread); WinAPI.CloseHandle(pThread); } } }
private void resume(object _ = null) { lock (_lock) { if (_pauseTimerDue == null || _process == null || State != CommandRunnerState.Started) { return; } // The due time may have changed; wait more if necessary var now = DateTime.UtcNow; if (now < _pauseTimerDue) { _pauseTimer.Change(_pauseTimerDue.Value - now, TimeSpan.FromMilliseconds(-1)); return; } _pauseTimerDue = null; _pauseTimer.Dispose(); _pauseTimer = null; foreach (var childProcess in _process.ChildProcessIds(true).Select(pid => Process.GetProcessById(pid)).Concat(_process)) { foreach (ProcessThread thr in childProcess.Threads) { IntPtr pThread = WinAPI.OpenThread(WinAPI.ThreadAccess.SUSPEND_RESUME, false, (uint)thr.Id); if (pThread == IntPtr.Zero) { continue; } WinAPI.ResumeThread(pThread); WinAPI.CloseHandle(pThread); } } } if (CommandResumed != null) { CommandResumed(); } }