Пример #1
0
 public bool WaitForExit(int exitTime = -1)
 {
     using (var wait = new ProcessWaitHandle(proc))
     {
         return(wait.WaitOne(exitTime));
     }
 }
Пример #2
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);
 }
Пример #3
0
        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);
        }
Пример #4
0
 public bool WaitForExit(TimeSpan timeout)
 {
     if (IsInvalid || IsClosed)
     {
         return(true);
     }
     using (var waitHandle = new ProcessWaitHandle(this))
     {
         return(waitHandle.WaitOne(timeout));
     }
 }
Пример #5
0
        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);
        }
Пример #6
0
        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;
        }
Пример #7
0
 public bool WaitForExit(TimeSpan timeout)
 {
     if (IsInvalid || IsClosed)
     {
         return true;
     }
     using (var waitHandle = new ProcessWaitHandle(this))
     {
         return waitHandle.WaitOne(timeout);
     }
 }
Пример #8
0
        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;
        }
Пример #10
0
        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);
            }
        }