Ejemplo n.º 1
0
        /// <summary>
        /// Uses the shell to execute the command. This method must only be used by Mono Paint
        /// and not by plugins.
        /// </summary>
        /// <param name="parent">
        /// The window that is currently in the foreground. This may be null if requireAdmin
        /// is false and the executable that exePath refers to is not marked (e.g. via a
        /// manifest) as requiring administrator privilege.
        /// </param>
        /// <param name="exePath">
        /// The path to the executable to launch.
        /// </param>
        /// <param name="args">
        /// The command-line arguments for the executable.
        /// </param>
        /// <param name="requireAdmin">
        /// Whether or not administrator privilege is required to launch this. However,
        /// if the executable is already marked as requiring administrator privilege
        /// (e.g. via a "requiresAdministrator" UAC manifest), this parameter should be
        /// set to false.
        /// </param>
        /// <remarks>
        /// If administrator privilege is required, a consent UI may be displayed asking the
        /// user to approve the action. A parent window must be provided in this case so that
        /// the consent UI will know where to position itself. Administrator privilege is
        /// required if requireAdmin is set to true, or if the executable being launched
        /// has a manifest declaring that it requires this privilege and if the operating
        /// system recognizes the manifest.
        /// </remarks>
        /// <exception cref="ArgumentException">
        /// requireAdmin was true, but parent was null.
        /// </exception>
        /// <exception cref="SecurityException">
        /// requireAdmin was true, but the user does not have this privilege, nor do they
        /// have the ability to acquire or elevate to obtain this privilege.
        /// </exception>
        /// <exception cref="Win32Exception">
        /// There was an error launching the program.
        /// </exception>
        public static void Execute(
            IWin32Window parent,
            string exePath,
            string args,
            bool requireAdmin,
            ExecuteWaitType executeWaitType)
        {
            const string runAs = "runas";

            if (exePath == null)
            {
                throw new ArgumentNullException("exePath");
            }

            if (requireAdmin && parent == null)
            {
                throw new ArgumentException("If requireAdmin is true, a parent window must be provided");
            }

            // If this action requires admin privilege, but the user does not have this
            // privilege and is not capable of acquiring this privilege, then we will
            // throw an exception.
            if (requireAdmin && !Security.IsAdministrator && !Security.CanElevateToAdministrator)
            {
                throw new SecurityException("Executable requires administrator privilege, but user is not an administrator and cannot elevate");
            }

            switch (executeWaitType)
            {
            case ExecuteWaitType.ReturnImmediately:
                Process.Start(exePath, args);
                return;

            case ExecuteWaitType.RelaunchPdnOnExit:
                Console.WriteLine("PORT: Execute does not support RelaunchPdnOnExit yet");
                goto case ExecuteWaitType.WaitForExit;

            case ExecuteWaitType.WaitForExit:
                Process child = Process.Start(exePath, args);
                child.WaitForExit();
                return;
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Uses the shell to execute the command. This method must only be used by Paint.NET
        /// and not by plugins.
        /// </summary>
        /// <param name="parent">
        /// The window that is currently in the foreground. This may be null if requireAdmin
        /// is false and the executable that exePath refers to is not marked (e.g. via a
        /// manifest) as requiring administrator privilege.
        /// </param>
        /// <param name="exePath">
        /// The path to the executable to launch.
        /// </param>
        /// <param name="args">
        /// The command-line arguments for the executable.
        /// </param>
        /// <param name="execPrivilege">
        /// The privileges to execute the new process with.
        /// If the executable is already marked as requiring administrator privilege
        /// (e.g. via a "requiresAdministrator" UAC manifest), this parameter should be
        /// set to AsInvokerOrAsManifest.
        /// </param>
        /// <remarks>
        /// If administrator privilege is required, a consent UI may be displayed asking the
        /// user to approve the action. A parent window must be provided in this case so that
        /// the consent UI will know where to position itself. Administrator privilege is
        /// required if execPrivilege is set to RequireAdmin, or if the executable being launched
        /// has a manifest declaring that it requires this privilege and if the operating
        /// system recognizes the manifest.
        /// </remarks>
        /// <exception cref="ArgumentException">
        /// execPrivilege was RequireAdmin, but parent was null.
        /// </exception>
        /// <exception cref="SecurityException">
        /// execPrivilege was RequireAdmin, but the user does not have this privilege, nor do they
        /// have the ability to acquire or elevate to obtain this privilege.
        /// </exception>
        /// <exception cref="Win32Exception">
        /// There was an error launching the program.
        /// </exception>
        public static void Execute(
            IWin32Window parent,
            string exePath,
            string args,
            ExecutePrivilege execPrivilege,
            ExecuteWaitType execWaitType)
        {
            if (exePath == null)
            {
                throw new ArgumentNullException("exePath");
            }

            if (execPrivilege == ExecutePrivilege.RequireAdmin && parent == null)
            {
                throw new ArgumentException("If requireAdmin is true, a parent window must be provided");
            }

            // If this action requires admin privilege, but the user does not have this
            // privilege and is not capable of acquiring this privilege, then we will
            // throw an exception.
            if (execPrivilege == ExecutePrivilege.RequireAdmin &&
                !Security.IsAdministrator &&
                !Security.CanElevateToAdministrator)
            {
                throw new SecurityException("Executable requires administrator privilege, but user is not an administrator and cannot elevate");
            }

            ExecuteHandOff executeHandOff = null;

            switch (execPrivilege)
            {
            case ExecutePrivilege.AsInvokerOrAsManifest:
                executeHandOff = new ExecuteHandOff(ExecAsInvokerOrAsManifest);
                break;

            case ExecutePrivilege.RequireAdmin:
                executeHandOff = new ExecuteHandOff(ExecRequireAdmin);
                break;

            case ExecutePrivilege.RequireNonAdminIfPossible:
                if (Security.CanLaunchNonAdminProcess)
                {
                    executeHandOff = new ExecuteHandOff(ExecRequireNonAdmin);
                }
                else
                {
                    executeHandOff = new ExecuteHandOff(ExecAsInvokerOrAsManifest);
                }
                break;

            default:
                throw new InvalidEnumArgumentException("ExecutePrivilege");
            }

            string updateMonitorExePath = null;

            if (execWaitType == ExecuteWaitType.RelaunchPdnOnExit)
            {
                RelaunchPdnHelperPart1(out updateMonitorExePath);
            }

            IntPtr hProcess = IntPtr.Zero;
            int    nResult  = executeHandOff(parent, exePath, args, out hProcess);

            if (nResult == NativeConstants.ERROR_SUCCESS)
            {
                if (execWaitType == ExecuteWaitType.WaitForExit)
                {
                    SafeNativeMethods.WaitForSingleObject(hProcess, NativeConstants.INFINITE);
                }
                else if (execWaitType == ExecuteWaitType.RelaunchPdnOnExit)
                {
                    bool bResult2 = SafeNativeMethods.SetHandleInformation(
                        hProcess,
                        NativeConstants.HANDLE_FLAG_INHERIT,
                        NativeConstants.HANDLE_FLAG_INHERIT);

                    RelaunchPdnHelperPart2(updateMonitorExePath, hProcess);

                    // Ensure that we don't close the process handle right away in the next few lines of code.
                    // It must be inherited by the child process. Yes, this is technically a leak but we are
                    // planning to terminate in just a moment anyway.
                    hProcess = IntPtr.Zero;
                }
                else if (execWaitType == ExecuteWaitType.ReturnImmediately)
                {
                }

                if (hProcess != IntPtr.Zero)
                {
                    SafeNativeMethods.CloseHandle(hProcess);
                    hProcess = IntPtr.Zero;
                }
            }
            else
            {
                if (nResult == NativeConstants.ERROR_CANCELLED ||
                    nResult == NativeConstants.ERROR_TIMEOUT)
                {
                    // no problem
                }
                else
                {
                    NativeMethods.ThrowOnWin32Error("ExecuteHandoff failed", nResult);
                }

                if (updateMonitorExePath != null)
                {
                    try
                    {
                        File.Delete(updateMonitorExePath);
                    }

                    catch (Exception)
                    {
                    }

                    updateMonitorExePath = null;
                }
            }

            GC.KeepAlive(parent);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Uses the shell to execute the command. This method must only be used by Paint.NET
        /// and not by plugins.
        /// </summary>
        /// <param name="parent">
        /// The window that is currently in the foreground. This may be null if requireAdmin
        /// is false and the executable that exePath refers to is not marked (e.g. via a
        /// manifest) as requiring administrator privilege.
        /// </param>
        /// <param name="exePath">
        /// The path to the executable to launch.
        /// </param>
        /// <param name="args">
        /// The command-line arguments for the executable.
        /// </param>
        /// <param name="requireAdmin">
        /// Whether or not administrator privilege is required to launch this. However,
        /// if the executable is already marked as requiring administrator privilege
        /// (e.g. via a "requiresAdministrator" UAC manifest), this parameter should be
        /// set to false.
        /// </param>
        /// <remarks>
        /// If administrator privilege is required, a consent UI may be displayed asking the
        /// user to approve the action. A parent window must be provided in this case so that
        /// the consent UI will know where to position itself. Administrator privilege is
        /// required if requireAdmin is set to true, or if the executable being launched
        /// has a manifest declaring that it requires this privilege and if the operating
        /// system recognizes the manifest.
        /// </remarks>
        /// <exception cref="ArgumentException">
        /// requireAdmin was true, but parent was null.
        /// </exception>
        /// <exception cref="SecurityException">
        /// requireAdmin was true, but the user does not have this privilege, nor do they
        /// have the ability to acquire or elevate to obtain this privilege.
        /// </exception>
        /// <exception cref="Win32Exception">
        /// There was an error launching the program.
        /// </exception>
        public static void Execute(
            IWin32Window parent,
            string exePath,
            string args,
            bool requireAdmin,
            ExecuteWaitType executeWaitType)
        {
            const string runAs = "runas";

            if (exePath == null)
            {
                throw new ArgumentNullException("exePath");
            }

            if (requireAdmin && parent == null)
            {
                throw new ArgumentException("If requireAdmin is true, a parent window must be provided");
            }

            // If this action requires admin privilege, but the user does not have this
            // privilege and is not capable of acquiring this privilege, then we will
            // throw an exception.
            if (requireAdmin && !Security.IsAdministrator && !Security.CanElevateToAdministrator)
            {
                throw new SecurityException("Executable requires administrator privilege, but user is not an administrator and cannot elevate");
            }

            NativeStructs.SHELLEXECUTEINFO sei = new NativeStructs.SHELLEXECUTEINFO();
            sei.cbSize = (uint)Marshal.SizeOf(typeof(NativeStructs.SHELLEXECUTEINFO));

            sei.fMask =
                NativeConstants.SEE_MASK_NOCLOSEPROCESS |
                NativeConstants.SEE_MASK_NO_CONSOLE |
                NativeConstants.SEE_MASK_FLAG_DDEWAIT;

            if (requireAdmin && !Security.IsAdministrator)
            {
                sei.lpVerb = runAs;
            }

            string dir;

            try
            {
                dir = Path.GetDirectoryName(exePath);
            }

            catch (Exception)
            {
                dir = null;
            }

            sei.lpDirectory = dir;

            sei.lpFile       = exePath;
            sei.lpParameters = args;
            sei.nShow        = NativeConstants.SW_SHOWNORMAL;

            if (parent != null)
            {
                sei.hwnd = parent.Handle;
            }

            string updateMonitorExePath = null;

            if (executeWaitType == ExecuteWaitType.RelaunchPdnOnExit)
            {
                RelaunchPdnHelperPart1(out updateMonitorExePath);
            }

            bool bResult = NativeMethods.ShellExecuteExW(ref sei);

            if (bResult)
            {
                if (executeWaitType == ExecuteWaitType.WaitForExit)
                {
                    SafeNativeMethods.WaitForSingleObject(sei.hProcess, NativeConstants.INFINITE);
                }
                else if (executeWaitType == ExecuteWaitType.RelaunchPdnOnExit)
                {
                    bool bResult2 = SafeNativeMethods.SetHandleInformation(
                        sei.hProcess,
                        NativeConstants.HANDLE_FLAG_INHERIT,
                        NativeConstants.HANDLE_FLAG_INHERIT);

                    RelaunchPdnHelperPart2(updateMonitorExePath, sei.hProcess);

                    // Ensure that we don't close the process handle right away in the next few lines of code.
                    // It must be inherited by the child process.
                    sei.hProcess = IntPtr.Zero;
                }
                else if (executeWaitType == ExecuteWaitType.ReturnImmediately)
                {
                }

                if (sei.hProcess != IntPtr.Zero)
                {
                    SafeNativeMethods.CloseHandle(sei.hProcess);
                    sei.hProcess = IntPtr.Zero;
                }
            }
            else
            {
                int dwError = Marshal.GetLastWin32Error();

                if (dwError != NativeConstants.ERROR_CANCELLED)
                {
                    NativeMethods.ThrowOnWin32Error("ShellExecuteW returned FALSE");
                }

                if (updateMonitorExePath != null)
                {
                    try
                    {
                        File.Delete(updateMonitorExePath);
                    }

                    catch (Exception)
                    {
                    }

                    updateMonitorExePath = null;
                }
            }

            GC.KeepAlive(parent);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Uses the shell to execute the command. This method must only be used by Paint.NET
        /// and not by plugins.
        /// </summary>
        /// <param name="parent">
        /// The window that is currently in the foreground. This may be null if requireAdmin 
        /// is false and the executable that exePath refers to is not marked (e.g. via a 
        /// manifest) as requiring administrator privilege.
        /// </param>
        /// <param name="exePath">
        /// The path to the executable to launch.
        /// </param>
        /// <param name="args">
        /// The command-line arguments for the executable.
        /// </param>
        /// <param name="requireAdmin">
        /// Whether or not administrator privilege is required to launch this. However,
        /// if the executable is already marked as requiring administrator privilege
        /// (e.g. via a "requiresAdministrator" UAC manifest), this parameter should be 
        /// set to false.
        /// </param>
        /// <remarks>
        /// If administrator privilege is required, a consent UI may be displayed asking the
        /// user to approve the action. A parent window must be provided in this case so that
        /// the consent UI will know where to position itself. Administrator privilege is
        /// required if requireAdmin is set to true, or if the executable being launched
        /// has a manifest declaring that it requires this privilege and if the operating
        /// system recognizes the manifest.
        /// </remarks>
        /// <exception cref="ArgumentException">
        /// requireAdmin was true, but parent was null.
        /// </exception>
        /// <exception cref="SecurityException">
        /// requireAdmin was true, but the user does not have this privilege, nor do they 
        /// have the ability to acquire or elevate to obtain this privilege.
        /// </exception>
        /// <exception cref="Win32Exception">
        /// There was an error launching the program.
        /// </exception>
        public static void Execute(
            IWin32Window parent,
            string exePath,
            string args,
            bool requireAdmin,
            ExecuteWaitType executeWaitType)
        {
            const string runAs = "runas";

            if (exePath == null)
            {
                throw new ArgumentNullException("exePath");
            }

            if (requireAdmin && parent == null)
            {
                throw new ArgumentException("If requireAdmin is true, a parent window must be provided");
            }

            // If this action requires admin privilege, but the user does not have this
            // privilege and is not capable of acquiring this privilege, then we will
            // throw an exception.
            if (requireAdmin && !Security.IsAdministrator && !Security.CanElevateToAdministrator)
            {
                throw new SecurityException("Executable requires administrator privilege, but user is not an administrator and cannot elevate");
            }

            NativeStructs.SHELLEXECUTEINFO sei = new NativeStructs.SHELLEXECUTEINFO();
            sei.cbSize = (uint)Marshal.SizeOf(typeof(NativeStructs.SHELLEXECUTEINFO));

            sei.fMask =
                NativeConstants.SEE_MASK_NOCLOSEPROCESS |
                NativeConstants.SEE_MASK_NO_CONSOLE |
                NativeConstants.SEE_MASK_FLAG_DDEWAIT;

            if (requireAdmin && !Security.IsAdministrator)
            {
                sei.lpVerb = runAs;
            }

            string dir;

            try
            {
                dir = Path.GetDirectoryName(exePath);
            }

            catch (Exception)
            {
                dir = null;
            }

            sei.lpDirectory = dir;

            sei.lpFile = exePath;
            sei.lpParameters = args;
            sei.nShow = NativeConstants.SW_SHOWNORMAL;

            if (parent != null)
            {
                sei.hwnd = parent.Handle;
            }

            string updateMonitorExePath = null;
            if (executeWaitType == ExecuteWaitType.RelaunchPdnOnExit)
            {
                RelaunchPdnHelperPart1(out updateMonitorExePath);
            }

            bool bResult = NativeMethods.ShellExecuteExW(ref sei);

            if (bResult)
            {
                if (executeWaitType == ExecuteWaitType.WaitForExit)
                {
                    SafeNativeMethods.WaitForSingleObject(sei.hProcess, NativeConstants.INFINITE);
                }
                else if (executeWaitType == ExecuteWaitType.RelaunchPdnOnExit)
                {
                    bool bResult2 = SafeNativeMethods.SetHandleInformation(
                        sei.hProcess,
                        NativeConstants.HANDLE_FLAG_INHERIT,
                        NativeConstants.HANDLE_FLAG_INHERIT);

                    RelaunchPdnHelperPart2(updateMonitorExePath, sei.hProcess);

                    // Ensure that we don't close the process handle right away in the next few lines of code.
                    // It must be inherited by the child process.
                    sei.hProcess = IntPtr.Zero;
                }
                else if (executeWaitType == ExecuteWaitType.ReturnImmediately)
                {
                }

                if (sei.hProcess != IntPtr.Zero)
                {
                    SafeNativeMethods.CloseHandle(sei.hProcess);
                    sei.hProcess = IntPtr.Zero;
                }
            }
            else
            {
                int dwError = Marshal.GetLastWin32Error();

                if (dwError != NativeConstants.ERROR_CANCELLED)
                {
                    NativeMethods.ThrowOnWin32Error("ShellExecuteW returned FALSE");
                }

                if (updateMonitorExePath != null)
                {
                    try
                    {
                        File.Delete(updateMonitorExePath);
                    }

                    catch (Exception)
                    {
                    }

                    updateMonitorExePath = null;
                }
            }

            GC.KeepAlive(parent);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Uses the shell to execute the command. This method must only be used by Mono Paint
        /// and not by plugins.
        /// </summary>
        /// <param name="parent">
        /// The window that is currently in the foreground. This may be null if requireAdmin 
        /// is false and the executable that exePath refers to is not marked (e.g. via a 
        /// manifest) as requiring administrator privilege.
        /// </param>
        /// <param name="exePath">
        /// The path to the executable to launch.
        /// </param>
        /// <param name="args">
        /// The command-line arguments for the executable.
        /// </param>
        /// <param name="requireAdmin">
        /// Whether or not administrator privilege is required to launch this. However,
        /// if the executable is already marked as requiring administrator privilege
        /// (e.g. via a "requiresAdministrator" UAC manifest), this parameter should be 
        /// set to false.
        /// </param>
        /// <remarks>
        /// If administrator privilege is required, a consent UI may be displayed asking the
        /// user to approve the action. A parent window must be provided in this case so that
        /// the consent UI will know where to position itself. Administrator privilege is
        /// required if requireAdmin is set to true, or if the executable being launched
        /// has a manifest declaring that it requires this privilege and if the operating
        /// system recognizes the manifest.
        /// </remarks>
        /// <exception cref="ArgumentException">
        /// requireAdmin was true, but parent was null.
        /// </exception>
        /// <exception cref="SecurityException">
        /// requireAdmin was true, but the user does not have this privilege, nor do they 
        /// have the ability to acquire or elevate to obtain this privilege.
        /// </exception>
        /// <exception cref="Win32Exception">
        /// There was an error launching the program.
        /// </exception>
        public static void Execute(
            IWin32Window parent, 
            string exePath, 
            string args, 
            bool requireAdmin, 
            ExecuteWaitType executeWaitType)
        {
            const string runAs = "runas";

            if (exePath == null)
            {
                throw new ArgumentNullException("exePath");
            }

            if (requireAdmin && parent == null)
            {
                throw new ArgumentException("If requireAdmin is true, a parent window must be provided");
            }

            // If this action requires admin privilege, but the user does not have this
            // privilege and is not capable of acquiring this privilege, then we will
            // throw an exception.
            if (requireAdmin && !Security.IsAdministrator && !Security.CanElevateToAdministrator)
            {
                throw new SecurityException("Executable requires administrator privilege, but user is not an administrator and cannot elevate");
            }

            switch (executeWaitType){
            case ExecuteWaitType.ReturnImmediately:
                Process.Start (exePath, args);
                return;

            case ExecuteWaitType.RelaunchPdnOnExit:
                Console.WriteLine ("PORT: Execute does not support RelaunchPdnOnExit yet");
                goto case ExecuteWaitType.WaitForExit;

            case ExecuteWaitType.WaitForExit:
                Process child = Process.Start (exePath, args);
                child.WaitForExit ();
                return;
            }
        }