Exemple #1
0
        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;
        }