How can I find the upgrade code for an installed application in C#?

前端 未结 5 1144
时光说笑
时光说笑 2020-12-03 11:12

I am using the C# wrapper for the Windows Installer API from the WIX Toolset. I use the ProductInstallation class to get information about the installed produc

5条回答
  •  攒了一身酷
    2020-12-03 12:09

    And here is your helper modified in such a way that it also works in .Net3.5 32 bit applications. They need special treatement because .net 3.5 has no awareness about registry being splitted between 32 and 64 bit entries. My solution is only using To64BitPath to browse 64 bit part of it. There is also a great tutorial that uses DllImports for that: https://www.rhyous.com/2011/01/24/how-read-the-64-bit-registry-from-a-32-bit-application-or-vice-versa/

    class RegistryHelper
    {
        private const string UpgradeCodeRegistryKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UpgradeCodes";
        private const string UninstallRegistryKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
    
        private static readonly int[] GuidRegistryFormatPattern = new[] { 8, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2 };
    
    
    
        public static string To64BitPath(string path)
        { 
            return path.Replace("SOFTWARE\\Microsoft", "SOFTWARE\\WOW6432Node\\Microsoft");
        }
    
        private static RegistryKey GetLocalMachineRegistryKey(string path)
        {
            return RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, string.Empty).OpenSubKey(path);
        }
    
        public static IEnumerable GetUpgradeCodes()
        {
            var list = new List();
    
            var key = GetRegistryKey(UpgradeCodeRegistryKey);
            if (key != null)
            {
                list.AddRange(key.GetSubKeyNames().Select(ConvertFromRegistryFormat));
            }
    
            return list;
        }
    
        public static Guid? GetProductCode(Guid upgradeCode)
        {
            // Convert the product upgradeCode to the format found in the registry
            var productCodeSearchString = ConvertToRegistryFormat(upgradeCode);
    
            // Open the upgradeCode upgradeCode registry key
            var upgradeCodeRegistryRoot = GetRegistryKey(Path.Combine(UpgradeCodeRegistryKey, productCodeSearchString));
    
            if (upgradeCodeRegistryRoot == null)
                return null;
    
            var uninstallCode = upgradeCodeRegistryRoot.GetValueNames().FirstOrDefault();
            if (string.IsNullOrEmpty(uninstallCode))
            {
                return null;
            }
    
            // Convert it back to a Guid
            return ConvertFromRegistryFormat(uninstallCode);
        }
    
        public static string ConvertToRegistryFormat(Guid code)
        {
            return Reverse(code, GuidRegistryFormatPattern);
        }
    
        private static Guid ConvertFromRegistryFormat(string code)
        {
            if (code == null || code.Length != 32)
                throw new FormatException("Product upgradeCode was in an invalid format");
    
            code = Reverse(code, GuidRegistryFormatPattern);
    
            return new Guid(code);
        }
    
        private static string Reverse(object value, params int[] pattern)
        {
            // Strip the hyphens
            var inputString = value.ToString().Replace("-", "");
    
            var returnString = new StringBuilder();
    
            var index = 0;
    
            // Iterate over the reversal pattern
            foreach (var length in pattern)
            {
                // Reverse the sub-string and append it
                returnString.Append(inputString.Substring(index, length).Reverse().ToArray());
    
                // Increment our posistion in the string
                index += length;
            }
    
            return returnString.ToString();
        }
    
        static RegistryKey GetRegistryKey(string registryPath)
        {
            var registryKey64 = GetLocalMachineRegistryKey(To64BitPath(registryPath));
            if (((bool?)registryKey64?.GetValueNames()?.Any()).GetValueOrDefault())
            {
                return registryKey64;
            }
    
            return GetLocalMachineRegistryKey(registryPath);
        }
    
    
        public static Guid? GetUpgradeCode(Guid productCode)
        {
            var productCodeSearchString = ConvertToRegistryFormat(productCode);
            var upgradeCodeRegistryRoot = GetRegistryKey(UpgradeCodeRegistryKey);
    
            if (upgradeCodeRegistryRoot == null)
            {
                return null;
            }
    
            // Iterate over each sub-key
            foreach (var subKeyName in upgradeCodeRegistryRoot.GetSubKeyNames())
            {
                var subkey = upgradeCodeRegistryRoot.OpenSubKey(subKeyName);
    
                if (subkey == null)
                    continue;
    
                // Check for a value containing the product upgradeCode
                if (subkey.GetValueNames().Any(s => s.IndexOf(productCodeSearchString, StringComparison.OrdinalIgnoreCase) >= 0))
                {
                    // Extract the name of the subkey from the qualified name
                    var formattedUpgradeCode = subkey.Name.Split('\\').LastOrDefault();
    
                    // Convert it back to a Guid
                    return ConvertFromRegistryFormat(formattedUpgradeCode);
                }
            }
    
            return null;
        }
    }
    

提交回复
热议问题