예제 #1
0
        public IEnumerable <PackageResult> list_run(ChocolateyConfiguration config)
        {
            var packageResults = new List <PackageResult>();
            var args           = ExternalCommandArgsBuilder.build_arguments(config, _listArguments);

            //var whereToStartRecording = "---";
            //var whereToStopRecording = "--";
            //var recordingValues = false;

            Environment.ExitCode = _commandExecutor.execute(
                EXE_PATH,
                args,
                config.CommandExecutionTimeoutSeconds,
                workingDirectory: ApplicationParameters.ShimsLocation,
                stdOutAction: (s, e) =>
            {
                var logMessage = e.Data;
                if (string.IsNullOrWhiteSpace(logMessage))
                {
                    return;
                }
                if (!config.QuietOutput)
                {
                    this.Log().Info(e.Data);
                }
                else
                {
                    this.Log().Debug(() => "[{0}] {1}".format_with(APP_NAME, logMessage));
                }

                //if (recordingValues)
                //{
                //    var lineParts = logMessage.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                //    if (lineParts.Length > 1)
                //    {
                //        var pkgResult = new PackageResult(lineParts[0], null, null);
                //        packageResults.GetOrAdd(lineParts[0], pkgResult);
                //    }
                //}

                //if (logMessage.Contains(whereToStartRecording)) recordingValues = true;
            },
                stdErrAction: (s, e) =>
            {
                if (string.IsNullOrWhiteSpace(e.Data))
                {
                    return;
                }
                this.Log().Error(() => "{0}".format_with(e.Data));
            },
                updateProcessPath: false,
                allowUseWindow: true
                );

            return(packageResults);
        }
예제 #2
0
        public ConcurrentDictionary <string, PackageResult> install_run(ChocolateyConfiguration config, Action <PackageResult> continueAction)
        {
            var args           = build_args(config, _installArguments);
            var packageResults = new ConcurrentDictionary <string, PackageResult>(StringComparer.InvariantCultureIgnoreCase);

            foreach (var packageToInstall in config.PackageNames.Split(new[] { ApplicationParameters.PackageNamesSeparator }, StringSplitOptions.RemoveEmptyEntries))
            {
                var argsForPackage = args.Replace(PACKAGE_NAME_TOKEN, packageToInstall);

                var exitCode = _commandExecutor.execute(
                    get_exe(_rootDirectory),
                    argsForPackage,
                    config.CommandExecutionTimeoutSeconds,
                    _fileSystem.get_current_directory(),
                    (s, e) =>
                {
                    var logMessage = e.Data;
                    if (string.IsNullOrWhiteSpace(logMessage))
                    {
                        return;
                    }
                    this.Log().Info(() => " [{0}] {1}".format_with(APP_NAME, logMessage.escape_curly_braces()));

                    if (InstalledRegex.IsMatch(logMessage))
                    {
                        var packageName = get_value_from_output(logMessage, PackageNameRegex, PACKAGE_NAME_GROUP);
                        var results     = packageResults.GetOrAdd(packageName, new PackageResult(packageName, null, null));
                        results.Messages.Add(new ResultMessage(ResultType.Note, packageName));
                        this.Log().Info(ChocolateyLoggers.Important, " {0} has been installed successfully.".format_with(string.IsNullOrWhiteSpace(packageName) ? packageToInstall : packageName));
                    }
                },
                    (s, e) =>
                {
                    var logMessage = e.Data;
                    if (string.IsNullOrWhiteSpace(logMessage))
                    {
                        return;
                    }
                    this.Log().Error("[{0}] {1}".format_with(APP_NAME, logMessage.escape_curly_braces()));
                },
                    updateProcessPath: false,
                    allowUseWindow: true
                    );

                if (exitCode != 0)
                {
                    Environment.ExitCode = exitCode;
                }
            }

            return(packageResults);
        }
예제 #3
0
        private TestCommandOutputResult execute_vagrant(string command)
        {
            this.Log().Debug(() => "Executing vagrant command '{0}'.".format_with(command.escape_curly_braces()));
            var results = new TestCommandOutputResult();
            var logs    = new StringBuilder();

            var output = _commandExecutor.execute(
                _vagrantExecutable,
                command,
                _configuration.CommandExecutionTimeoutSeconds + 60,
                _fileSystem.get_directory_name(Assembly.GetExecutingAssembly().Location),
                (s, e) =>
            {
                if (e == null || string.IsNullOrWhiteSpace(e.Data))
                {
                    return;
                }
                this.Log().Info(() => " [Vagrant] {0}".format_with(e.Data));
                logs.AppendLine(e.Data);
                results.Messages.Add(
                    new ResultMessage
                {
                    Message     = e.Data,
                    MessageType = ResultType.Note
                });
            },
                (s, e) =>
            {
                if (e == null || string.IsNullOrWhiteSpace(e.Data))
                {
                    return;
                }
                this.Log().Warn(() => " [Vagrant][Error] {0}".format_with(e.Data));
                logs.AppendLine("[ERROR] " + e.Data);
                results.Messages.Add(
                    new ResultMessage
                {
                    Message     = e.Data,
                    MessageType = ResultType.Note
                });
            },
                updateProcessPath: false,
                allowUseWindow: false);

            //if (!string.IsNullOrWhiteSpace(output.StandardError))
            //{
            //    results.Messages.Add(new ResultMessage { Message = output.StandardError, MessageType = ResultType.Error });
            //    logs.Append("##Error Output" + Environment.NewLine);
            //    logs.Append(output.StandardError + Environment.NewLine + Environment.NewLine);
            //}

            //results.Messages.Add(new ResultMessage { Message = output.StandardOut, MessageType = ResultType.Note });
            //logs.Append("##Standard Output" + Environment.NewLine);
            //logs.Append(output.StandardOut);

            results.Logs     = logs.ToString();
            results.ExitCode = output;

            return(results);
        }
예제 #4
0
        public void install(ChocolateyConfiguration configuration, PackageResult packageResult)
        {
            _fileSystem.create_directory_if_not_exists(ApplicationParameters.ShimsLocation);

            //gather all .exes in the folder
            var exeFiles = _fileSystem.get_files(packageResult.InstallLocation, pattern: "*.exe", option: SearchOption.AllDirectories);

            foreach (string file in exeFiles)
            {
                if (_fileSystem.file_exists(file + ".ignore"))
                {
                    continue;
                }
                bool isGui = _fileSystem.file_exists(file + ".gui");
                //todo: v2 be able to determine gui automatically

                var args           = ExternalCommandArgsBuilder.build_arguments(configuration, _shimGenArguments);
                var shimLocation   = _fileSystem.combine_paths(ApplicationParameters.ShimsLocation, _fileSystem.get_file_name(file));
                var argsForPackage = args.Replace(PATH_TOKEN, file.Replace(ApplicationParameters.InstallLocation, "..\\")).Replace(OUTPUT_TOKEN, shimLocation).Replace(ICON_PATH_TOKEN, file);
                if (isGui)
                {
                    argsForPackage += " --gui";
                }

                var exitCode = _commandExecutor.execute(
                    _shimGenExePath, argsForPackage, configuration.CommandExecutionTimeoutSeconds,
                    (s, e) =>
                {
                    if (string.IsNullOrWhiteSpace(e.Data))
                    {
                        return;
                    }
                    this.Log().Debug(() => " [ShimGen] {0}".format_with(e.Data));
                },
                    (s, e) =>
                {
                    if (string.IsNullOrWhiteSpace(e.Data))
                    {
                        return;
                    }
                    this.Log().Error(() => " [ShimGen] {0}".format_with(e.Data));
                }
                    );

                if (exitCode != 0)
                {
                    Environment.ExitCode = exitCode;
                }
                else
                {
                    this.Log().Info(() => " ShimGen has successfully created a {0}shim for {1}".format_with(isGui ? "gui " : string.Empty, _fileSystem.get_file_name(file)));
                    this.Log().Debug(() => "  Created: {0}{1}  Targeting: {2}{1}  IsGui:{3}{1}".format_with(shimLocation, Environment.NewLine, file, isGui));
                }
            }
        }
예제 #5
0
        public IEnumerable <PackageResult> list_run(ChocolateyConfiguration config)
        {
            set_executable_path_if_not_set();
            var args           = build_args(config, _listArguments);
            var packageResults = new List <PackageResult>();

            Environment.ExitCode = _commandExecutor.execute(
                _exePath,
                args,
                config.CommandExecutionTimeoutSeconds,
                _fileSystem.get_current_directory(),
                stdOutAction: (s, e) =>
            {
                var logMessage = e.Data;
                if (string.IsNullOrWhiteSpace(logMessage))
                {
                    return;
                }
                if (!config.QuietOutput)
                {
                    this.Log().Info(e.Data);
                }
                else
                {
                    this.Log().Debug(() => "[{0}] {1}".format_with(APP_NAME, logMessage));
                }
            },
                stdErrAction: (s, e) =>
            {
                if (string.IsNullOrWhiteSpace(e.Data))
                {
                    return;
                }
                this.Log().Error(() => "{0}".format_with(e.Data));
            },
                updateProcessPath: false,
                allowUseWindow: true
                );

            return(packageResults);
        }
예제 #6
0
        public ConcurrentDictionary <string, PackageResult> list_run(ChocolateyConfiguration config, bool logResults)
        {
            set_executable_path_if_not_set();
            var args           = build_args(config, _listArguments);
            var packageResults = new ConcurrentDictionary <string, PackageResult>(StringComparer.InvariantCultureIgnoreCase);

            Environment.ExitCode = _commandExecutor.execute(
                _exePath,
                args,
                config.CommandExecutionTimeoutSeconds,
                stdOutAction: (s, e) =>
            {
                var logMessage = e.Data;
                if (string.IsNullOrWhiteSpace(logMessage))
                {
                    return;
                }
                if (logResults)
                {
                    this.Log().Info(e.Data);
                }
                else
                {
                    this.Log().Debug(() => "[{0}] {1}".format_with(APP_NAME, logMessage));
                }
            },
                stdErrAction: (s, e) =>
            {
                if (string.IsNullOrWhiteSpace(e.Data))
                {
                    return;
                }
                this.Log().Error(() => "{0}".format_with(e.Data));
            },
                updateProcessPath: false
                );

            return(packageResults);
        }
예제 #7
0
        public IEnumerable <PackageResult> list_run(ChocolateyConfiguration config)
        {
            var packageResults = new List <PackageResult>();
            var args           = ExternalCommandArgsBuilder.build_arguments(config, _listArguments);

            Environment.ExitCode = _commandExecutor.execute(
                EXE_PATH,
                args,
                config.CommandExecutionTimeoutSeconds,
                stdOutAction: (s, e) =>
            {
                var logMessage = e.Data;
                if (string.IsNullOrWhiteSpace(logMessage))
                {
                    return;
                }
                if (!config.QuietOutput)
                {
                    this.Log().Info(logMessage.escape_curly_braces());
                }
                else
                {
                    this.Log().Debug(() => "[{0}] {1}".format_with(APP_NAME, logMessage.escape_curly_braces()));
                }
            },
                stdErrAction: (s, e) =>
            {
                if (string.IsNullOrWhiteSpace(e.Data))
                {
                    return;
                }
                this.Log().Error(() => "{0}".format_with(e.Data.escape_curly_braces()));
            },
                updateProcessPath: false
                );

            return(packageResults);
        }
        public void run(PackageResult packageResult, ChocolateyConfiguration config)
        {
            if (!config.Features.AutoUninstaller)
            {
                this.Log().Info(" Skipping auto uninstaller - AutoUninstaller feature is not enabled.");
                return;
            }

            var pkgInfo = _packageInfoService.get_package_information(packageResult.Package);

            if (pkgInfo.RegistrySnapshot == null)
            {
                this.Log().Info(" Skipping auto uninstaller - No registry snapshot.");
                return;
            }

            var registryKeys = pkgInfo.RegistrySnapshot.RegistryKeys;

            if (registryKeys == null || registryKeys.Count == 0)
            {
                this.Log().Info(" Skipping auto uninstaller - No registry keys in snapshot.");
                return;
            }

            this.Log().Info(" Running auto uninstaller...");
            if (WaitForCleanup)
            {
                this.Log().Debug("Sleeping for {0} seconds to allow Windows to finish cleaning up.".format_with(SLEEP_TIME));
                Thread.Sleep((int)TimeSpan.FromSeconds(SLEEP_TIME).TotalMilliseconds);
            }

            foreach (var key in registryKeys.or_empty_list_if_null())
            {
                this.Log().Debug(() => " Preparing uninstall key '{0}'".format_with(key.UninstallString));

                if ((!string.IsNullOrWhiteSpace(key.InstallLocation) && !_fileSystem.directory_exists(key.InstallLocation)) || !_registryService.installer_value_exists(key.KeyPath, ApplicationParameters.RegistryValueInstallLocation))
                {
                    this.Log().Info(" Skipping auto uninstaller - The application appears to have been uninstalled already by other means.");
                    this.Log().Debug(() => " Searched for install path '{0}' - found? {1}".format_with(key.InstallLocation.escape_curly_braces(), _fileSystem.directory_exists(key.InstallLocation)));
                    this.Log().Debug(() => " Searched for registry key '{0}' value '{1}' - found? {2}".format_with(key.KeyPath.escape_curly_braces(), ApplicationParameters.RegistryValueInstallLocation, _registryService.installer_value_exists(key.KeyPath, ApplicationParameters.RegistryValueInstallLocation)));
                    continue;
                }

                // split on " /" and " -" for quite a bit more accuracy
                IList <string> uninstallArgsSplit = key.UninstallString.to_string().Split(new[] { " /", " -" }, StringSplitOptions.RemoveEmptyEntries).ToList();
                var            uninstallExe       = uninstallArgsSplit.DefaultIfEmpty(string.Empty).FirstOrDefault();
                var            uninstallArgs      = key.UninstallString.to_string().Replace(uninstallExe.to_string(), string.Empty);
                uninstallExe = uninstallExe.remove_surrounding_quotes();
                this.Log().Debug(() => " Uninstaller path is '{0}'".format_with(uninstallExe));


                IInstaller installer = new CustomInstaller();

                switch (key.InstallerType)
                {
                case InstallerType.Msi:
                    installer = new MsiInstaller();
                    break;

                case InstallerType.InnoSetup:
                    installer = new InnoSetupInstaller();
                    break;

                case InstallerType.Nsis:
                    installer = new NsisInstaller();
                    break;

                case InstallerType.InstallShield:
                    installer = new InstallShieldInstaller();
                    break;
                }

                this.Log().Debug(() => " Installer type is '{0}'".format_with(installer.GetType().Name));

                if (key.InstallerType == InstallerType.Msi)
                {
                    // because sometimes the key is set with /i to allow for modify :/
                    uninstallArgs = uninstallArgs.Replace("/I{", "/X{");
                    uninstallArgs = uninstallArgs.Replace("/i{", "/X{");
                    uninstallArgs = uninstallArgs.Replace("/I ", "/X ");
                    uninstallArgs = uninstallArgs.Replace("/i ", "/X ");
                }

                if (!key.HasQuietUninstall)
                {
                    //todo: ultimately we should merge keys
                    uninstallArgs += " " + installer.build_uninstall_command_arguments();
                }

                var logLocation = _fileSystem.combine_paths(_fileSystem.get_full_path(config.CacheLocation), "chocolatey", pkgInfo.Package.Id, pkgInfo.Package.Version.to_string());
                _fileSystem.create_directory_if_not_exists(_fileSystem.get_directory_name(logLocation));
                uninstallArgs = uninstallArgs.Replace(InstallTokens.PACKAGE_LOCATION, logLocation);

                this.Log().Debug(() => " Args are '{0}'".format_with(uninstallArgs));

                if (!key.HasQuietUninstall && installer.GetType() == typeof(CustomInstaller))
                {
                    var skipUninstaller = true;
                    if (config.PromptForConfirmation)
                    {
                        var selection = InteractivePrompt.prompt_for_confirmation("Uninstall may not be silent (could not detect). Proceed?", new[] { "yes", "no" }, defaultChoice: null, requireAnswer: true);
                        if (selection.is_equal_to("no"))
                        {
                            skipUninstaller = false;
                        }
                    }

                    if (skipUninstaller)
                    {
                        this.Log().Info(" Skipping auto uninstaller - Installer type was not detected and no silent uninstall key exists.");
                        return;
                    }
                }

                var exitCode = _commandExecutor.execute(
                    uninstallExe,
                    uninstallArgs.trim_safe(),
                    config.CommandExecutionTimeoutSeconds,
                    (s, e) =>
                {
                    if (e == null || string.IsNullOrWhiteSpace(e.Data))
                    {
                        return;
                    }
                    this.Log().Info(() => " [AutoUninstaller] {0}".format_with(e.Data));
                },
                    (s, e) =>
                {
                    if (e == null || string.IsNullOrWhiteSpace(e.Data))
                    {
                        return;
                    }
                    this.Log().Error(() => " [AutoUninstaller] {0}".format_with(e.Data));
                },
                    updateProcessPath: false);

                if (!installer.ValidUninstallExitCodes.Contains(exitCode))
                {
                    Environment.ExitCode = exitCode;
                    string logMessage = " Auto uninstaller failed. Please remove machine installation manually.{0} Exit code was {1}".format_with(Environment.NewLine, exitCode);
                    this.Log().Error(() => logMessage);
                    packageResult.Messages.Add(new ResultMessage(config.Features.FailOnAutoUninstaller ? ResultType.Error : ResultType.Warn, logMessage));
                }
                else
                {
                    this.Log().Info(() => " Auto uninstaller has successfully uninstalled {0} or detected previous uninstall.".format_with(packageResult.Package.Id));
                }
            }
        }
        public void remove(RegistryApplicationKey key, ChocolateyConfiguration config, PackageResult packageResult, string packageCacheLocation)
        {
            this.Log().Debug(() => " Preparing uninstall key '{0}'".format_with(key.UninstallString.to_string().escape_curly_braces()));

            if ((!string.IsNullOrWhiteSpace(key.InstallLocation) && !_fileSystem.directory_exists(key.InstallLocation)) || !_registryService.installer_value_exists(key.KeyPath, ApplicationParameters.RegistryValueInstallLocation))
            {
                this.Log().Info(" Skipping auto uninstaller - The application appears to have been uninstalled already by other means.");
                this.Log().Debug(() => " Searched for install path '{0}' - found? {1}".format_with(key.InstallLocation.to_string().escape_curly_braces(), _fileSystem.directory_exists(key.InstallLocation)));
                this.Log().Debug(() => " Searched for registry key '{0}' value '{1}' - found? {2}".format_with(key.KeyPath.escape_curly_braces(), ApplicationParameters.RegistryValueInstallLocation, _registryService.installer_value_exists(key.KeyPath, ApplicationParameters.RegistryValueInstallLocation)));
                return;
            }

            // split on " /" and " -" for quite a bit more accuracy
            IList <string> uninstallArgsSplit = key.UninstallString.to_string().Split(new[] { " /", " -" }, StringSplitOptions.RemoveEmptyEntries).ToList();
            var            uninstallExe       = uninstallArgsSplit.DefaultIfEmpty(string.Empty).FirstOrDefault();

            if (uninstallExe.Count(u => u == '"') > 2)
            {
                uninstallExe = uninstallExe.Split(new [] { " \"" }, StringSplitOptions.RemoveEmptyEntries).First();
            }
            var uninstallArgs = key.UninstallString.to_string().Replace(uninstallExe.to_string(), string.Empty);

            uninstallExe = uninstallExe.remove_surrounding_quotes();
            this.Log().Debug(() => " Uninstaller path is '{0}'".format_with(uninstallExe));

            if (uninstallExe.contains("\\") || uninstallExe.contains("/"))
            {
                if (!_fileSystem.file_exists(uninstallExe))
                {
                    this.Log().Info(" Skipping auto uninstaller - The uninstaller file no longer exists. \"{0}\"".format_with(uninstallExe));
                    return;
                }
            }

            IInstaller installer = get_installer_type(key, uninstallExe, uninstallArgs);

            this.Log().Debug(() => " Installer type is '{0}'".format_with(installer.GetType().Name));

            if (key.InstallerType == InstallerType.Msi)
            {
                // because sometimes the key is set with /i to allow for modify :/
                uninstallArgs = uninstallArgs.Replace("/I{", "/X{");
                uninstallArgs = uninstallArgs.Replace("/i{", "/X{");
                uninstallArgs = uninstallArgs.Replace("/I ", "/X ");
                uninstallArgs = uninstallArgs.Replace("/i ", "/X ");
            }

            if (!key.HasQuietUninstall)
            {
                //todo: ultimately we should merge keys
                uninstallArgs += " " + installer.build_uninstall_command_arguments();
            }

            this.Log().Debug(() => " Setting up uninstall logging directory at {0}".format_with(packageCacheLocation.escape_curly_braces()));
            _fileSystem.create_directory_if_not_exists(_fileSystem.get_directory_name(packageCacheLocation));
            uninstallArgs = uninstallArgs.Replace(InstallTokens.PACKAGE_LOCATION, packageCacheLocation);
            uninstallArgs = uninstallArgs.Replace(InstallTokens.TEMP_LOCATION, packageCacheLocation);

            this.Log().Debug(() => " Args are '{0}'".format_with(uninstallArgs.escape_curly_braces()));

            if (!key.HasQuietUninstall && installer.GetType() == typeof(CustomInstaller))
            {
                if (!config.Information.IsLicensedVersion)
                {
                    this.Log().Warn(@"
  Did you know licensed versions of Chocolatey are 95% effective with 
   Automatic Uninstaller due to licensed enhancements and Package 
   Synchronizer?
");
                }

                var skipUninstaller = true;

                var timeout = config.PromptForConfirmation ? 0 : 30;

                var selection = InteractivePrompt.prompt_for_confirmation(
                    "Uninstall may not be silent (could not detect). Proceed?",
                    new[] { "yes", "no" },
                    defaultChoice: "no",
                    requireAnswer: true,
                    allowShortAnswer: true,
                    shortPrompt: true,
                    timeoutInSeconds: timeout
                    );
                if (selection.is_equal_to("yes"))
                {
                    skipUninstaller = false;
                }

                if (skipUninstaller)
                {
                    this.Log().Info(" Skipping auto uninstaller - Installer type was not detected and no silent uninstall key exists.");
                    this.Log().Warn("If the application was not removed with a chocolateyUninstall.ps1,{0} please remove it from Programs and Features manually.".format_with(Environment.NewLine));
                    return;
                }
            }

            var exitCode = _commandExecutor.execute(
                uninstallExe,
                uninstallArgs.trim_safe(),
                config.CommandExecutionTimeoutSeconds,
                (s, e) =>
            {
                if (e == null || string.IsNullOrWhiteSpace(e.Data))
                {
                    return;
                }
                this.Log().Info(() => " [AutoUninstaller] {0}".format_with(e.Data.escape_curly_braces()));
            },
                (s, e) =>
            {
                if (e == null || string.IsNullOrWhiteSpace(e.Data))
                {
                    return;
                }
                this.Log().Error(() => " [AutoUninstaller] {0}".format_with(e.Data.escape_curly_braces()));
            },
                updateProcessPath: false);

            if (!installer.ValidUninstallExitCodes.Contains(exitCode))
            {
                Environment.ExitCode = exitCode;
                string logMessage = " Auto uninstaller failed. Please remove machine installation manually.{0} Exit code was {1}".format_with(Environment.NewLine, exitCode);
                this.Log().Error(() => logMessage.escape_curly_braces());
                packageResult.Messages.Add(new ResultMessage(config.Features.FailOnAutoUninstaller ? ResultType.Error : ResultType.Warn, logMessage));
            }
            else
            {
                this.Log().Info(() => " Auto uninstaller has successfully uninstalled {0} or detected previous uninstall.".format_with(packageResult.Package.Id));
            }
        }
예제 #10
0
        public void run(PackageResult packageResult, ChocolateyConfiguration config)
        {
            if (!config.Features.AutoUninstaller)
            {
                this.Log().Info(" Skipping auto uninstaller - AutoUninstaller feature is not enabled.");
                return;
            }

            var pkgInfo = _packageInfoService.get_package_information(packageResult.Package);

            if (pkgInfo.RegistrySnapshot == null)
            {
                this.Log().Info(" Skipping auto uninstaller - No registry snapshot.");
                return;
            }

            var registryKeys = pkgInfo.RegistrySnapshot.RegistryKeys;

            if (registryKeys == null || registryKeys.Count == 0)
            {
                this.Log().Info(" Skipping auto uninstaller - No registry keys in snapshot.");
                return;
            }

            this.Log().Info(" Running auto uninstaller...");

            foreach (var key in registryKeys.or_empty_list_if_null())
            {
                this.Log().Debug(() => " Preparing uninstall key '{0}'".format_with(key.UninstallString));

                if ((!string.IsNullOrWhiteSpace(key.InstallLocation) && !_fileSystem.directory_exists(key.InstallLocation)) || !_registryService.value_exists(key.KeyPath, ApplicationParameters.RegistryValueInstallLocation))
                {
                    this.Log().Info(" Skipping auto uninstaller - The application appears to have been uninstalled already by other means.");
                    this.Log().Debug(() => " Searched for install path '{0}' - found? {1}".format_with(key.InstallLocation.escape_curly_braces(), _fileSystem.directory_exists(key.InstallLocation)));
                    this.Log().Debug(() => " Searched for registry key '{0}' value '{1}' - found? {2}".format_with(key.KeyPath.escape_curly_braces(), ApplicationParameters.RegistryValueInstallLocation, _registryService.value_exists(key.KeyPath, ApplicationParameters.RegistryValueInstallLocation)));
                    continue;
                }

                // split on " /" and " -" for quite a bit more accuracy
                IList <string> uninstallArgsSplit = key.UninstallString.to_string().Split(new[] { " /", " -" }, StringSplitOptions.RemoveEmptyEntries).ToList();
                var            uninstallExe       = uninstallArgsSplit.DefaultIfEmpty(string.Empty).FirstOrDefault();
                var            uninstallArgs      = key.UninstallString.to_string().Replace(uninstallExe.to_string(), string.Empty);
                uninstallExe = uninstallExe.remove_surrounding_quotes();
                this.Log().Debug(() => " Uninstaller path is '{0}'".format_with(uninstallExe));

                if (!key.HasQuietUninstall)
                {
                    IInstaller installer = new CustomInstaller();

                    switch (key.InstallerType)
                    {
                    case InstallerType.Msi:
                        installer = new MsiInstaller();
                        break;

                    case InstallerType.InnoSetup:
                        installer = new InnoSetupInstaller();
                        break;

                    case InstallerType.Nsis:
                        installer = new NsisInstaller();
                        break;

                    case InstallerType.InstallShield:
                        installer = new InstallShieldInstaller();
                        break;

                    default:
                        // skip
                        break;
                    }

                    this.Log().Debug(() => " Installer type is '{0}'".format_with(installer.GetType().Name));


                    //todo: ultimately we should merge keys with logging
                    uninstallArgs += " " + installer.build_uninstall_command_arguments();
                }

                if (key.InstallerType == InstallerType.Msi)
                {
                    //because sometimes the key is set with /i to allow for modify :/
                    uninstallArgs = uninstallArgs.Replace("/I{", "/X{");
                    uninstallArgs = uninstallArgs.Replace("/i{", "/X{");
                    uninstallArgs = uninstallArgs.Replace("/I ", "/X ");
                    uninstallArgs = uninstallArgs.Replace("/i ", "/X ");
                }

                this.Log().Debug(() => " Args are '{0}'".format_with(uninstallArgs));

                var exitCode = _commandExecutor.execute(
                    uninstallExe,
                    uninstallArgs.trim_safe(),
                    config.CommandExecutionTimeoutSeconds,
                    (s, e) =>
                {
                    if (e == null || string.IsNullOrWhiteSpace(e.Data))
                    {
                        return;
                    }
                    this.Log().Debug(() => " [AutoUninstaller] {0}".format_with(e.Data));
                },
                    (s, e) =>
                {
                    if (e == null || string.IsNullOrWhiteSpace(e.Data))
                    {
                        return;
                    }
                    this.Log().Error(() => " [AutoUninstaller] {0}".format_with(e.Data));
                },
                    updateProcessPath: false);

                if (exitCode != 0)
                {
                    Environment.ExitCode = exitCode;
                    string logMessage = " Auto uninstaller failed. Please remove machine installation manually.";
                    this.Log().Error(() => logMessage);
                    packageResult.Messages.Add(new ResultMessage(ResultType.Error, logMessage));
                }
                else
                {
                    this.Log().Info(() => " Auto uninstaller has successfully uninstalled {0} from your machine.".format_with(packageResult.Package.Id));
                }
            }
        }
예제 #11
0
        public void install(ChocolateyConfiguration configuration, PackageResult packageResult)
        {
            if (!configuration.Features.UseShimGenService)
            {
                return;
            }

            _fileSystem.create_directory_if_not_exists(ApplicationParameters.ShimsLocation);

            if (packageResult.InstallLocation.is_equal_to(ApplicationParameters.InstallLocation) || packageResult.InstallLocation.is_equal_to(ApplicationParameters.PackagesLocation))
            {
                var logMessage = "Install location is not specific enough, cannot run shimgen:{0} Erroneous install location captured as '{1}'".format_with(Environment.NewLine, packageResult.InstallLocation);
                packageResult.Messages.Add(new ResultMessage(ResultType.Warn, logMessage));
                this.Log().Error(logMessage.escape_curly_braces());
                return;
            }

            //gather all .exes in the folder
            var exeFiles = _fileSystem.get_files(packageResult.InstallLocation, pattern: "*.exe", option: SearchOption.AllDirectories);

            foreach (string file in exeFiles.or_empty_list_if_null())
            {
                if (_fileSystem.file_exists(file + ".ignore"))
                {
                    continue;
                }
                bool isGui = _fileSystem.file_exists(file + ".gui");
                //todo: v2 be able to determine gui automatically

                var args           = ExternalCommandArgsBuilder.build_arguments(configuration, _shimGenArguments);
                var shimLocation   = _fileSystem.combine_paths(ApplicationParameters.ShimsLocation, _fileSystem.get_file_name(file));
                var argsForPackage = args.Replace(PATH_TOKEN, file.Replace(ApplicationParameters.InstallLocation, "..\\")).Replace(OUTPUT_TOKEN, shimLocation).Replace(ICON_PATH_TOKEN, file);
                if (isGui)
                {
                    argsForPackage += " --gui";
                }

                var exitCode = _commandExecutor.execute(
                    ApplicationParameters.Tools.ShimGenExe, argsForPackage, configuration.CommandExecutionTimeoutSeconds,
                    (s, e) =>
                {
                    if (string.IsNullOrWhiteSpace(e.Data))
                    {
                        return;
                    }
                    this.Log().Debug(() => " [ShimGen] {0}".format_with(e.Data.escape_curly_braces()));
                },
                    (s, e) =>
                {
                    if (string.IsNullOrWhiteSpace(e.Data))
                    {
                        return;
                    }
                    this.Log().Error(() => " [ShimGen] {0}".format_with(e.Data.escape_curly_braces()));
                },
                    updateProcessPath: true
                    );

                if (exitCode != 0)
                {
                    Environment.ExitCode = exitCode;
                }
                else
                {
                    this.Log().Info(() => " ShimGen has successfully created a {0}shim for {1}".format_with(isGui ? "gui " : string.Empty, _fileSystem.get_file_name(file)));
                    this.Log().Debug(() => "  Created: {0}{1}  Targeting: {2}{1}  IsGui:{3}{1}".format_with(shimLocation, Environment.NewLine, file, isGui));
                }
            }
        }
예제 #12
0
        public ConcurrentDictionary <string, PackageResult> install_run(ChocolateyConfiguration configuration, Action <PackageResult> continueAction)
        {
            var packageInstalls = new ConcurrentDictionary <string, PackageResult>();

            var args = ExternalCommandArgsBuilder.build_arguments(configuration, _webPiInstallArguments);

            foreach (var packageToInstall in configuration.PackageNames.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries))
            {
                var argsForPackage = args.Replace(PACKAGE_NAME_TOKEN, packageToInstall);
                var exitCode       = _commandExecutor.execute(
                    _webPiExePath, argsForPackage, configuration.CommandExecutionTimeoutSeconds,
                    (s, e) =>
                {
                    var logMessage = e.Data;
                    if (string.IsNullOrWhiteSpace(logMessage))
                    {
                        return;
                    }
                    this.Log().Debug(() => " [WebPI] {0}".format_with(logMessage));

                    var packageName    = get_value_from_output(logMessage, ApplicationParameters.OutputParser.Nuget.PackageName, ApplicationParameters.OutputParser.Nuget.PACKAGE_NAME_GROUP);
                    var packageVersion = get_value_from_output(logMessage, ApplicationParameters.OutputParser.Nuget.PackageVersion, ApplicationParameters.OutputParser.Nuget.PACKAGE_VERSION_GROUP);

                    if (ApplicationParameters.OutputParser.Nuget.ResolvingDependency.IsMatch(logMessage))
                    {
                        return;
                    }

                    var results = packageInstalls.GetOrAdd(packageName, new PackageResult(packageName, packageVersion, _webPiInstallArguments["_output_directory_"].ArgumentValue));

                    if (ApplicationParameters.OutputParser.Nuget.NotInstalled.IsMatch(logMessage))
                    {
                        this.Log().Error("{0} not installed: {1}".format_with(packageName, logMessage));
                        results.Messages.Add(new ResultMessage(ResultType.Error, logMessage));

                        return;
                    }

                    if (ApplicationParameters.OutputParser.Nuget.Installing.IsMatch(logMessage))
                    {
                        return;
                    }

                    if (string.IsNullOrWhiteSpace(packageName))
                    {
                        return;
                    }

                    this.Log().Info(ChocolateyLoggers.Important, "{0} {1}".format_with(packageName, !string.IsNullOrWhiteSpace(packageVersion) ? "v" + packageVersion : string.Empty));

                    if (ApplicationParameters.OutputParser.Nuget.AlreadyInstalled.IsMatch(logMessage) && !configuration.Force)
                    {
                        results.Messages.Add(new ResultMessage(ResultType.Inconclusive, packageName));
                        this.Log().Warn(" Already installed.");
                        this.Log().Warn(ChocolateyLoggers.Important, " Use -force if you want to reinstall.".format_with(Environment.NewLine));
                        return;
                    }

                    results.Messages.Add(new ResultMessage(ResultType.Debug, ApplicationParameters.Messages.ContinueChocolateyAction));
                    if (continueAction != null)
                    {
                        continueAction.Invoke(results);
                    }
                },
                    (s, e) =>
                {
                    if (string.IsNullOrWhiteSpace(e.Data))
                    {
                        return;
                    }
                    this.Log().Error(() => "{0}".format_with(e.Data));
                },
                    updateProcessPath: false
                    );

                if (exitCode != 0)
                {
                    Environment.ExitCode = exitCode;
                }
            }
            return(packageInstalls);
        }
예제 #13
0
        public void remove(RegistryApplicationKey key, ChocolateyConfiguration config, PackageResult packageResult, string packageCacheLocation)
        {
            var userProvidedUninstallArguments = string.Empty;
            var userOverrideUninstallArguments = false;
            var package = packageResult.Package;

            if (package != null)
            {
                if (!PackageUtility.package_is_a_dependency(config, package.Id) || config.ApplyInstallArgumentsToDependencies)
                {
                    userProvidedUninstallArguments = config.InstallArguments;
                    userOverrideUninstallArguments = config.OverrideArguments;

                    if (!string.IsNullOrWhiteSpace(userProvidedUninstallArguments))
                    {
                        this.Log().Debug(ChocolateyLoggers.Verbose, " Using user passed {2}uninstaller args for {0}:'{1}'".format_with(package.Id, userProvidedUninstallArguments.escape_curly_braces(), userOverrideUninstallArguments ? "overriding " : string.Empty));
                    }
                }
            }

            //todo: if there is a local package, look to use it in the future
            if (string.IsNullOrWhiteSpace(key.UninstallString))
            {
                this.Log().Info(" Skipping auto uninstaller - '{0}' does not have an uninstall string.".format_with(!string.IsNullOrEmpty(key.DisplayName.to_string()) ? key.DisplayName.to_string().escape_curly_braces() : "The application"));
                return;
            }

            this.Log().Debug(() => " Preparing uninstall key '{0}' for '{1}'".format_with(key.UninstallString.to_string().escape_curly_braces(), key.DisplayName.to_string().escape_curly_braces()));

            if ((!string.IsNullOrWhiteSpace(key.InstallLocation) && !_fileSystem.directory_exists(key.InstallLocation)) || !_registryService.installer_value_exists(key.KeyPath, ApplicationParameters.RegistryValueInstallLocation))
            {
                this.Log().Info(" Skipping auto uninstaller - '{0}' appears to have been uninstalled already by other means.".format_with(!string.IsNullOrEmpty(key.DisplayName.to_string()) ? key.DisplayName.to_string().escape_curly_braces() : "The application"));
                this.Log().Debug(() => " Searched for install path '{0}' - found? {1}".format_with(key.InstallLocation.to_string().escape_curly_braces(), _fileSystem.directory_exists(key.InstallLocation)));
                this.Log().Debug(() => " Searched for registry key '{0}' value '{1}' - found? {2}".format_with(key.KeyPath.escape_curly_braces(), ApplicationParameters.RegistryValueInstallLocation, _registryService.installer_value_exists(key.KeyPath, ApplicationParameters.RegistryValueInstallLocation)));
                return;
            }

            // split on " /" and " -" for quite a bit more accuracy
            IList <string> uninstallArgsSplit = key.UninstallString.to_string().Replace("&quot;", "\"").Replace("&apos;", "'").Split(new[] { " /", " -" }, StringSplitOptions.RemoveEmptyEntries).ToList();
            var            uninstallExe       = uninstallArgsSplit.DefaultIfEmpty(string.Empty).FirstOrDefault().trim_safe();

            if (uninstallExe.Count(u => u == '"') > 2)
            {
                uninstallExe = uninstallExe.Split(new [] { " \"" }, StringSplitOptions.RemoveEmptyEntries).First();
            }

            if (uninstallExe.Count(u => u == ':') > 1)
            {
                try
                {
                    var firstMatch = Regex.Match(uninstallExe, @"\s+\w\:", RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
                    uninstallExe = uninstallExe.Substring(0, firstMatch.Index);
                }
                catch (Exception ex)
                {
                    this.Log().Debug("Error splitting the uninstall string:{0} {1}".format_with(Environment.NewLine, ex.to_string()));
                }
            }
            var uninstallArgs = key.UninstallString.to_string().Replace("&quot;", "\"").Replace("&apos;", "'").Replace(uninstallExe.to_string(), string.Empty).trim_safe();

            uninstallExe = uninstallExe.remove_surrounding_quotes();
            this.Log().Debug(() => " Uninstaller path is '{0}'".format_with(uninstallExe));

            if (uninstallExe.contains("\\") || uninstallExe.contains("/"))
            {
                if (!_fileSystem.file_exists(uninstallExe))
                {
                    this.Log().Info(" Skipping auto uninstaller - The uninstaller file no longer exists. \"{0}\"".format_with(uninstallExe));
                    return;
                }
            }

            IInstaller installer = get_installer_type(key, uninstallExe, uninstallArgs);

            this.Log().Debug(() => " Installer type is '{0}'".format_with(installer.GetType().Name));

            if (key.InstallerType == InstallerType.Msi)
            {
                // because sometimes the key is set with /i to allow for modify :/
                uninstallArgs = uninstallArgs.Replace("/I{", "/X{");
                uninstallArgs = uninstallArgs.Replace("/i{", "/X{");
                uninstallArgs = uninstallArgs.Replace("/I ", "/X ");
                uninstallArgs = uninstallArgs.Replace("/i ", "/X ");
            }

            if (!key.HasQuietUninstall)
            {
                //todo: ultimately we should merge keys
                uninstallArgs += " " + installer.build_uninstall_command_arguments();
            }

            if (!string.IsNullOrWhiteSpace(userProvidedUninstallArguments))
            {
                if (userOverrideUninstallArguments)
                {
                    this.Log().Debug(() => " Replacing original uninstall arguments of '{0}' with '{1}'".format_with(uninstallArgs.escape_curly_braces(), userProvidedUninstallArguments.escape_curly_braces()));
                    uninstallArgs = userProvidedUninstallArguments;
                }
                else
                {
                    this.Log().Debug(() => " Appending original uninstall arguments with '{0}'".format_with(userProvidedUninstallArguments.escape_curly_braces()));
                    uninstallArgs += " " + userProvidedUninstallArguments;
                }
            }

            this.Log().Debug(() => " Setting up uninstall logging directory at {0}".format_with(packageCacheLocation.escape_curly_braces()));
            _fileSystem.create_directory_if_not_exists(_fileSystem.get_directory_name(packageCacheLocation));
            uninstallArgs = uninstallArgs.Replace(InstallTokens.PACKAGE_LOCATION, packageCacheLocation);
            uninstallArgs = uninstallArgs.Replace(InstallTokens.TEMP_LOCATION, packageCacheLocation);

            this.Log().Debug(() => " Args are '{0}'".format_with(uninstallArgs.escape_curly_braces()));

            if (!key.HasQuietUninstall && installer.GetType() == typeof(CustomInstaller))
            {
                var skipUninstaller = true;

                var timeout = config.PromptForConfirmation ? 0 : 30;

                var selection = InteractivePrompt.prompt_for_confirmation(
                    "Uninstall may not be silent (could not detect). Proceed?",
                    new[] { "yes", "no" },
                    defaultChoice: "no",
                    requireAnswer: true,
                    allowShortAnswer: true,
                    shortPrompt: true,
                    timeoutInSeconds: timeout
                    );
                if (selection.is_equal_to("yes"))
                {
                    skipUninstaller = false;
                }

                if (skipUninstaller)
                {
                    this.Log().Info(" Skipping auto uninstaller - Installer type was not detected and no silent uninstall key exists.");
                    this.Log().Warn("If the application was not removed with a chocolateyUninstall.ps1,{0} please remove it from Programs and Features manually.".format_with(Environment.NewLine));
                    return;
                }
            }

            var exitCode = _commandExecutor.execute(
                uninstallExe,
                uninstallArgs.trim_safe(),
                config.CommandExecutionTimeoutSeconds,
                (s, e) =>
            {
                if (e == null || string.IsNullOrWhiteSpace(e.Data))
                {
                    return;
                }
                this.Log().Info(() => " [AutoUninstaller] {0}".format_with(e.Data.escape_curly_braces()));
            },
                (s, e) =>
            {
                if (e == null || string.IsNullOrWhiteSpace(e.Data))
                {
                    return;
                }
                this.Log().Error(() => " [AutoUninstaller] {0}".format_with(e.Data.escape_curly_braces()));
            },
                updateProcessPath: false);

            if (!installer.ValidUninstallExitCodes.Contains(exitCode))
            {
                Environment.ExitCode = exitCode;
                string logMessage = " Auto uninstaller failed. Please remove machine installation manually.{0} Exit code was {1}".format_with(Environment.NewLine, exitCode);
                this.Log().Error(() => logMessage.escape_curly_braces());
                packageResult.Messages.Add(new ResultMessage(config.Features.FailOnAutoUninstaller ? ResultType.Error : ResultType.Warn, logMessage));
            }
            else
            {
                this.Log().Info(() => " Auto uninstaller has successfully uninstalled {0} or detected previous uninstall.".format_with(packageResult.Package.Id));
            }
        }