private SafeProcessHandle GetProcessHandle(int access, bool throwIfExited)
{
#if FEATURE_TRACESWITCH
Debug.WriteLineIf(_processTracing.TraceVerbose, "GetProcessHandle(access = 0x" + access.ToString("X8", CultureInfo.InvariantCulture) + ", throwIfExited = " + throwIfExited + ")");
#if DEBUG
if (_processTracing.TraceVerbose) {
StackFrame calledFrom = new StackTrace(true).GetFrame(0);
Debug.WriteLine(" called from " + calledFrom.GetFileName() + ", line " + calledFrom.GetFileLineNumber());
}
#endif
#endif
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.
using (ProcessWaitHandle waitHandle = new ProcessWaitHandle(_processHandle))
{
if (waitHandle.WaitOne(0))
{
if (_haveProcessId)
throw new InvalidOperationException(SR.Format(SR.ProcessHasExited, _processId.ToString(CultureInfo.CurrentCulture)));
else
throw new InvalidOperationException(SR.ProcessHasExitedNoId);
}
}
}
return _processHandle;
}
else
{
EnsureState(State.HaveId | State.IsLocal);
SafeProcessHandle handle = SafeProcessHandle.InvalidHandle;
handle = ProcessManager.OpenProcess(_processId, access, throwIfExited);
if (throwIfExited && (access & Interop.Advapi32.ProcessOptions.PROCESS_QUERY_INFORMATION) != 0)
{
if (Interop.Kernel32.GetExitCodeProcess(handle, out _exitCode) && _exitCode != Interop.Kernel32.HandleOptions.STILL_ACTIVE)
{
throw new InvalidOperationException(SR.Format(SR.ProcessHasExited, _processId.ToString(CultureInfo.CurrentCulture)));
}
}
return handle;
}
}