Beispiel #1
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 (!_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> uninstallArgs = key.UninstallString.to_string().Split(new[] { " /", " -" }, StringSplitOptions.RemoveEmptyEntries).ToList();
                var            uninstallExe  = uninstallArgs.DefaultIfEmpty(string.Empty).FirstOrDefault();
                uninstallArgs.Remove(uninstallExe);
                uninstallExe = uninstallExe.remove_surrounding_quotes();
                this.Log().Debug(() => " Uninstaller path is '{0}'".format_with(uninstallExe));

                //todo: ultimately we should merge keys with logging
                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 CustomInstaller();
                        break;

                    default:
                        // skip
                        break;
                    }

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

                    uninstallArgs.Add(installer.build_uninstall_command_arguments());
                }

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

                var exitCode = _commandExecutor.execute(
                    uninstallExe,
                    uninstallArgs.@join(" "),
                    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));
                });

                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));
                }
            }
        }