private unsafe bool StartWithShellExecuteEx(ProcessStartInfo startInfo) { if (!string.IsNullOrEmpty(startInfo.UserName) || startInfo.Password != null) { throw new InvalidOperationException(SR.CantStartAsUser); } if (startInfo.RedirectStandardInput || startInfo.RedirectStandardOutput || startInfo.RedirectStandardError) { throw new InvalidOperationException(SR.CantRedirectStreams); } if (startInfo.StandardInputEncoding != null) { throw new InvalidOperationException(SR.StandardInputEncodingNotAllowed); } if (startInfo.StandardErrorEncoding != null) { throw new InvalidOperationException(SR.StandardErrorEncodingNotAllowed); } if (startInfo.StandardOutputEncoding != null) { throw new InvalidOperationException(SR.StandardOutputEncodingNotAllowed); } if (startInfo._environmentVariables != null) { throw new InvalidOperationException(SR.CantUseEnvVars); } string arguments = startInfo.BuildArguments(); fixed(char *fileName = startInfo.FileName.Length > 0?startInfo.FileName : null) fixed(char *verb = startInfo.Verb.Length > 0 ? startInfo.Verb : null) fixed(char *parameters = arguments.Length > 0 ? arguments : null) fixed(char *directory = startInfo.WorkingDirectory.Length > 0 ? startInfo.WorkingDirectory : null) { Interop.Shell32.SHELLEXECUTEINFO shellExecuteInfo = new Interop.Shell32.SHELLEXECUTEINFO() { cbSize = (uint)sizeof(Interop.Shell32.SHELLEXECUTEINFO), lpFile = fileName, lpVerb = verb, lpParameters = parameters, lpDirectory = directory, fMask = Interop.Shell32.SEE_MASK_NOCLOSEPROCESS | Interop.Shell32.SEE_MASK_FLAG_DDEWAIT }; if (startInfo.ErrorDialog) { shellExecuteInfo.hwnd = startInfo.ErrorDialogParentHandle; } else { shellExecuteInfo.fMask |= Interop.Shell32.SEE_MASK_FLAG_NO_UI; } shellExecuteInfo.nShow = startInfo.WindowStyle switch { ProcessWindowStyle.Hidden => Interop.Shell32.SW_HIDE, ProcessWindowStyle.Minimized => Interop.Shell32.SW_SHOWMINIMIZED, ProcessWindowStyle.Maximized => Interop.Shell32.SW_SHOWMAXIMIZED, _ => Interop.Shell32.SW_SHOWNORMAL, }; ShellExecuteHelper executeHelper = new ShellExecuteHelper(&shellExecuteInfo); if (!executeHelper.ShellExecuteOnSTAThread()) { int error = executeHelper.ErrorCode; if (error == 0) { error = GetShellError(shellExecuteInfo.hInstApp); } switch (error) { case Interop.Errors.ERROR_BAD_EXE_FORMAT: case Interop.Errors.ERROR_EXE_MACHINE_TYPE_MISMATCH: throw new Win32Exception(error, SR.InvalidApplication); case Interop.Errors.ERROR_CALL_NOT_IMPLEMENTED: // This happens on Windows Nano throw new PlatformNotSupportedException(SR.UseShellExecuteNotSupported); default: throw new Win32Exception(error); } } if (shellExecuteInfo.hProcess != IntPtr.Zero) { SetProcessHandle(new SafeProcessHandle(shellExecuteInfo.hProcess)); return(true); } } return(false); }
private bool StartWithShellExecuteEx(ProcessStartInfo startInfo) { if (this.disposed) { throw new ObjectDisposedException(base.GetType().Name); } if (!string.IsNullOrEmpty(startInfo.UserName) || (startInfo.Password != null)) { throw new InvalidOperationException(SR.GetString("CantStartAsUser")); } if ((startInfo.RedirectStandardInput || startInfo.RedirectStandardOutput) || startInfo.RedirectStandardError) { throw new InvalidOperationException(SR.GetString("CantRedirectStreams")); } if (startInfo.StandardErrorEncoding != null) { throw new InvalidOperationException(SR.GetString("StandardErrorEncodingNotAllowed")); } if (startInfo.StandardOutputEncoding != null) { throw new InvalidOperationException(SR.GetString("StandardOutputEncodingNotAllowed")); } if (startInfo.environmentVariables != null) { throw new InvalidOperationException(SR.GetString("CantUseEnvVars")); } Microsoft.Win32.NativeMethods.ShellExecuteInfo executeInfo = new Microsoft.Win32.NativeMethods.ShellExecuteInfo { fMask = 0x40 }; if (startInfo.ErrorDialog) { executeInfo.hwnd = startInfo.ErrorDialogParentHandle; } else { executeInfo.fMask |= 0x400; } switch (startInfo.WindowStyle) { case ProcessWindowStyle.Hidden: executeInfo.nShow = 0; break; case ProcessWindowStyle.Minimized: executeInfo.nShow = 2; break; case ProcessWindowStyle.Maximized: executeInfo.nShow = 3; break; default: executeInfo.nShow = 1; break; } try { if (startInfo.FileName.Length != 0) { executeInfo.lpFile = Marshal.StringToHGlobalAuto(startInfo.FileName); } if (startInfo.Verb.Length != 0) { executeInfo.lpVerb = Marshal.StringToHGlobalAuto(startInfo.Verb); } if (startInfo.Arguments.Length != 0) { executeInfo.lpParameters = Marshal.StringToHGlobalAuto(startInfo.Arguments); } if (startInfo.WorkingDirectory.Length != 0) { executeInfo.lpDirectory = Marshal.StringToHGlobalAuto(startInfo.WorkingDirectory); } executeInfo.fMask |= 0x100; ShellExecuteHelper helper = new ShellExecuteHelper(executeInfo); if (helper.ShellExecuteOnSTAThread()) { goto Label_0325; } int errorCode = helper.ErrorCode; if (errorCode != 0) { goto Label_0282; } long hInstApp = (long) executeInfo.hInstApp; if (hInstApp <= 8L) { if (hInstApp < 2L) { goto Label_0276; } switch (((int) (hInstApp - 2L))) { case 0: errorCode = 2; goto Label_0282; case 1: errorCode = 3; goto Label_0282; case 2: case 4: case 5: goto Label_0276; case 3: errorCode = 5; goto Label_0282; case 6: errorCode = 8; goto Label_0282; } } if ((hInstApp <= 0x20L) && (hInstApp >= 0x1aL)) { switch (((int) (hInstApp - 0x1aL))) { case 0: errorCode = 0x20; goto Label_0282; case 2: case 3: case 4: errorCode = 0x484; goto Label_0282; case 5: errorCode = 0x483; goto Label_0282; case 6: errorCode = 0x485; goto Label_0282; } } Label_0276: errorCode = (int) executeInfo.hInstApp; Label_0282: if ((errorCode != 0xc1) && (errorCode != 0xd8)) { throw new Win32Exception(errorCode); } throw new Win32Exception(errorCode, SR.GetString("InvalidApplication")); } finally { if (executeInfo.lpFile != IntPtr.Zero) { Marshal.FreeHGlobal(executeInfo.lpFile); } if (executeInfo.lpVerb != IntPtr.Zero) { Marshal.FreeHGlobal(executeInfo.lpVerb); } if (executeInfo.lpParameters != IntPtr.Zero) { Marshal.FreeHGlobal(executeInfo.lpParameters); } if (executeInfo.lpDirectory != IntPtr.Zero) { Marshal.FreeHGlobal(executeInfo.lpDirectory); } } Label_0325: if (executeInfo.hProcess != IntPtr.Zero) { Microsoft.Win32.SafeHandles.SafeProcessHandle processHandle = new Microsoft.Win32.SafeHandles.SafeProcessHandle(executeInfo.hProcess); this.SetProcessHandle(processHandle); return true; } return false; }