public bool WaitForExit(int exitTime = -1) { using (var wait = new ProcessWaitHandle(proc)) { return(wait.WaitOne(exitTime)); } }
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); }
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) { if (Kernel32.GetExitCodeProcess(handle, out var exitCode) && exitCode != Kernel32.STILL_ACTIVE) { throw new InvalidOperationException("Process has exited"); } } return(handle); }
public bool WaitForExit(TimeSpan timeout) { if (IsInvalid || IsClosed) { return(true); } using (var waitHandle = new ProcessWaitHandle(this)) { return(waitHandle.WaitOne(timeout)); } }
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); }
public int Run() { STARTUPINFO si = new STARTUPINFO(); si.lpDesktop = this.Desktop; PROCESSINFO pi = new PROCESSINFO(); int creationFlags = NORMAL_PRIORITY_CLASS | CREATE_UNICODE_ENVIRONMENT; creationFlags |= this.CreateNoWindow ? CREATE_NO_WINDOW : 0; // This creates the default environment block for this user. If you need // something custom skip te CreateEnvironmentBlock (and DestroyEnvironmentBlock) // calls. You need to handle the allocation of the memory and writing to // it yourself. IntPtr envBlock; if (!CreateEnvironmentBlock(out envBlock, this.mSessionTokenHandle, 0)) { throw new System.ComponentModel.Win32Exception(); } try { CreateProcessAsUser(this.mSessionTokenHandle, this.mApplicationPath, this.CommandLine, IntPtr.Zero, IntPtr.Zero, 0, creationFlags, envBlock, this.WorkingDirectory, si, pi); ProcessWaitHandle waitable = new ProcessWaitHandle(pi.hProcess); if (waitable.WaitOne()) { return pi.dwProcessId; } } catch (Win32Exception) { } finally { DestroyEnvironmentBlock(envBlock); } return -1; }
public bool WaitForExit(TimeSpan timeout) { if (IsInvalid || IsClosed) { return true; } using (var waitHandle = new ProcessWaitHandle(this)) { return waitHandle.WaitOne(timeout); } }
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 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; }
private static void StartProcessAsUser(ProcessStartInfo psi) { string username = psi.UserName; string domain = psi.Domain; SecureString password = psi.Password; string commandLinePath = "\"" + psi.FileName + "\" " + psi.Arguments; string cwd = psi.WorkingDirectory; IntPtr Token = IntPtr.Zero; IntPtr DupedToken = IntPtr.Zero; SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES(); sa.bInheritHandle = false; sa.Length = Marshal.SizeOf(sa); sa.lpSecurityDescriptor = IntPtr.Zero; if (string.IsNullOrEmpty(domain)) { domain = "."; } IntPtr passwordPtr = Marshal.SecureStringToGlobalAllocUnicode(password ?? new SecureString()); try { if (!LogonUser(username, domain, passwordPtr, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref Token)) { var ex = new Win32Exception(); CloseHandle(Token); throw ex; } } finally { Marshal.ZeroFreeGlobalAllocUnicode(passwordPtr); } const uint GENERIC_ALL = 0x10000000; const int SecurityImpersonation = 2; const int TokenType = 1; PROCESS_INFORMATION pi = new PROCESS_INFORMATION(); try { if (!DuplicateTokenEx(Token, GENERIC_ALL, ref sa, SecurityImpersonation, TokenType, ref DupedToken)) { throw new Win32Exception(); } STARTUPINFO si = new STARTUPINFO(); si.cb = Marshal.SizeOf(si); if (!CreateProcessAsUser(DupedToken, null, commandLinePath, ref sa, ref sa, false, 0, (IntPtr)0, cwd, ref si, out pi)) { throw new Win32Exception(); } uint exitCode = 0; bool timeout = false; ProcessWaitHandle waitable = new ProcessWaitHandle(pi.hProcess); if (!waitable.WaitOne(timeoutToKill * 1000)) { timeout = true; using (Process process = Process.GetProcessById((int)pi.dwProcessId)) if (process != null) { process.Kill(); } } else { if (!GetExitCodeProcess(pi.hProcess, out exitCode)) { throw new Win32Exception(); } } ValidateExitCode(timeout ? -10 : (int)exitCode); } finally { CloseHandle(pi.hProcess); CloseHandle(pi.hThread); CloseHandle(DupedToken); CloseHandle(Token); } }