Ejemplo n.º 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);
        }