IntPtr GetProcessHandle(Kernel32.ProcessAccessFlags access, bool throwIfExited) {
if (_haveProcessHandle) {
if (throwIfExited) {
// Since haveProcessHandle is true, we know we have the process handle
// open with at least SYNCHRONIZE access, so we can wait on it with
// zero timeout to see if the process has exited.
ProcessWaitHandle waitHandle = null;
try {
waitHandle = new ProcessWaitHandle(_processHandle);
if (waitHandle.WaitOne(0, false)) {
throw new InvalidOperationException("Process has exited");
}
} finally {
waitHandle?.Close();
}
}
return _processHandle;
}
var handle = Kernel32.OpenProcess(access, false, _inner.Id);
if (throwIfExited && (access & Kernel32.ProcessAccessFlags.QueryInformation) != 0) {
int exitCode;
if (Kernel32.GetExitCodeProcess(handle, out exitCode) && exitCode != Kernel32.STILL_ACTIVE) {
throw new InvalidOperationException("Process has exited");
}
}
return handle;
}