示例#1
0
        public Process LaunchProcessSuspended(ProcessStartInfo startInfo, bool inheritHandle = false)
        {
            string commandLine;

            if (!string.IsNullOrWhiteSpace(startInfo.Verb))
            {
                commandLine = string.Format("-runverb -verb \"{0}\" -exefile \"{1}\"",
                                            startInfo.Verb.Trim(), startInfo.FileName.Trim());

                string tempArg = startInfo.Arguments.Trim();
                if (!string.IsNullOrWhiteSpace(tempArg))
                {
                    commandLine += string.Format(" -arg \"{0}\"", tempArg);
                }

                startInfo.FileName = BootstrapProcess;
            }
            else
            {
                commandLine = startInfo.Arguments;
            }

            commandLine = BuildCommandLine(startInfo.FileName.Trim(), commandLine.Trim()).ToString();

            var      startupInfo       = new STARTUPINFO();
            var      processInfo       = new PROCESS_INFORMATION();
            bool     retVal            = false;
            int      errorCode         = 0;
            GCHandle environmentHandle = new GCHandle();

            try
            {
                // set up the creation flags paramater
                var creationFlags = ProcessCreationFlags.CREATE_SUSPENDED;

                if (startInfo.CreateNoWindow)
                {
                    creationFlags |= ProcessCreationFlags.CREATE_NO_WINDOW;
                }

                // set up the environment block parameter
                IntPtr environmentPtr = (IntPtr)0;
                if (startInfo.EnvironmentVariables != null)
                {
                    creationFlags |= ProcessCreationFlags.CREATE_UNICODE_ENVIRONMENT;
                    byte[] environmentBytes = EnvironmentBlock.ToByteArray(startInfo.EnvironmentVariables, true);
                    environmentHandle = GCHandle.Alloc(environmentBytes, GCHandleType.Pinned);
                    environmentPtr    = environmentHandle.AddrOfPinnedObject();
                }

                //fix working dir
                string workingDirectory = startInfo.WorkingDirectory;
                if (workingDirectory == string.Empty)
                {
                    workingDirectory = Environment.CurrentDirectory;
                }

                try { }
                finally
                {
                    retVal = NativeMethods.CreateProcess(
                        null,                    // we don't need this since all the info is in commandLine
                        commandLine,             // pointer to the command line string
                        IntPtr.Zero,             // pointer to process security attributes, we don't need to inheriat the handle
                        IntPtr.Zero,             // pointer to thread security attributes
                        inheritHandle,           // handle inheritance flag
                        creationFlags,           // creation flags
                        environmentPtr,          // pointer to new environment block
                        workingDirectory,        // pointer to current directory name
                        ref startupInfo,         // pointer to STARTUPINFO
                        out processInfo          // pointer to PROCESS_INFORMATION
                        );
                    if (!retVal)
                    {
                        errorCode = Marshal.GetLastWin32Error();
                    }
                    if (processInfo.hProcess != (IntPtr)0 && processInfo.hProcess != (IntPtr)NativeMethods.INVALID_HANDLE_VALUE)
                    {
                        _pid        = processInfo.dwProcessId;
                        _procHandle = processInfo.hProcess;
                    }
                    if (processInfo.hThread != (IntPtr)0 && processInfo.hThread != (IntPtr)NativeMethods.INVALID_HANDLE_VALUE)
                    {
                        _threadHandle = processInfo.hThread;
                        _tid          = processInfo.dwThreadId;
                    }
                }
                if (!retVal)
                {
                    if (errorCode == NativeMethods.ERROR_BAD_EXE_FORMAT || errorCode == NativeMethods.ERROR_EXE_MACHINE_TYPE_MISMATCH)
                    {
                        throw new Win32Exception(errorCode, "Invalid Application");
                    }
                    throw new Win32Exception(errorCode);
                }
                retVal = true;
            }
            finally
            {
                // free environment block
                if (environmentHandle.IsAllocated)
                {
                    environmentHandle.Free();
                }
            }

            if (_pid != 0)
            {
                return(Process.GetProcessById((int)_pid));
            }
            else
            {
                return(null);
            }
        }