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); } }