/// <devdoc>
/// Gets a short-term handle to the process, with the given access.
/// If a handle is stored in current process object, then use it.
/// Note that the handle we stored in current process object will have all access we need.
/// </devdoc>
/// <internalonly/>
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 (Interop.Kernel32.ProcessWaitHandle waitHandle = new Interop.Kernel32.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);
}
}
}
}
// If we dispose of our contained handle we'll be in a bad state. NetFX dealt with this
// by doing a try..finally around every usage of GetProcessHandle and only disposed if
// it wasn't our handle.
return(new SafeProcessHandle(_processHandle.DangerousGetHandle(), ownsHandle: false));
}
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);
}
}