public virtual IInstaller get_installer_type(RegistryApplicationKey key, string uninstallExe, string uninstallArgs)
        {
            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;
            }

            return(installer);
        }
Exemple #2
0
        public void AddInstallEntry(RegistryApplicationKey appKey)
        {
            Type type = appKey.GetType();

            appKey.Hive         = Microsoft.Win32.RegistryHive.LocalMachine;
            appKey.RegistryView = Microsoft.Win32.RegistryView.Default;
            appKey.KeyPath      = $"HKEY_LOCAL_MACHINE\\{RegistryService.UNINSTALLER_KEY_NAME}\\{appKey.PackageId}";
            appKey.Publisher    = "TestRegistry";

            // So control panel would see it:
            appKey.UninstallString = "none";
            appKey.DisplayName     = appKey.PackageId;
            appKey.DisplayVersion  = appKey.Version.ToString();

            List <string> propNames = RegistryApplicationKey.GetPropertyNames(true);

            foreach (string propName in propNames.ToArray())
            {
                var prop = type.GetProperty(propName);
                if (prop.GetValue(appKey) == null)
                {
                    propNames.Remove(propName);
                }
            }

            registryService.set_key_values(appKey, propNames.ToArray());
        }
Exemple #3
0
        public void set_key_values(RegistryApplicationKey appKey, params string[] properties)
        {
            // Hive is in double with appKey.KeyPath.Split('\\')[0]
            // https://stackoverflow.com/questions/58510869/c-sharp-get-basekey-from-registrykey
            // maybe makes sense to centralize later on.

            var    key     = open_key(appKey.Hive, appKey.RegistryView);
            string subPath = String.Join("\\", appKey.KeyPath.Split('\\').Skip(1));
            var    subKey  = FaultTolerance.try_catch_with_logging_exception(
                () => key.OpenSubKey(subPath, true),
                $"Could not open subkey {appKey.KeyPath}",
                logWarningInsteadOfError: true);

            if (subKey == null)
            {
                subKey = FaultTolerance.try_catch_with_logging_exception(
                    () => key.CreateSubKey(subPath, true),
                    $"Could not open subkey {appKey.KeyPath}",
                    logWarningInsteadOfError: true);
            }

            if (subKey != null)
            {
                foreach (string prop in properties)
                {
                    var               propInfo = appKey.GetType().GetProperty(prop);
                    object            value;
                    RegistryValueKind type = RegistryValueKind.DWord;

                    if (propInfo.PropertyType == typeof(long))
                    {
                        value = (long)propInfo.GetValue(appKey);
                        type  = RegistryValueKind.DWord;
                    }
                    else if (propInfo.PropertyType == typeof(bool))
                    {
                        bool bvalue = (bool)propInfo.GetValue(appKey);

                        if (!bvalue && propInfo.Name == nameof(RegistryApplicationKey.IsPinned))
                        {
                            subKey.DeleteValue(propInfo.Name, false);
                            continue;
                        }

                        value = (bvalue) ? 1: 0;
                        type  = RegistryValueKind.DWord;
                    }
                    else
                    {
                        value = propInfo.GetValue(appKey).ToString();
                        type  = RegistryValueKind.String;
                    }

                    subKey.SetValue(propInfo.Name, value, type);
                }
            }
        }
Exemple #4
0
        public void delete_key(RegistryApplicationKey appKey)
        {
            var    key     = open_key(appKey.Hive, appKey.RegistryView);
            string subPath = String.Join("\\", appKey.KeyPath.Split('\\').Skip(1));

            FaultTolerance.try_catch_with_logging_exception(
                () => key.DeleteSubKey(subPath, false),
                $"Could not delete subkey {appKey.KeyPath}",
                logWarningInsteadOfError: true
                );
        }
Exemple #5
0
        public RegistryPackage(RegistryApplicationKey registryKey)
        {
            Listed      = true;
            RegistryKey = registryKey;
            SemanticVersion semversion;

            SemanticVersion.TryParse(registryKey.Version, out semversion);
            Version  = semversion;
            Id       = registryKey.PackageId;
            IsPinned = registryKey.IsPinned;
        }
Exemple #6
0
        public void DeleteInstallEntries(params string[] packageIds)
        {
            foreach (string packageId in packageIds)
            {
                var keyInfo = new RegistryApplicationKey()
                {
                    Hive         = Microsoft.Win32.RegistryHive.LocalMachine,
                    KeyPath      = $"HKEY_LOCAL_MACHINE\\{RegistryService.UNINSTALLER_KEY_NAME}\\{packageId}",
                    RegistryView = Microsoft.Win32.RegistryView.Default
                };

                registryService.delete_key(keyInfo);
            }
        }
        public virtual IInstaller get_installer_type(RegistryApplicationKey key, string uninstallExe, string uninstallArgs)
        {
            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;
            }

            return installer;
        }
Exemple #8
0
        /// <summary>
        ///   Evaluates registry keys and updates the snapshop with items
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="snapshot">The snapshot.</param>
        public void evaluate_keys(RegistryKey key, Registry snapshot)
        {
            if (key == null)
            {
                return;
            }

            FaultTolerance.try_catch_with_logging_exception(
                () =>
            {
                foreach (var subKeyName in key.GetSubKeyNames())
                {
                    FaultTolerance.try_catch_with_logging_exception(
                        () => evaluate_keys(key.OpenSubKey(subKeyName, RegistryKeyPermissionCheck.ReadSubTree, RegistryRights.ReadKey), snapshot),
                        "Failed to open subkey named '{0}' for '{1}', likely due to permissions".format_with(subKeyName, key.Name),
                        logWarningInsteadOfError: true);
                }
            },
                "Failed to open subkeys for '{0}', likely due to permissions".format_with(key.Name),
                logWarningInsteadOfError: true);

            var appKey = new RegistryApplicationKey
            {
                KeyPath      = key.Name,
                RegistryView = key.View,
                DefaultValue = key.GetValue("").to_string(),
                DisplayName  = key.GetValue("DisplayName").to_string()
            };

            if (string.IsNullOrWhiteSpace(appKey.DisplayName))
            {
                appKey.DisplayName = appKey.DefaultValue;
            }

            if (!string.IsNullOrWhiteSpace(appKey.DisplayName))
            {
                appKey.InstallLocation = key.GetValue("InstallLocation").to_string();
                appKey.UninstallString = key.GetValue("UninstallString").to_string();
                if (key.GetValue("QuietUninstallString") != null)
                {
                    appKey.UninstallString   = key.GetValue("QuietUninstallString").to_string();
                    appKey.HasQuietUninstall = true;
                }

                // informational
                appKey.Publisher     = key.GetValue("Publisher").to_string();
                appKey.InstallDate   = key.GetValue("InstallDate").to_string();
                appKey.InstallSource = key.GetValue("InstallSource").to_string();
                appKey.Language      = key.GetValue("Language").to_string();

                // Version
                appKey.DisplayVersion = key.GetValue("DisplayVersion").to_string();
                appKey.Version        = key.GetValue("Version").to_string();
                appKey.VersionMajor   = key.GetValue("VersionMajor").to_string();
                appKey.VersionMinor   = key.GetValue("VersionMinor").to_string();

                // installinformation
                appKey.SystemComponent  = key.GetValue("SystemComponent").to_string() == "1";
                appKey.WindowsInstaller = key.GetValue("WindowsInstaller").to_string() == "1";
                appKey.NoRemove         = key.GetValue("NoRemove").to_string() == "1";
                appKey.NoModify         = key.GetValue("NoModify").to_string() == "1";
                appKey.NoRepair         = key.GetValue("NoRepair").to_string() == "1";
                appKey.ReleaseType      = key.GetValue("ReleaseType").to_string();
                appKey.ParentKeyName    = key.GetValue("ParentKeyName").to_string();

                if (appKey.WindowsInstaller || appKey.UninstallString.to_lower().Contains("msiexec"))
                {
                    appKey.InstallerType = InstallerType.Msi;
                }

                if (key.Name.EndsWith("_is1") || !string.IsNullOrWhiteSpace(key.GetValue("Inno Setup: Setup Version").to_string()))
                {
                    appKey.InstallerType = InstallerType.InnoSetup;
                }

                if (key.GetValue("dwVersionMajor") != null)
                {
                    appKey.InstallerType   = InstallerType.Nsis;
                    appKey.VersionMajor    = key.GetValue("dwVersionMajor").to_string();
                    appKey.VersionMinor    = key.GetValue("dwVersionMinor").to_string();
                    appKey.VersionRevision = key.GetValue("dwVersionRev").to_string();
                    appKey.VersionBuild    = key.GetValue("dwVersionBuild").to_string();
                }
                if (appKey.ReleaseType.is_equal_to("Hotfix") || appKey.ReleaseType.is_equal_to("Update Rollup") || appKey.ReleaseType.is_equal_to("Security Update") || appKey.DefaultValue.to_string().StartsWith("KB", ignoreCase: true, culture: CultureInfo.InvariantCulture))
                {
                    appKey.InstallerType = InstallerType.HotfixOrSecurityUpdate;
                }
                if (appKey.ReleaseType.is_equal_to("ServicePack"))
                {
                    appKey.InstallerType = InstallerType.ServicePack;
                }

                // assume NSIS if we still don't know and we find uninst.exe
                if (appKey.InstallerType == InstallerType.Unknown && appKey.UninstallString.to_lower().Contains("uninst.exe"))
                {
                    appKey.InstallerType = InstallerType.Nsis;
                }

                if (appKey.InstallerType == InstallerType.Unknown && appKey.HasQuietUninstall)
                {
                    appKey.InstallerType = InstallerType.Custom;
                }

                if (_logOutput)
                {
                    if (appKey.is_in_programs_and_features() && appKey.InstallerType == InstallerType.Unknown)
                    {
                        foreach (var name in key.GetValueNames())
                        {
                            //var kind = key.GetValueKind(name);
                            var value = key.GetValue(name);
                            if (name.is_equal_to("QuietUninstallString") || name.is_equal_to("UninstallString"))
                            {
                                Console.WriteLine("key - {0}|{1}={2}|Type detected={3}".format_with(key.Name, name, value.to_string(), appKey.InstallerType.to_string()));
                            }

                            //Console.WriteLine("key - {0}, name - {1}, kind - {2}, value - {3}".format_with(key.Name, name, kind, value.to_string()));
                        }
                    }
                }

                snapshot.RegistryKeys.Add(appKey);
            }

            key.Close();
            key.Dispose();
        }
        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));
            }
        }
Exemple #10
0
        private void get_msi_information(RegistryApplicationKey appKey, RegistryKey key)
        {
            _componentLoopCount = 0;

            var userDataProductKeyId = get_msi_user_data_key(key.Name);
            if (string.IsNullOrWhiteSpace(userDataProductKeyId)) return;

            var hklm = open_key(RegistryHive.LocalMachine, RegistryView.Default);
            if (Environment.Is64BitOperatingSystem)
            {
                hklm = open_key(RegistryHive.LocalMachine, RegistryView.Registry64);
            }

            FaultTolerance.try_catch_with_logging_exception(
             () =>
             {
                 var msiRegistryKey = hklm.OpenSubKey(UNINSTALLER_MSI_MACHINE_KEY_NAME, RegistryKeyPermissionCheck.ReadSubTree, RegistryRights.ReadKey);
                 if (msiRegistryKey == null) return;

                 foreach (var subKeyName in msiRegistryKey.GetSubKeyNames())
                 {
                     var msiProductKey = FaultTolerance.try_catch_with_logging_exception(
                         () => msiRegistryKey.OpenSubKey("{0}\\Products\\{1}\\InstallProperties".format_with(subKeyName, userDataProductKeyId), RegistryKeyPermissionCheck.ReadSubTree, RegistryRights.ReadKey),
                         "Failed to open subkey named '{0}' for '{1}', likely due to permissions".format_with(subKeyName, msiRegistryKey.Name),
                         logWarningInsteadOfError: true);
                     if (msiProductKey == null) continue;

                     appKey.InstallLocation = set_if_empty(appKey.InstallLocation, msiProductKey.get_value_as_string("InstallLocation"));
                     // informational
                     appKey.Publisher = set_if_empty(appKey.Publisher, msiProductKey.get_value_as_string("Publisher"));
                     appKey.InstallDate = set_if_empty(appKey.InstallDate, msiProductKey.get_value_as_string("InstallDate"));
                     appKey.InstallSource = set_if_empty(appKey.InstallSource, msiProductKey.get_value_as_string("InstallSource"));
                     appKey.Language = set_if_empty(appKey.Language, msiProductKey.get_value_as_string("Language"));
                     appKey.LocalPackage = set_if_empty(appKey.LocalPackage, msiProductKey.get_value_as_string("LocalPackage"));

                     // Version
                     appKey.DisplayVersion = set_if_empty(appKey.DisplayVersion, msiProductKey.get_value_as_string("DisplayVersion"));
                     appKey.Version = set_if_empty(appKey.Version, msiProductKey.get_value_as_string("Version"));
                     appKey.VersionMajor = set_if_empty(appKey.VersionMajor, msiProductKey.get_value_as_string("VersionMajor"));
                     appKey.VersionMinor = set_if_empty(appKey.VersionMinor, msiProductKey.get_value_as_string("VersionMinor"));

                     // search components for install location if still empty
                     // the performance of this is very bad - without this the query is sub-second
                     // with this it takes about 15 seconds with around 200 apps installed
                     //if (string.IsNullOrWhiteSpace(appKey.InstallLocation) && !appKey.Publisher.contains("Microsoft"))
                     //{
                     //    var msiComponentsKey = FaultTolerance.try_catch_with_logging_exception(
                     //       () => msiRegistryKey.OpenSubKey("{0}\\Components".format_with(subKeyName), RegistryKeyPermissionCheck.ReadSubTree, RegistryRights.ReadKey),
                     //       "Failed to open subkey named '{0}' for '{1}', likely due to permissions".format_with(subKeyName, msiRegistryKey.Name),
                     //       logWarningInsteadOfError: true);
                     //    if (msiComponentsKey == null) continue;

                     //    foreach (var msiComponentKeyName in msiComponentsKey.GetSubKeyNames())
                     //    {
                     //        var msiComponentKey = FaultTolerance.try_catch_with_logging_exception(
                     //           () => msiComponentsKey.OpenSubKey(msiComponentKeyName, RegistryKeyPermissionCheck.ReadSubTree, RegistryRights.ReadKey),
                     //           "Failed to open subkey named '{0}' for '{1}', likely due to permissions".format_with(subKeyName, msiRegistryKey.Name),
                     //           logWarningInsteadOfError: true);

                     //        if (msiComponentKey.GetValueNames().Contains(userDataProductKeyId, StringComparer.OrdinalIgnoreCase))
                     //        {
                     //            _componentLoopCount++;
                     //            appKey.InstallLocation = set_if_empty(appKey.InstallLocation, get_install_location_estimate(msiComponentKey.get_value(userDataProductKeyId)));
                     //            if (!string.IsNullOrWhiteSpace(appKey.InstallLocation)) break;
                     //            if (_componentLoopCount >= 10) break;
                     //        }
                     //    }
                     //}
                 }
             },
             "Failed to open subkeys for '{0}', likely due to permissions".format_with(hklm.Name),
             logWarningInsteadOfError: true);
        }
Exemple #11
0
        /// <summary>
        ///   Evaluates registry keys and updates the snapshop with items
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="snapshot">The snapshot.</param>
        public void evaluate_keys(RegistryKey key, Registry snapshot)
        {
            if (key == null) return;

            FaultTolerance.try_catch_with_logging_exception(
                () =>
                {
                    foreach (var subKeyName in key.GetSubKeyNames())
                    {
                        FaultTolerance.try_catch_with_logging_exception(
                            () => evaluate_keys(key.OpenSubKey(subKeyName, RegistryKeyPermissionCheck.ReadSubTree, RegistryRights.ReadKey), snapshot),
                            "Failed to open subkey named '{0}' for '{1}', likely due to permissions".format_with(subKeyName, key.Name),
                            logWarningInsteadOfError: true);
                    }
                },
                "Failed to open subkeys for '{0}', likely due to permissions".format_with(key.Name),
                logWarningInsteadOfError: true);

            var appKey = new RegistryApplicationKey
                {
                    KeyPath = key.Name,
                    RegistryView = key.View,
                    DefaultValue = key.get_value_as_string(""),
                    DisplayName = key.get_value_as_string("DisplayName")
                };

            if (string.IsNullOrWhiteSpace(appKey.DisplayName))
            {
                appKey.DisplayName = appKey.DefaultValue;
            }

            if (!string.IsNullOrWhiteSpace(appKey.DisplayName))
            {
                appKey.InstallLocation = key.get_value_as_string("InstallLocation");
                appKey.UninstallString = key.get_value_as_string("UninstallString");
                if (!string.IsNullOrWhiteSpace(key.get_value_as_string("QuietUninstallString")))
                {
                    appKey.UninstallString = key.get_value_as_string("QuietUninstallString");
                    appKey.HasQuietUninstall = true;
                }

                // informational
                appKey.Publisher = key.get_value_as_string("Publisher");
                appKey.InstallDate = key.get_value_as_string("InstallDate");
                appKey.InstallSource = key.get_value_as_string("InstallSource");
                appKey.Language = key.get_value_as_string("Language");

                // Version
                appKey.DisplayVersion = key.get_value_as_string("DisplayVersion");
                appKey.Version = key.get_value_as_string("Version");
                appKey.VersionMajor = key.get_value_as_string("VersionMajor");
                appKey.VersionMinor = key.get_value_as_string("VersionMinor");

                // installinformation
                appKey.SystemComponent = key.get_value_as_string("SystemComponent") == "1";
                appKey.WindowsInstaller = key.get_value_as_string("WindowsInstaller") == "1";
                appKey.NoRemove = key.get_value_as_string("NoRemove") == "1";
                appKey.NoModify = key.get_value_as_string("NoModify") == "1";
                appKey.NoRepair = key.get_value_as_string("NoRepair") == "1";
                appKey.ReleaseType = key.get_value_as_string("ReleaseType");
                appKey.ParentKeyName = key.get_value_as_string("ParentKeyName");

                if (appKey.WindowsInstaller || appKey.UninstallString.to_string().to_lower().Contains("msiexec"))
                {
                    appKey.InstallerType = InstallerType.Msi;
                }

                if (key.Name.EndsWith("_is1") || !string.IsNullOrWhiteSpace(key.get_value_as_string("Inno Setup: Setup Version")))
                {
                    appKey.InstallerType = InstallerType.InnoSetup;
                }

                if (!string.IsNullOrWhiteSpace(key.get_value_as_string("dwVersionMajor")))
                {
                    appKey.InstallerType = InstallerType.Nsis;
                    appKey.VersionMajor = key.get_value_as_string("dwVersionMajor");
                    appKey.VersionMinor = key.get_value_as_string("dwVersionMinor");
                    appKey.VersionRevision = key.get_value_as_string("dwVersionRev");
                    appKey.VersionBuild = key.get_value_as_string("dwVersionBuild");
                }
                if (appKey.ReleaseType.is_equal_to("Hotfix") || appKey.ReleaseType.is_equal_to("Update Rollup") || appKey.ReleaseType.is_equal_to("Security Update") || appKey.DefaultValue.to_string().StartsWith("KB", ignoreCase: true, culture: CultureInfo.InvariantCulture))
                {
                    appKey.InstallerType = InstallerType.HotfixOrSecurityUpdate;
                }
                if (appKey.ReleaseType.is_equal_to("ServicePack"))
                {
                    appKey.InstallerType = InstallerType.ServicePack;
                }

                // assume NSIS if we still don't know and we find uninst.exe
                if (appKey.InstallerType == InstallerType.Unknown && appKey.UninstallString.to_string().to_lower().Contains("uninst.exe"))
                {
                    appKey.InstallerType = InstallerType.Nsis;
                }

                if (appKey.InstallerType == InstallerType.Unknown && appKey.HasQuietUninstall)
                {
                    appKey.InstallerType = InstallerType.Custom;
                }

                if (appKey.InstallerType == InstallerType.Msi)
                {
                    get_msi_information(appKey, key);
                }

                if (_logOutput)
                {
                    //if (appKey.is_in_programs_and_features() && appKey.InstallerType == InstallerType.Unknown)
                    //{
                        foreach (var name in key.GetValueNames())
                        {
                            //var kind = key.GetValueKind(name);
                            var value = key.get_value_as_string(name);
                            if (name.is_equal_to("QuietUninstallString") || name.is_equal_to("UninstallString"))
                            {
                                Console.WriteLine("key - {0}|{1}={2}|Type detected={3}|install location={4}".format_with(key.Name, name, value.to_string(), appKey.InstallerType.to_string(),appKey.InstallLocation.to_string()));
                            }

                            //Console.WriteLine("key - {0}, name - {1}, kind - {2}, value - {3}".format_with(key.Name, name, kind, value.to_string()));
                        }
                    //}
                }

                snapshot.RegistryKeys.Add(appKey);
            }

            key.Close();
            key.Dispose();
        }
        private void get_msi_information(RegistryApplicationKey appKey, RegistryKey key)
        {
            _componentLoopCount = 0;

            var userDataProductKeyId = get_msi_user_data_key(key.Name);

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

            var hklm = open_key(RegistryHive.LocalMachine, RegistryView.Default);

            if (Environment.Is64BitOperatingSystem)
            {
                hklm = open_key(RegistryHive.LocalMachine, RegistryView.Registry64);
            }

            FaultTolerance.try_catch_with_logging_exception(
                () =>
            {
                var msiRegistryKey = hklm.OpenSubKey(UNINSTALLER_MSI_MACHINE_KEY_NAME, RegistryKeyPermissionCheck.ReadSubTree, RegistryRights.ReadKey);
                if (msiRegistryKey == null)
                {
                    return;
                }

                foreach (var subKeyName in msiRegistryKey.GetSubKeyNames())
                {
                    var msiProductKey = FaultTolerance.try_catch_with_logging_exception(
                        () => msiRegistryKey.OpenSubKey("{0}\\Products\\{1}\\InstallProperties".format_with(subKeyName, userDataProductKeyId), RegistryKeyPermissionCheck.ReadSubTree, RegistryRights.ReadKey),
                        "Failed to open subkey named '{0}' for '{1}', likely due to permissions".format_with(subKeyName, msiRegistryKey.Name),
                        logWarningInsteadOfError: true);
                    if (msiProductKey == null)
                    {
                        continue;
                    }

                    appKey.InstallLocation = set_if_empty(appKey.InstallLocation, msiProductKey.get_value_as_string("InstallLocation"));
                    // informational
                    appKey.Publisher     = set_if_empty(appKey.Publisher, msiProductKey.get_value_as_string("Publisher"));
                    appKey.InstallDate   = set_if_empty(appKey.InstallDate, msiProductKey.get_value_as_string("InstallDate"));
                    appKey.InstallSource = set_if_empty(appKey.InstallSource, msiProductKey.get_value_as_string("InstallSource"));
                    appKey.Language      = set_if_empty(appKey.Language, msiProductKey.get_value_as_string("Language"));
                    appKey.LocalPackage  = set_if_empty(appKey.LocalPackage, msiProductKey.get_value_as_string("LocalPackage"));

                    // Version
                    appKey.DisplayVersion = set_if_empty(appKey.DisplayVersion, msiProductKey.get_value_as_string("DisplayVersion"));
                    appKey.Version        = set_if_empty(appKey.Version, msiProductKey.get_value_as_string("Version"));
                    appKey.VersionMajor   = set_if_empty(appKey.VersionMajor, msiProductKey.get_value_as_string("VersionMajor"));
                    appKey.VersionMinor   = set_if_empty(appKey.VersionMinor, msiProductKey.get_value_as_string("VersionMinor"));

                    // search components for install location if still empty
                    // the performance of this is very bad - without this the query is sub-second
                    // with this it takes about 15 seconds with around 200 apps installed
                    //if (string.IsNullOrWhiteSpace(appKey.InstallLocation) && !appKey.Publisher.contains("Microsoft"))
                    //{
                    //    var msiComponentsKey = FaultTolerance.try_catch_with_logging_exception(
                    //       () => msiRegistryKey.OpenSubKey("{0}\\Components".format_with(subKeyName), RegistryKeyPermissionCheck.ReadSubTree, RegistryRights.ReadKey),
                    //       "Failed to open subkey named '{0}' for '{1}', likely due to permissions".format_with(subKeyName, msiRegistryKey.Name),
                    //       logWarningInsteadOfError: true);
                    //    if (msiComponentsKey == null) continue;

                    //    foreach (var msiComponentKeyName in msiComponentsKey.GetSubKeyNames())
                    //    {
                    //        var msiComponentKey = FaultTolerance.try_catch_with_logging_exception(
                    //           () => msiComponentsKey.OpenSubKey(msiComponentKeyName, RegistryKeyPermissionCheck.ReadSubTree, RegistryRights.ReadKey),
                    //           "Failed to open subkey named '{0}' for '{1}', likely due to permissions".format_with(subKeyName, msiRegistryKey.Name),
                    //           logWarningInsteadOfError: true);

                    //        if (msiComponentKey.GetValueNames().Contains(userDataProductKeyId, StringComparer.OrdinalIgnoreCase))
                    //        {
                    //            _componentLoopCount++;
                    //            appKey.InstallLocation = set_if_empty(appKey.InstallLocation, get_install_location_estimate(msiComponentKey.get_value(userDataProductKeyId)));
                    //            if (!string.IsNullOrWhiteSpace(appKey.InstallLocation)) break;
                    //            if (_componentLoopCount >= 10) break;
                    //        }
                    //    }
                    //}
                }
            },
                "Failed to open subkeys for '{0}', likely due to permissions".format_with(hklm.Name),
                logWarningInsteadOfError: true);
        }
Exemple #13
0
        /// <summary>
        ///   Evaluates registry keys and updates the snapshop with items
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="snapshot">The snapshot.</param>
        public void evaluate_keys(RegistryKey key, Registry snapshot)
        {
            foreach (var subKeyName in key.GetSubKeyNames())
            {
                evaluate_keys(key.OpenSubKey(subKeyName), snapshot);
            }

            var appKey = new RegistryApplicationKey
            {
                KeyPath      = key.Name,
                RegistryView = key.View,
                DefaultValue = key.GetValue("").to_string(),
                DisplayName  = key.GetValue("DisplayName").to_string()
            };

            if (string.IsNullOrWhiteSpace(appKey.DisplayName))
            {
                appKey.DisplayName = appKey.DefaultValue;
            }

            if (!string.IsNullOrWhiteSpace(appKey.DisplayName))
            {
                appKey.InstallLocation = key.GetValue("InstallLocation").to_string();
                appKey.UninstallString = key.GetValue("UninstallString").to_string();
                if (key.GetValue("QuietUninstallString") != null)
                {
                    appKey.UninstallString   = key.GetValue("QuietUninstallString").to_string();
                    appKey.HasQuietUninstall = true;
                }

                // informational
                appKey.Publisher     = key.GetValue("Publisher").to_string();
                appKey.InstallDate   = key.GetValue("InstallDate").to_string();
                appKey.InstallSource = key.GetValue("InstallSource").to_string();
                appKey.Language      = key.GetValue("Language").to_string();

                // Version
                appKey.DisplayVersion = key.GetValue("DisplayVersion").to_string();
                appKey.Version        = key.GetValue("Version").to_string();
                appKey.VersionMajor   = key.GetValue("VersionMajor").to_string();
                appKey.VersionMinor   = key.GetValue("VersionMinor").to_string();

                // installinformation
                appKey.SystemComponent  = key.GetValue("SystemComponent").to_string() == "1";
                appKey.WindowsInstaller = key.GetValue("WindowsInstaller").to_string() == "1";
                appKey.NoRemove         = key.GetValue("NoRemove").to_string() == "1";
                appKey.NoModify         = key.GetValue("NoModify").to_string() == "1";
                appKey.NoRepair         = key.GetValue("NoRepair").to_string() == "1";
                appKey.ReleaseType      = key.GetValue("ReleaseType").to_string();
                appKey.ParentKeyName    = key.GetValue("ParentKeyName").to_string();

                if (appKey.WindowsInstaller || appKey.UninstallString.to_lower().Contains("msiexec"))
                {
                    appKey.InstallerType = InstallerType.Msi;
                }

                if (key.Name.EndsWith("_is1") || !string.IsNullOrWhiteSpace(key.GetValue("Inno Setup: Setup Version").to_string()))
                {
                    appKey.InstallerType = InstallerType.InnoSetup;
                }

                if (key.GetValue("dwVersionMajor") != null)
                {
                    appKey.InstallerType   = InstallerType.Nsis;
                    appKey.VersionMajor    = key.GetValue("dwVersionMajor").to_string();
                    appKey.VersionMinor    = key.GetValue("dwVersionMinor").to_string();
                    appKey.VersionRevision = key.GetValue("dwVersionRev").to_string();
                    appKey.VersionBuild    = key.GetValue("dwVersionBuild").to_string();
                }
                if (appKey.ReleaseType.is_equal_to("Hotfix") || appKey.ReleaseType.is_equal_to("Update Rollup") || appKey.ReleaseType.is_equal_to("Security Update") || appKey.DefaultValue.to_string().StartsWith("KB", ignoreCase: true, culture: CultureInfo.InvariantCulture))
                {
                    appKey.InstallerType = InstallerType.HotfixOrSecurityUpdate;
                }
                if (appKey.ReleaseType.is_equal_to("ServicePack"))
                {
                    appKey.InstallerType = InstallerType.ServicePack;
                }

                if (appKey.InstallerType == InstallerType.Unknown && appKey.HasQuietUninstall)
                {
                    appKey.InstallerType = InstallerType.Custom;
                }

                //if (appKey.InstallerType == InstallerType.Msi)
                //{
                //Console.WriteLine("");
                //if (!string.IsNullOrWhiteSpace(appKey.UninstallString))
                //{
                //    Console.WriteLine(appKey.UninstallString.to_string().Split(new[] { " /", " -" }, StringSplitOptions.RemoveEmptyEntries)[0]);
                //    key.UninstallString.to_string().Split(new[] { " /", " -" }, StringSplitOptions.RemoveEmptyEntries);
                //}
                //foreach (var name in key.GetValueNames())
                //{
                //    var kind = key.GetValueKind(name);
                //    var value = key.GetValue(name);
                //    Console.WriteLine("key - {0}, name - {1}, kind - {2}, value - {3}".format_with(key.Name, name, kind, value.to_string()));
                //}
                //}

                snapshot.RegistryKeys.Add(appKey);
            }

            key.Close();
            key.Dispose();
        }
Exemple #14
0
        /// <summary>
        ///   Evaluates registry keys and updates the snapshop with items
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="snapshot">The snapshot.</param>
        public void evaluate_keys(RegistryKeyInfo regkey, RegistryKey key, Registry snapshot,
                                  string packageId = null, string version = null, bool?nugetInstallable = null)
        {
            if (key == null)
            {
                return;
            }

            FaultTolerance.try_catch_with_logging_exception(
                () =>
            {
                Regex reMatchFile = null;

                if (packageId != null)
                {
                    reMatchFile = FindFilesPatternToRegex.Convert(packageId);
                }

                foreach (var subKeyName in key.GetSubKeyNames())
                {
                    if (reMatchFile != null && !reMatchFile.IsMatch(subKeyName))
                    {
                        continue;
                    }

                    regkey.SubKeyName = subKeyName;

                    FaultTolerance.try_catch_with_logging_exception(
                        () => evaluate_keys(regkey, key.OpenSubKey(subKeyName, RegistryKeyPermissionCheck.ReadSubTree, RegistryRights.ReadKey), snapshot, packageId, version, nugetInstallable),
                        "Failed to open subkey named '{0}' for '{1}', likely due to permissions".format_with(subKeyName, key.Name),
                        logWarningInsteadOfError: true);
                }
            },
                "Failed to open subkeys for '{0}', likely due to permissions".format_with(key.Name),
                logWarningInsteadOfError: true);

            var appKey = new RegistryApplicationKey
            {
                Hive         = regkey.hive,
                KeyPath      = key.Name,
                RegistryView = key.View,
                DefaultValue = key.get_value_as_string(""),
                DisplayName  = key.get_value_as_string("DisplayName")
            };

            if (string.IsNullOrWhiteSpace(appKey.DisplayName))
            {
                appKey.DisplayName = appKey.DefaultValue;
            }

            bool addRegEntry = false;

            if (!string.IsNullOrWhiteSpace(appKey.DisplayName))
            {
                addRegEntry      = true;
                appKey.PackageId = key.get_value_as_string("PackageId");
                if (string.IsNullOrWhiteSpace(appKey.PackageId))
                {
                    appKey.PackageId = regkey.SubKeyName;
                }

                string s = key.get_value_as_string(nameof(RegistryApplicationKey.IsPinned));
                if (string.IsNullOrWhiteSpace(s))
                {
                    appKey.IsPinned = false;
                }
                else
                {
                    appKey.IsPinned = s != "0";
                }
                appKey.InstallLocation = key.get_value_as_string("InstallLocation");

                if (nugetInstallable.HasValue)
                {
                    string dir = appKey.InstallLocation;
                    bool   isNugetInstallable = false;

                    if (!String.IsNullOrEmpty(dir))
                    {
                        string parentDir     = System.IO.Path.GetDirectoryName(dir);
                        string parentDirName = System.IO.Path.GetFileName(dir);
                        if (parentDirName == appKey.PackageId)
                        {
                            string nuspecPath = System.IO.Path.Combine(dir, appKey.PackageId + NuGet.Constants.ManifestExtension);
                            isNugetInstallable = System.IO.File.Exists(nuspecPath);
                        }
                    }

                    if (nugetInstallable.Value != isNugetInstallable)
                    {
                        addRegEntry = false;
                    }
                }
            }

            if (addRegEntry)
            {
                appKey.UninstallString = key.get_value_as_string("UninstallString");
                if (!string.IsNullOrWhiteSpace(key.get_value_as_string("QuietUninstallString")))
                {
                    appKey.UninstallString   = key.get_value_as_string("QuietUninstallString");
                    appKey.HasQuietUninstall = true;
                }

                // informational
                appKey.Publisher     = key.get_value_as_string("Publisher");
                appKey.InstallDate   = key.get_value_as_string("InstallDate");
                appKey.InstallSource = key.get_value_as_string("InstallSource");
                appKey.Language      = key.get_value_as_string("Language");

                // Version
                appKey.DisplayVersion = key.get_value_as_string("DisplayVersion");
                appKey.Version        = key.get_value_as_string("Version");
                appKey.VersionMajor   = key.get_value_as_string("VersionMajor");
                appKey.VersionMinor   = key.get_value_as_string("VersionMinor");

                // installinformation
                appKey.SystemComponent  = key.get_value_as_string("SystemComponent") == "1";
                appKey.WindowsInstaller = key.get_value_as_string("WindowsInstaller") == "1";
                appKey.NoRemove         = key.get_value_as_string("NoRemove") == "1";
                appKey.NoModify         = key.get_value_as_string("NoModify") == "1";
                appKey.NoRepair         = key.get_value_as_string("NoRepair") == "1";
                appKey.ReleaseType      = key.get_value_as_string("ReleaseType");
                appKey.ParentKeyName    = key.get_value_as_string("ParentKeyName");
                appKey.DisplayIcon      = key.get_value_as_string("DisplayIcon");
                long size = 0;
                if (long.TryParse(key.get_value_as_string("EstimatedSize"), out size))
                {
                    appKey.EstimatedSize = size;
                }

                if (appKey.WindowsInstaller || appKey.UninstallString.to_string().to_lower().Contains("msiexec"))
                {
                    appKey.InstallerType = InstallerType.Msi;
                }

                if (key.Name.EndsWith("_is1") || !string.IsNullOrWhiteSpace(key.get_value_as_string("Inno Setup: Setup Version")))
                {
                    appKey.InstallerType = InstallerType.InnoSetup;
                }

                if (!string.IsNullOrWhiteSpace(key.get_value_as_string("dwVersionMajor")))
                {
                    appKey.InstallerType   = InstallerType.Nsis;
                    appKey.VersionMajor    = key.get_value_as_string("dwVersionMajor");
                    appKey.VersionMinor    = key.get_value_as_string("dwVersionMinor");
                    appKey.VersionRevision = key.get_value_as_string("dwVersionRev");
                    appKey.VersionBuild    = key.get_value_as_string("dwVersionBuild");
                }
                if (appKey.ReleaseType.is_equal_to("Hotfix") || appKey.ReleaseType.is_equal_to("Update Rollup") || appKey.ReleaseType.is_equal_to("Security Update") || appKey.DefaultValue.to_string().StartsWith("KB", ignoreCase: true, culture: CultureInfo.InvariantCulture))
                {
                    appKey.InstallerType = InstallerType.HotfixOrSecurityUpdate;
                }
                if (appKey.ReleaseType.is_equal_to("ServicePack"))
                {
                    appKey.InstallerType = InstallerType.ServicePack;
                }

                // assume NSIS if we still don't know and we find uninst.exe
                if (appKey.InstallerType == InstallerType.Unknown && appKey.UninstallString.to_string().to_lower().Contains("uninst.exe"))
                {
                    appKey.InstallerType = InstallerType.Nsis;
                }

                if (appKey.InstallerType == InstallerType.Unknown && appKey.HasQuietUninstall)
                {
                    appKey.InstallerType = InstallerType.Custom;
                }

                if (appKey.InstallerType == InstallerType.Msi)
                {
                    get_msi_information(appKey, key);
                }

                if (_logOutput)
                {
                    //if (appKey.is_in_programs_and_features() && appKey.InstallerType == InstallerType.Unknown)
                    //{
                    foreach (var name in key.GetValueNames())
                    {
                        //var kind = key.GetValueKind(name);
                        var value = key.get_value_as_string(name);
                        if (name.is_equal_to("QuietUninstallString") || name.is_equal_to("UninstallString"))
                        {
                            Console.WriteLine("key - {0}|{1}={2}|Type detected={3}|install location={4}".format_with(key.Name, name, value.to_string(), appKey.InstallerType.to_string(), appKey.InstallLocation.to_string()));
                        }

                        //Console.WriteLine("key - {0}, name - {1}, kind - {2}, value - {3}".format_with(key.Name, name, kind, value.to_string()));
                    }
                    //}
                }

                snapshot.RegistryKeys.Add(appKey);
            }

            key.Close();
            key.Dispose();
        }
Exemple #15
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));
            }
        }
        /// <summary>
        ///   Evaluates registry keys and updates the snapshop with items
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="snapshot">The snapshot.</param>
        public void evaluate_keys(RegistryKey key, Registry snapshot)
        {
            foreach (var subKeyName in key.GetSubKeyNames())
            {
                evaluate_keys(key.OpenSubKey(subKeyName), snapshot);
            }

            var appKey = new RegistryApplicationKey
                {
                    KeyPath = key.Name,
                    RegistryView = key.View,
                    DefaultValue = key.GetValue("").to_string(),
                    DisplayName = key.GetValue("DisplayName").to_string()
                };

            if (string.IsNullOrWhiteSpace(appKey.DisplayName))
            {
                appKey.DisplayName = appKey.DefaultValue;
            }

            if (!string.IsNullOrWhiteSpace(appKey.DisplayName))
            {
                appKey.InstallLocation = key.GetValue("InstallLocation").to_string();
                appKey.UninstallString = key.GetValue("UninstallString").to_string();
                if (key.GetValue("QuietUninstallString") != null)
                {
                    appKey.UninstallString = key.GetValue("QuietUninstallString").to_string();
                    appKey.HasQuietUninstall = true;
                }

                // informational
                appKey.Publisher = key.GetValue("Publisher").to_string();
                appKey.InstallDate = key.GetValue("InstallDate").to_string();
                appKey.InstallSource = key.GetValue("InstallSource").to_string();
                appKey.Language = key.GetValue("Language").to_string();

                // Version
                appKey.DisplayVersion = key.GetValue("DisplayVersion").to_string();
                appKey.Version = key.GetValue("Version").to_string();
                appKey.VersionMajor = key.GetValue("VersionMajor").to_string();
                appKey.VersionMinor = key.GetValue("VersionMinor").to_string();

                // installinformation
                appKey.SystemComponent = key.GetValue("SystemComponent").to_string() == "1";
                appKey.WindowsInstaller = key.GetValue("WindowsInstaller").to_string() == "1";
                appKey.NoRemove = key.GetValue("NoRemove").to_string() == "1";
                appKey.NoModify = key.GetValue("NoModify").to_string() == "1";
                appKey.NoRepair = key.GetValue("NoRepair").to_string() == "1";
                appKey.ReleaseType = key.GetValue("ReleaseType").to_string();
                appKey.ParentKeyName = key.GetValue("ParentKeyName").to_string();

                if (appKey.WindowsInstaller || appKey.UninstallString.to_lower().Contains("msiexec"))
                {
                    appKey.InstallerType = InstallerType.Msi;
                }

                if (key.Name.EndsWith("_is1") || !string.IsNullOrWhiteSpace(key.GetValue("Inno Setup: Setup Version").to_string()))
                {
                    appKey.InstallerType = InstallerType.InnoSetup;
                }

                if (key.GetValue("dwVersionMajor") != null)
                {
                    appKey.InstallerType = InstallerType.Nsis;
                    appKey.VersionMajor = key.GetValue("dwVersionMajor").to_string();
                    appKey.VersionMinor = key.GetValue("dwVersionMinor").to_string();
                    appKey.VersionRevision = key.GetValue("dwVersionRev").to_string();
                    appKey.VersionBuild = key.GetValue("dwVersionBuild").to_string();
                }
                if (appKey.ReleaseType.is_equal_to("Hotfix") || appKey.ReleaseType.is_equal_to("Update Rollup") || appKey.ReleaseType.is_equal_to("Security Update") || appKey.DefaultValue.to_string().StartsWith("KB", ignoreCase: true, culture: CultureInfo.InvariantCulture))
                {
                    appKey.InstallerType = InstallerType.HotfixOrSecurityUpdate;
                }
                if (appKey.ReleaseType.is_equal_to("ServicePack"))
                {
                    appKey.InstallerType = InstallerType.ServicePack;
                }

                if (appKey.InstallerType == InstallerType.Unknown && appKey.HasQuietUninstall)
                {
                    appKey.InstallerType = InstallerType.Custom;
                }

                if (_logOutput)
                {
                    if (appKey.is_in_programs_and_features() && appKey.InstallerType == InstallerType.Unknown)
                    {
                        foreach (var name in key.GetValueNames())
                        {
                            //var kind = key.GetValueKind(name);
                            var value = key.GetValue(name);
                            if (name.is_equal_to("QuietUninstallString") || name.is_equal_to("UninstallString"))
                            {
                                Console.WriteLine("key - {0}|{1}={2}|Type detected={3}".format_with(key.Name, name, value.to_string(), appKey.InstallerType.to_string()));
                            }

                            //Console.WriteLine("key - {0}, name - {1}, kind - {2}, value - {3}".format_with(key.Name, name, kind, value.to_string()));
                        }
                    }
                }

                snapshot.RegistryKeys.Add(appKey);
            }

            key.Close();
            key.Dispose();
        }