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; }
/// <summary> /// Instructs the Process component to wait the specified number of milliseconds for the associated process to exit. /// </summary> private bool WaitForExitCore(int milliseconds) { SafeProcessHandle handle = null; try { handle = GetProcessHandle(Interop.Advapi32.ProcessOptions.SYNCHRONIZE, false); if (handle.IsInvalid) { return(true); } using (ProcessWaitHandle processWaitHandle = new ProcessWaitHandle(handle)) { return(_signaled = processWaitHandle.WaitOne(milliseconds)); } } finally { // If we have a hard timeout, we cannot wait for the streams if (_output != null && milliseconds == Timeout.Infinite) { _output.WaitUtilEOF(); } if (_error != null && milliseconds == Timeout.Infinite) { _error.WaitUtilEOF(); } handle?.Dispose(); } }
/// <summary>Checks whether the process has exited and updates state accordingly.</summary> private void UpdateHasExited() { SafeProcessHandle handle = null; try { handle = GetProcessHandle(Interop.Advapi32.ProcessOptions.PROCESS_QUERY_LIMITED_INFORMATION | Interop.Advapi32.ProcessOptions.SYNCHRONIZE, false); if (handle.IsInvalid) { _exited = true; } else { int localExitCode; // Although this is the wrong way to check whether the process has exited, // it was historically the way we checked for it, and a lot of code then took a dependency on // the fact that this would always be set before the pipes were closed, so they would read // the exit code out after calling ReadToEnd() or standard output or standard error. In order // to allow 259 to function as a valid exit code and to break as few people as possible that // took the ReadToEnd dependency, we check for an exit code before doing the more correct // check to see if we have been signaled. if (Interop.Kernel32.GetExitCodeProcess(handle, out localExitCode) && localExitCode != Interop.Kernel32.HandleOptions.STILL_ACTIVE) { _exitCode = localExitCode; _exited = true; } else { // The best check for exit is that the kernel process object handle is invalid, // or that it is valid and signaled. Checking if the exit code != STILL_ACTIVE // does not guarantee the process is closed, // since some process could return an actual STILL_ACTIVE exit code (259). if (!_signaled) // if we just came from WaitForExit, don't repeat { using (var wh = new ProcessWaitHandle(handle)) { _signaled = wh.WaitOne(0); } } if (_signaled) { if (!Interop.Kernel32.GetExitCodeProcess(handle, out localExitCode)) { throw new Win32Exception(); } _exitCode = localExitCode; _exited = true; } } } } finally { ReleaseProcessHandle(handle); } }
/// <summary> /// Instructs the Process component to wait the specified number of milliseconds for the associated process to exit. /// </summary> public bool WaitForExit(int milliseconds) { SafeProcessHandle handle = null; bool exited; ProcessWaitHandle processWaitHandle = null; try { handle = GetProcessHandle(Interop.SYNCHRONIZE, false); if (handle.IsInvalid) { exited = true; } else { processWaitHandle = new ProcessWaitHandle(handle); if (processWaitHandle.WaitOne(milliseconds)) { exited = true; _signaled = true; } else { exited = false; _signaled = false; } } } finally { if (processWaitHandle != null) { processWaitHandle.Dispose(); } // If we have a hard timeout, we cannot wait for the streams if (_output != null && milliseconds == -1) { _output.WaitUtilEOF(); } if (_error != null && milliseconds == -1) { _error.WaitUtilEOF(); } ReleaseProcessHandle(handle); } if (exited && _watchForExit) { RaiseOnExited(); } return(exited); }
/// <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 (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); } } } } // 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); } }
/// <summary> /// Instructs the Process component to wait the specified number of milliseconds for the associated process to exit. /// </summary> private bool WaitForExitCore(int milliseconds) { SafeProcessHandle handle = null; bool exited; ProcessWaitHandle processWaitHandle = null; try { handle = GetProcessHandle(Interop.Advapi32.ProcessOptions.SYNCHRONIZE, false); if (handle.IsInvalid) { exited = true; } else { processWaitHandle = new ProcessWaitHandle(handle); if (processWaitHandle.WaitOne(milliseconds)) { exited = true; _signaled = true; } else { exited = false; _signaled = false; } } } finally { if (processWaitHandle != null) { processWaitHandle.Dispose(); } // If we have a hard timeout, we cannot wait for the streams if (_output != null && milliseconds == Timeout.Infinite) { _output.WaitUtilEOF(); } if (_error != null && milliseconds == Timeout.Infinite) { _error.WaitUtilEOF(); } ReleaseProcessHandle(handle); } return(exited); }
/// <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 (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.mincore.ProcessOptions.PROCESS_QUERY_INFORMATION) != 0) { if (Interop.mincore.GetExitCodeProcess(handle, out _exitCode) && _exitCode != Interop.mincore.HandleOptions.STILL_ACTIVE) { throw new InvalidOperationException(SR.Format(SR.ProcessHasExited, _processId.ToString(CultureInfo.CurrentCulture))); } } return(handle); } }
/// <summary> /// Instructs the Process component to wait the specified number of milliseconds for the associated process to exit. /// </summary> private bool WaitForExitCore(int milliseconds) { SafeProcessHandle handle = null; bool exited; ProcessWaitHandle processWaitHandle = null; try { handle = GetProcessHandle(Interop.mincore.ProcessOptions.SYNCHRONIZE, false); if (handle.IsInvalid) { exited = true; } else { processWaitHandle = new ProcessWaitHandle(handle); if (processWaitHandle.WaitOne(milliseconds)) { exited = true; _signaled = true; } else { exited = false; _signaled = false; } } } finally { if (processWaitHandle != null) { processWaitHandle.Dispose(); } // If we have a hard timeout, we cannot wait for the streams if (_output != null && milliseconds == Timeout.Infinite) { _output.WaitUtilEOF(); } if (_error != null && milliseconds == Timeout.Infinite) { _error.WaitUtilEOF(); } ReleaseProcessHandle(handle); } return exited; }
/// <summary>Checks whether the process has exited and updates state accordingly.</summary> private void UpdateHasExited() { SafeProcessHandle handle = null; try { handle = GetProcessHandle(Interop.mincore.ProcessOptions.PROCESS_QUERY_LIMITED_INFORMATION | Interop.mincore.ProcessOptions.SYNCHRONIZE, false); if (handle.IsInvalid) { _exited = true; } else { int localExitCode; // Although this is the wrong way to check whether the process has exited, // it was historically the way we checked for it, and a lot of code then took a dependency on // the fact that this would always be set before the pipes were closed, so they would read // the exit code out after calling ReadToEnd() or standard output or standard error. In order // to allow 259 to function as a valid exit code and to break as few people as possible that // took the ReadToEnd dependency, we check for an exit code before doing the more correct // check to see if we have been signalled. if (Interop.mincore.GetExitCodeProcess(handle, out localExitCode) && localExitCode != Interop.mincore.HandleOptions.STILL_ACTIVE) { _exitCode = localExitCode; _exited = true; } else { // The best check for exit is that the kernel process object handle is invalid, // or that it is valid and signaled. Checking if the exit code != STILL_ACTIVE // does not guarantee the process is closed, // since some process could return an actual STILL_ACTIVE exit code (259). if (!_signaled) // if we just came from WaitForExit, don't repeat { using (var wh = new ProcessWaitHandle(handle)) { _signaled = wh.WaitOne(0); } } if (_signaled) { if (!Interop.mincore.GetExitCodeProcess(handle, out localExitCode)) throw new Win32Exception(); _exitCode = localExitCode; _exited = true; } } } } finally { ReleaseProcessHandle(handle); } }
private Microsoft.Win32.SafeHandles.SafeProcessHandle GetProcessHandle(int access, bool throwIfExited) { if (this.haveProcessHandle) { if (throwIfExited) { ProcessWaitHandle handle = null; try { handle = new ProcessWaitHandle(this.m_processHandle); if (handle.WaitOne(0, false)) { if (this.haveProcessId) { throw new InvalidOperationException(SR.GetString("ProcessHasExited", new object[] { this.processId.ToString(CultureInfo.CurrentCulture) })); } throw new InvalidOperationException(SR.GetString("ProcessHasExitedNoId")); } } finally { if (handle != null) { handle.Close(); } } } return this.m_processHandle; } this.EnsureState(State.IsLocal | State.HaveId); Microsoft.Win32.SafeHandles.SafeProcessHandle invalidHandle = Microsoft.Win32.SafeHandles.SafeProcessHandle.InvalidHandle; invalidHandle = ProcessManager.OpenProcess(this.processId, access, throwIfExited); if ((throwIfExited && ((access & 0x400) != 0)) && (Microsoft.Win32.NativeMethods.GetExitCodeProcess(invalidHandle, out this.exitCode) && (this.exitCode != 0x103))) { throw new InvalidOperationException(SR.GetString("ProcessHasExited", new object[] { this.processId.ToString(CultureInfo.CurrentCulture) })); } return invalidHandle; }
private static unsafe int ExecWaitWithCaptureUnimpersonated(SafeUserTokenHandle userToken, string cmd, string currentDir, TempFileCollection tempFiles, ref string outputName, ref string errorName, string trueCmdLine) { IntSecurity.UnmanagedCode.Demand(); FileStream output; FileStream error; int retValue = 0; if (outputName == null || outputName.Length == 0) outputName = tempFiles.AddExtension("out"); if (errorName == null || errorName.Length == 0) errorName = tempFiles.AddExtension("err"); // Create the files output = CreateInheritedFile(outputName); error = CreateInheritedFile(errorName); bool success = false; SafeNativeMethods.PROCESS_INFORMATION pi = new SafeNativeMethods.PROCESS_INFORMATION(); SafeProcessHandle procSH = new SafeProcessHandle(); SafeThreadHandle threadSH = new SafeThreadHandle(); SafeUserTokenHandle primaryToken = null; try { // Output the command line... StreamWriter sw = new StreamWriter(output, Encoding.UTF8); sw.Write(currentDir); sw.Write("> "); // 'true' command line is used in case the command line points to // a response file sw.WriteLine(trueCmdLine != null ? trueCmdLine : cmd); sw.WriteLine(); sw.WriteLine(); sw.Flush(); NativeMethods.STARTUPINFO si = new NativeMethods.STARTUPINFO(); si.cb = Marshal.SizeOf(si); #if FEATURE_PAL si.dwFlags = NativeMethods.STARTF_USESTDHANDLES; #else //!FEATURE_PAL si.dwFlags = NativeMethods.STARTF_USESTDHANDLES | NativeMethods.STARTF_USESHOWWINDOW; si.wShowWindow = NativeMethods.SW_HIDE; #endif //!FEATURE_PAL si.hStdOutput = output.SafeFileHandle; si.hStdError = error.SafeFileHandle; si.hStdInput = new SafeFileHandle(UnsafeNativeMethods.GetStdHandle(NativeMethods.STD_INPUT_HANDLE), false); // // Prepare the environment // #if PLATFORM_UNIX StringDictionary environment = new CaseSensitiveStringDictionary(); #else StringDictionary environment = new StringDictionary (); #endif // PLATFORM_UNIX // Add the current environment foreach ( DictionaryEntry entry in Environment.GetEnvironmentVariables () ) environment[(string) entry.Key] = (string) entry.Value; // Add the flag to indicate restricted security in the process environment["_ClrRestrictSecAttributes"] = "1"; #if DEBUG environment["OANOCACHE"] = "1"; #endif // set up the environment block parameter byte[] environmentBytes = EnvironmentBlock.ToByteArray(environment, false); fixed (byte* environmentBytesPtr = environmentBytes) { IntPtr environmentPtr = new IntPtr((void*)environmentBytesPtr); if (userToken == null || userToken.IsInvalid) { RuntimeHelpers.PrepareConstrainedRegions(); try {} finally { success = NativeMethods.CreateProcess( null, // String lpApplicationName, new StringBuilder(cmd), // String lpCommandLine, null, // SECURITY_ATTRIBUTES lpProcessAttributes, null, // SECURITY_ATTRIBUTES lpThreadAttributes, true, // bool bInheritHandles, 0, // int dwCreationFlags, environmentPtr, // IntPtr lpEnvironment, currentDir, // String lpCurrentDirectory, si, // STARTUPINFO lpStartupInfo, pi); // PROCESS_INFORMATION lpProcessInformation); if ( pi.hProcess!= (IntPtr)0 && pi.hProcess!= (IntPtr)NativeMethods.INVALID_HANDLE_VALUE) procSH.InitialSetHandle(pi.hProcess); if ( pi.hThread != (IntPtr)0 && pi.hThread != (IntPtr)NativeMethods.INVALID_HANDLE_VALUE) threadSH.InitialSetHandle(pi.hThread); } } else { #if FEATURE_PAL throw new NotSupportedException(); #else success = SafeUserTokenHandle.DuplicateTokenEx( userToken, NativeMethods.TOKEN_ALL_ACCESS, null, NativeMethods.IMPERSONATION_LEVEL_SecurityImpersonation, NativeMethods.TOKEN_TYPE_TokenPrimary, out primaryToken ); if (success) { RuntimeHelpers.PrepareConstrainedRegions(); try {} finally { success = NativeMethods.CreateProcessAsUser( primaryToken, // int token, null, // String lpApplicationName, cmd, // String lpCommandLine, null, // SECURITY_ATTRIBUTES lpProcessAttributes, null, // SECURITY_ATTRIBUTES lpThreadAttributes, true, // bool bInheritHandles, 0, // int dwCreationFlags, new HandleRef(null, environmentPtr), // IntPtr lpEnvironment, currentDir, // String lpCurrentDirectory, si, // STARTUPINFO lpStartupInfo, pi); // PROCESS_INFORMATION lpProcessInformation); if ( pi.hProcess!= (IntPtr)0 && pi.hProcess!= (IntPtr)NativeMethods.INVALID_HANDLE_VALUE) procSH.InitialSetHandle(pi.hProcess); if ( pi.hThread != (IntPtr)0 && pi.hThread != (IntPtr)NativeMethods.INVALID_HANDLE_VALUE) threadSH.InitialSetHandle(pi.hThread); } } #endif // !FEATURE_PAL } } } finally { // Close the file handles if (!success && (primaryToken != null && !primaryToken.IsInvalid)) { primaryToken.Close(); primaryToken = null; } output.Close(); error.Close(); } if (success) { try { bool signaled; ProcessWaitHandle pwh = null; try { pwh = new ProcessWaitHandle(procSH); signaled = pwh.WaitOne(ProcessTimeOut, false); } finally { if (pwh != null) pwh.Close(); } // Check for timeout if (!signaled) { throw new ExternalException(SR.GetString(SR.ExecTimeout, cmd), NativeMethods.WAIT_TIMEOUT); } // Check the process's exit code int status = NativeMethods.STILL_ACTIVE; if (!NativeMethods.GetExitCodeProcess(procSH, out status)) { throw new ExternalException(SR.GetString(SR.ExecCantGetRetCode, cmd), Marshal.GetLastWin32Error()); } retValue = status; } finally { procSH.Close(); threadSH.Close(); if (primaryToken != null && !primaryToken.IsInvalid) primaryToken.Close(); } } else { int err = Marshal.GetLastWin32Error(); if (err == NativeMethods.ERROR_NOT_ENOUGH_MEMORY) throw new OutOfMemoryException(); Win32Exception win32Exception = new Win32Exception(err); ExternalException ex = new ExternalException(SR.GetString(SR.ExecCantExec, cmd), win32Exception); throw ex; } return retValue; }
private unsafe void VerifyLifetime(InstanceEntry* currentInstancePointer) { Debug.Assert(currentInstancePointer->RefCount != 0, "RefCount must be 1 for instances passed to VerifyLifetime"); CounterEntry* counter = (CounterEntry*) ResolveOffset(currentInstancePointer->FirstCounterOffset, CounterEntrySize); if (counter->LifetimeOffset != 0) { ProcessLifetimeEntry* lifetime = (ProcessLifetimeEntry*) ResolveOffset(counter->LifetimeOffset, ProcessLifetimeEntrySize); if (lifetime->LifetimeType == (int) PerformanceCounterInstanceLifetime.Process) { int pid = lifetime->ProcessId; long startTime = lifetime->StartupTime; if (pid != 0) { // Optimize for this process if (pid == ProcessData.ProcessId) { if ((ProcessData.StartupTime != -1) && (startTime != -1) && (ProcessData.StartupTime != startTime)) { // Process id got recycled. Reclaim this instance. currentInstancePointer->RefCount = 0; return; } } else { long processStartTime; using (SafeProcessHandle procHandle = SafeProcessHandle.OpenProcess(NativeMethods.PROCESS_QUERY_INFORMATION, false, pid)) { int error = Marshal.GetLastWin32Error(); if ((error == NativeMethods.ERROR_INVALID_PARAMETER) && procHandle.IsInvalid) { // The process is dead. Reclaim this instance. Note that we only clear the refcount here. // If we tried to clear the pid and startup time as well, we would have a ---- where // we could clear the pid/startup time but not the refcount. currentInstancePointer->RefCount = 0; return; } // Defer cleaning the instance when we had previously encountered errors in // recording process start time (i.e, when startTime == -1) until after the // process id is not valid (which will be caught in the if check above) if (!procHandle.IsInvalid && startTime != -1) { long temp; if (NativeMethods.GetProcessTimes(procHandle, out processStartTime, out temp, out temp, out temp)) { if (processStartTime != startTime) { // The process is dead but a new one is using the same pid. Reclaim this instance. currentInstancePointer->RefCount = 0; return; } } } } // Check to see if the process handle has been signaled by the kernel. If this is the case then it's safe // to reclaim the instance as the process is in the process of exiting. using (SafeProcessHandle procHandle = SafeProcessHandle.OpenProcess(NativeMethods.SYNCHRONIZE, false, pid)) { if (!procHandle.IsInvalid) { using (ProcessWaitHandle wh = new ProcessWaitHandle(procHandle)) { if (wh.WaitOne(0, false)) { // Process has exited currentInstancePointer->RefCount = 0; return; } } } } } } } } }
private SafeProcessHandle GetProcessHandle(int access, bool throwIfExited) { if (haveProcessHandle) { if (throwIfExited) { ProcessWaitHandle processWaitHandle = null; try { processWaitHandle = new ProcessWaitHandle(m_processHandle); if (processWaitHandle.WaitOne(0, false)) { if (haveProcessId) { throw new InvalidOperationException("ProcessHasExited"); } throw new InvalidOperationException("ProcessHasExitedNoId"); } } finally { if (processWaitHandle != null) { processWaitHandle.Close(); } } } return m_processHandle; } EnsureState((Process2.State)3); SafeProcessHandle safeProcessHandle = SafeProcessHandle.InvalidHandle; safeProcessHandle = ProcessManager.OpenProcess(processId, access, throwIfExited); if (throwIfExited && (access & 1024) != 0 && NativeMethods.GetExitCodeProcess(safeProcessHandle, out exitCode) && exitCode != 259) { throw new InvalidOperationException(); } return safeProcessHandle; }
public bool WaitForExit(int milliseconds) { SafeProcessHandle safeProcessHandle = null; ProcessWaitHandle processWaitHandle = null; bool flag; try { safeProcessHandle = GetProcessHandle(1048576, false); if (safeProcessHandle.IsInvalid) { flag = true; } else { processWaitHandle = new ProcessWaitHandle(safeProcessHandle); if (processWaitHandle.WaitOne(milliseconds, false)) { flag = true; signaled = true; } else { flag = false; signaled = false; } } } finally { if (processWaitHandle != null) { processWaitHandle.Close(); } if (output != null && milliseconds == -1) { output.WaitUtilEOF(); } if (error != null && milliseconds == -1) { error.WaitUtilEOF(); } ReleaseProcessHandle(safeProcessHandle); } if (flag && watchForExit) { RaiseOnExited(); } return flag; }
public bool WaitForExit(int milliseconds) { Microsoft.Win32.SafeHandles.SafeProcessHandle processHandle = null; bool flag; ProcessWaitHandle handle2 = null; try { processHandle = this.GetProcessHandle(0x100000, false); if (processHandle.IsInvalid) { flag = true; } else { handle2 = new ProcessWaitHandle(processHandle); if (handle2.WaitOne(milliseconds, false)) { flag = true; this.signaled = true; } else { flag = false; this.signaled = false; } } } finally { if (handle2 != null) { handle2.Close(); } if ((this.output != null) && (milliseconds == -1)) { this.output.WaitUtilEOF(); } if ((this.error != null) && (milliseconds == -1)) { this.error.WaitUtilEOF(); } this.ReleaseProcessHandle(processHandle); } if (flag && this.watchForExit) { this.RaiseOnExited(); } return flag; }
private unsafe void VerifyLifetime(InstanceEntry* currentInstancePointer) { CounterEntry* entryPtr = (CounterEntry*) this.ResolveOffset(currentInstancePointer.FirstCounterOffset, CounterEntrySize); if (entryPtr->LifetimeOffset != 0) { ProcessLifetimeEntry* entryPtr2 = (ProcessLifetimeEntry*) this.ResolveOffset(entryPtr->LifetimeOffset, ProcessLifetimeEntrySize); if (entryPtr2->LifetimeType == 1) { int processId = entryPtr2->ProcessId; long startupTime = entryPtr2->StartupTime; if (processId != 0) { if (processId == ProcessData.ProcessId) { if (((ProcessData.StartupTime != -1L) && (startupTime != -1L)) && (ProcessData.StartupTime != startupTime)) { currentInstancePointer.RefCount = 0; } } else { using (Microsoft.Win32.SafeHandles.SafeProcessHandle handle = Microsoft.Win32.SafeHandles.SafeProcessHandle.OpenProcess(0x400, false, processId)) { long num3; long num5; if ((Marshal.GetLastWin32Error() == 0x57) && handle.IsInvalid) { currentInstancePointer.RefCount = 0; return; } if ((!handle.IsInvalid && (startupTime != -1L)) && (Microsoft.Win32.NativeMethods.GetProcessTimes(handle, out num3, out num5, out num5, out num5) && (num3 != startupTime))) { currentInstancePointer.RefCount = 0; return; } } using (Microsoft.Win32.SafeHandles.SafeProcessHandle handle2 = Microsoft.Win32.SafeHandles.SafeProcessHandle.OpenProcess(0x100000, false, processId)) { if (!handle2.IsInvalid) { using (ProcessWaitHandle handle3 = new ProcessWaitHandle(handle2)) { if (handle3.WaitOne(0, false)) { currentInstancePointer.RefCount = 0; } } } } } } } } }
public bool WaitForExit(int millisecondsTimeout) { if (hasExited) return true; if (!wasStarted) throw new InvalidOperationException("Process was not yet started"); if (safeProcessHandle.IsClosed) throw new ObjectDisposedException("ProcessRunner"); using (var waitHandle = new ProcessWaitHandle(safeProcessHandle)) { if (waitHandle.WaitOne(millisecondsTimeout, false)) { if (!GetExitCodeProcess(safeProcessHandle, out exitCode)) throw new Win32Exception(); // Wait until the output is processed // if (standardOutputTask != null) // standardOutputTask.Wait(); // if (standardErrorTask != null) // standardErrorTask.Wait(); hasExited = true; } } return hasExited; }
public bool WaitForExitSafe(int milliseconds) { var handle = IntPtr.Zero; bool exited; ProcessWaitHandle processWaitHandle = null; try { handle = GetProcessHandle(Kernel32.ProcessAccessFlags.Synchronize, false); if (handle == IntPtr.Zero || handle == new IntPtr(-1)) { exited = true; } else { processWaitHandle = new ProcessWaitHandle(handle); if (processWaitHandle.WaitOne(milliseconds, false)) { exited = true; _signaled = true; } else { exited = false; _signaled = false; } } } finally { processWaitHandle?.Close(); ReleaseProcessHandle(handle); } if (exited && _watchForExit) { RaiseOnExited(); } return exited; }
/// <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 (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.mincore.ProcessOptions.PROCESS_QUERY_INFORMATION) != 0) { if (Interop.mincore.GetExitCodeProcess(handle, out _exitCode) && _exitCode != Interop.mincore.HandleOptions.STILL_ACTIVE) { throw new InvalidOperationException(SR.Format(SR.ProcessHasExited, _processId.ToString(CultureInfo.CurrentCulture))); } } return handle; } }
private static unsafe int ExecWaitWithCaptureUnimpersonated(SafeUserTokenHandle userToken, string cmd, string currentDir, TempFileCollection tempFiles, ref string outputName, ref string errorName, string trueCmdLine) { IntSecurity.UnmanagedCode.Demand(); if ((outputName == null) || (outputName.Length == 0)) { outputName = tempFiles.AddExtension("out"); } if ((errorName == null) || (errorName.Length == 0)) { errorName = tempFiles.AddExtension("err"); } FileStream stream = CreateInheritedFile(outputName); FileStream stream2 = CreateInheritedFile(errorName); bool flag = false; Microsoft.Win32.SafeNativeMethods.PROCESS_INFORMATION lpProcessInformation = new Microsoft.Win32.SafeNativeMethods.PROCESS_INFORMATION(); Microsoft.Win32.SafeHandles.SafeProcessHandle processHandle = new Microsoft.Win32.SafeHandles.SafeProcessHandle(); Microsoft.Win32.SafeHandles.SafeThreadHandle handle2 = new Microsoft.Win32.SafeHandles.SafeThreadHandle(); SafeUserTokenHandle hNewToken = null; try { Microsoft.Win32.NativeMethods.STARTUPINFO startupinfo; StreamWriter writer = new StreamWriter(stream, Encoding.UTF8); writer.Write(currentDir); writer.Write("> "); writer.WriteLine((trueCmdLine != null) ? trueCmdLine : cmd); writer.WriteLine(); writer.WriteLine(); writer.Flush(); startupinfo = new Microsoft.Win32.NativeMethods.STARTUPINFO { cb = Marshal.SizeOf(startupinfo), dwFlags = 0x101, wShowWindow = 0, hStdOutput = stream.SafeFileHandle, hStdError = stream2.SafeFileHandle, hStdInput = new SafeFileHandle(Microsoft.Win32.UnsafeNativeMethods.GetStdHandle(-10), false) }; StringDictionary sd = new StringDictionary(); foreach (DictionaryEntry entry in Environment.GetEnvironmentVariables()) { sd[(string) entry.Key] = (string) entry.Value; } sd["_ClrRestrictSecAttributes"] = "1"; byte[] buffer = EnvironmentBlock.ToByteArray(sd, false); try { fixed (byte* numRef = buffer) { IntPtr lpEnvironment = new IntPtr((void*) numRef); if ((userToken == null) || userToken.IsInvalid) { RuntimeHelpers.PrepareConstrainedRegions(); try { goto Label_0325; } finally { flag = Microsoft.Win32.NativeMethods.CreateProcess(null, new StringBuilder(cmd), null, null, true, 0, lpEnvironment, currentDir, startupinfo, lpProcessInformation); if ((lpProcessInformation.hProcess != IntPtr.Zero) && (lpProcessInformation.hProcess != Microsoft.Win32.NativeMethods.INVALID_HANDLE_VALUE)) { processHandle.InitialSetHandle(lpProcessInformation.hProcess); } if ((lpProcessInformation.hThread != IntPtr.Zero) && (lpProcessInformation.hThread != Microsoft.Win32.NativeMethods.INVALID_HANDLE_VALUE)) { handle2.InitialSetHandle(lpProcessInformation.hThread); } } } flag = SafeUserTokenHandle.DuplicateTokenEx(userToken, 0xf01ff, null, 2, 1, out hNewToken); if (flag) { RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { flag = Microsoft.Win32.NativeMethods.CreateProcessAsUser(hNewToken, null, cmd, null, null, true, 0, new HandleRef(null, lpEnvironment), currentDir, startupinfo, lpProcessInformation); if ((lpProcessInformation.hProcess != IntPtr.Zero) && (lpProcessInformation.hProcess != Microsoft.Win32.NativeMethods.INVALID_HANDLE_VALUE)) { processHandle.InitialSetHandle(lpProcessInformation.hProcess); } if ((lpProcessInformation.hThread != IntPtr.Zero) && (lpProcessInformation.hThread != Microsoft.Win32.NativeMethods.INVALID_HANDLE_VALUE)) { handle2.InitialSetHandle(lpProcessInformation.hThread); } } } } } finally { numRef = null; } } finally { if ((!flag && (hNewToken != null)) && !hNewToken.IsInvalid) { hNewToken.Close(); hNewToken = null; } stream.Close(); stream2.Close(); } Label_0325: if (flag) { try { bool flag2; ProcessWaitHandle handle4 = null; try { handle4 = new ProcessWaitHandle(processHandle); flag2 = handle4.WaitOne(0x927c0, false); } finally { if (handle4 != null) { handle4.Close(); } } if (!flag2) { throw new ExternalException(SR.GetString("ExecTimeout", new object[] { cmd }), 0x102); } int exitCode = 0x103; if (!Microsoft.Win32.NativeMethods.GetExitCodeProcess(processHandle, out exitCode)) { throw new ExternalException(SR.GetString("ExecCantGetRetCode", new object[] { cmd }), Marshal.GetLastWin32Error()); } return exitCode; } finally { processHandle.Close(); handle2.Close(); if ((hNewToken != null) && !hNewToken.IsInvalid) { hNewToken.Close(); } } } int error = Marshal.GetLastWin32Error(); if (error == 8) { throw new OutOfMemoryException(); } Win32Exception inner = new Win32Exception(error); ExternalException exception2 = new ExternalException(SR.GetString("ExecCantExec", new object[] { cmd }), inner); throw exception2; }