Пример #1
0
                : null; //(UnixUtils.HasGui ? "0install-gtk" : null);

        /// <summary>
        /// Parses command-line arguments and performs the indicated action. Performs error handling.
        /// </summary>
        /// <param name="exeName">The name of the executable to use as a reference in help messages and self-invokation.</param>
        /// <param name="args">The arguments to be processed.</param>
        /// <param name="handler">A callback object used when the the user needs to be asked questions or informed about download and IO tasks.</param>
        /// <returns>The exit status code to end the process with. Cast to <see cref="int"/> to return from a Main method.</returns>
        public static ExitCode Run([NotNull] string exeName, [NotNull] string[] args, [NotNull] ICommandHandler handler)
        {
            #region Sanity checks
            if (string.IsNullOrEmpty(exeName))
            {
                throw new ArgumentNullException(nameof(exeName));
            }
            if (args == null)
            {
                throw new ArgumentNullException(nameof(args));
            }
            if (handler == null)
            {
                throw new ArgumentNullException(nameof(handler));
            }
            #endregion

            try
            {
                var command = CommandFactory.CreateAndParse(args, handler);
                return(command.Execute());
            }
            #region Error handling
            catch (OperationCanceledException)
            {
                return(ExitCode.UserCanceled);
            }
            catch (NeedGuiException ex)
            {
                if (GuiAssemblyName != null)
                {
                    Log.Info("Switching to GUI");
                    handler.DisableUI();
                    try
                    {
                        return((ExitCode)ProcessUtils.Assembly(GuiAssemblyName, args).Run());
                    }
                    catch (IOException ex2)
                    {
                        handler.Error(ex2);
                        return(ExitCode.IOError);
                    }
                    catch (NotAdminException ex2)
                    {
                        handler.Error(ex2);
                        return(ExitCode.AccessDenied);
                    }
                }
                else
                {
                    handler.Error(ex);
                    return(ExitCode.NotSupported);
                }
            }
            catch (NotAdminException ex)
            {
                if (WindowsUtils.HasUac)
                {
                    Log.Info("Elevating to admin");
                    handler.DisableUI();
                    try
                    {
                        return((ExitCode)ProcessUtils.Assembly(GuiAssemblyName ?? exeName, args).AsAdmin().Run());
                    }
                    catch (PlatformNotSupportedException ex2)
                    {
                        handler.Error(ex2);
                        return(ExitCode.NotSupported);
                    }
                    catch (IOException ex2)
                    {
                        handler.Error(ex2);
                        return(ExitCode.IOError);
                    }
                    catch (NotAdminException ex2)
                    {
                        handler.Error(ex2);
                        return(ExitCode.AccessDenied);
                    }
                    catch (OperationCanceledException)
                    {
                        return(ExitCode.UserCanceled);
                    }
                }
                else
                {
                    handler.Error(ex);
                    return(ExitCode.AccessDenied);
                }
            }
            catch (UnsuitableInstallBaseException ex)
            {
                if (WindowsUtils.IsWindows)
                {
                    try
                    {
                        var result = TryRunOtherInstance(exeName, args, handler, ex.NeedsMachineWide);
                        if (result.HasValue)
                        {
                            return(result.Value);
                        }
                        else if (handler.Ask(Resources.AskDeployZeroInstall + Environment.NewLine + ex.Message,
                                             defaultAnswer: false, alternateMessage: ex.Message))
                        {
                            var deployArgs = new[] { MaintenanceMan.Name, MaintenanceMan.Deploy.Name, "--batch" };
                            if (ex.NeedsMachineWide)
                            {
                                deployArgs = deployArgs.Append("--machine");
                            }
                            var deployResult = Run(exeName, deployArgs, handler);
                            if (deployResult == ExitCode.OK)
                            {
                                result = TryRunOtherInstance(exeName, args, handler, ex.NeedsMachineWide);
                                if (result.HasValue)
                                {
                                    return(result.Value);
                                }
                                else
                                {
                                    throw new IOException("Unable to find newly installed instance.");
                                }
                            }
                            else
                            {
                                return(deployResult);
                            }
                        }
                    }
                    catch (IOException ex2)
                    {
                        handler.Error(ex2);
                        return(ExitCode.IOError);
                    }
                    catch (NotAdminException ex2)
                    {
                        handler.Error(ex2);
                        return(ExitCode.AccessDenied);
                    }
                }
                else
                {
                    handler.Error(ex);
                }

                return(ExitCode.NotSupported);
            }
            catch (OptionException ex)
            {
                handler.Error(new OptionException(ex.Message + Environment.NewLine + string.Format(Resources.TryHelp, exeName), ex.OptionName));
                return(ExitCode.InvalidArguments);
            }
            catch (FormatException ex)
            {
                handler.Error(ex);
                return(ExitCode.InvalidArguments);
            }
            catch (WebException ex)
            {
                handler.Error(ex);
                return(ExitCode.WebError);
            }
            catch (NotSupportedException ex)
            {
                handler.Error(ex);
                return(ExitCode.NotSupported);
            }
            catch (IOException ex)
            {
                handler.Error(ex);
                return(ExitCode.IOError);
            }
            catch (UnauthorizedAccessException ex)
            {
                handler.Error(ex);
                return(ExitCode.AccessDenied);
            }
            catch (InvalidDataException ex)
            {
                handler.Error(ex);
                return(ExitCode.InvalidData);
            }
            catch (SignatureException ex)
            {
                handler.Error(ex);
                return(ExitCode.InvalidSignature);
            }
            catch (DigestMismatchException ex)
            {
                handler.Error(ex);
                return(ExitCode.DigestMismatch);
            }
            catch (SolverException ex)
            {
                handler.Error(ex);
                return(ExitCode.SolverError);
            }
            catch (ExecutorException ex)
            {
                handler.Error(ex);
                return(ExitCode.ExecutorError);
            }
            catch (ConflictException ex)
            {
                handler.Error(ex);
                return(ExitCode.Conflict);
            }
            #endregion

            finally
            {
                handler.CloseUI();
            }
        }