gpt4 book ai didi

c# - 如何在 C# 中找到已安装应用程序的升级代码?

转载 作者:可可西里 更新时间:2023-11-01 08:01:09 28 4
gpt4 key购买 nike

我正在使用来自 WIX Toolset 的 Windows Installer API 的 C# 包装器.我使用 ProductInstallation 类来获取有关已安装产品的信息,例如产品代码和产品名称。

例如

  • 产品名称 - “我的测试应用程序”
  • 产品代码 - {F46BA620-C027-4E68-9069-5D5D4E1FF30A}
  • 产品版本 - 1.4.0

这个包装器在内部使用 MsiGetProductInfo功能。遗憾的是,此函数不会返回产品的升级代码。

如何使用 C# 检索已安装应用程序的升级代码?

最佳答案

我发现升级代码存储在以下注册表位置。

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UpgradeCodes

注册表项名称是升级代码,注册表项值名称是产品代码。我可以轻松提取这些值,但代码以不同的格式存储。红圈为格式化后的升级代码,蓝圈为在regedit.exe查看时格式化后的产品代码。

Red circle is the formatted upgrade code, the blue circle the formatted product code

连字符从 Guid 中剥离,然后完成一系列字符串反转。前 8 个字符被反转,然后是接下来的 4 个,然后是接下来的 4 个,然后字符串的其余部分以 2 个字符为一组反转。通常,在反转字符串时,我们需要注意确保正确处理控制字符和特殊字符 ( see Jon Skeet's aricle here ),但在这种情况下,我们可以确信处理 Guid 字符串字符串将正确反转。

下面是我用来从注册表中提取已知产品代码的升级代码的完整代码。

internal static class RegistryHelper
{
private const string UpgradeCodeRegistryKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UpgradeCodes";

private static readonly int[] GuidRegistryFormatPattern = new[] { 8, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2 };

public static Guid? GetUpgradeCode(Guid productCode)
{
// Convert the product code to the format found in the registry
var productCodeSearchString = ConvertToRegistryFormat(productCode);

// Open the upgrade code registry key
var localMachine = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
var upgradeCodeRegistryRoot = localMachine.OpenSubKey(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 code
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;
}

private static string ConvertToRegistryFormat(Guid productCode)
{
return Reverse(productCode, GuidRegistryFormatPattern);
}

private static Guid ConvertFromRegistryFormat(string upgradeCode)
{
if (upgradeCode == null || upgradeCode.Length != 32)
throw new FormatException("Product code was in an invalid format");

upgradeCode = Reverse(upgradeCode, GuidRegistryFormatPattern);

return Guid.Parse(upgradeCode);
}

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

关于c# - 如何在 C# 中找到已安装应用程序的升级代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17936064/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com