在Windows安装msi文件后,它将重命名该文件,将其移至C:\ Windows \ Installers并写入有关如何在注册表中找到该文件的信息。
我想查询该密钥的注册表,以获取已安装文件的确切位置。我正在寻找的价值观点可以在:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products\
不幸的是,我不知道已安装文件的确切ID,因此我必须打开此位置列出的所有项目并检查产品名称。
但是,当我尝试以编程方式查询注册表的这一部分时,我无法看到应该在此处列出的任何项目。
这是我现在正在使用的代码(不包括异常处理等):
Registry.LocalMachine.OpenSubKey("SOFTWARE").OpenSubKey("Microsoft").OpenSubKey("Windows").OpenSubKey("CurrentVersion").OpenSubKey("Installer").OpenSubKey("UserData").OpenSubKey("S-1-5-18").OpenSubKey("Products")
如何查询注册表的这一部分?关于如何获取我正在寻找的msi文件的位置(和名称)的任何其他想法?
答案 0 :(得分:1)
了解注册表是不可取的。 Windows Installer提供了一个Win32 API来访问此信息。对于C#/ .NET,有一个非常好的互操作库可以为您封装所有这些。它被称为Microsoft.Deployment.WindowsInstaller,附带Windows Installer XML(WiX),可以在CodePlex上找到。
在这个库中有一个名为ProductInstallation的类,它带有一个名为GetProducts的静态方法,它包装了底层的MsiEnumProducts函数。
public static IEnumerable<ProductInstallation> GetProducts(
string productCode,
string userSid,
UserContexts context
)
productCode(String) 要生成的产品实例的ProductCode(GUID) 列举。仅限上下文范围内的产品实例 将枚举userSid和context参数指定的内容。 此参数可以设置为null以枚举中的所有产品 指定的背景。
userSid(String)指定安全标识符
(SID)限制枚举的上下文。其他SID值 比s-1-1-0被认为是用户SID并将枚举限制为 当前用户或系统中的任何用户。特殊的SID字符串s-1-1-0 (Everyone)指定系统中所有用户的枚举。这个 参数可以设置为null以将枚举范围限制为 当前用户。当context仅设置为机器上下文时,userSid 必须为null。上下文
(UserContexts)
指定用户上下文。
答案 1 :(得分:0)
首先,你可以写:
Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products")
无需单独打开每个密钥。
其次,我相信您的问题可能是您在64位计算机上运行32位程序集中的代码,并且正在尝试访问{{1的64位部分中的数据密钥。相反,您将被重新路由到SOFTWARE
,其中Wow6432Node
内的密钥UserData
不一定存在。
有关如何从32位程序集中的64位部分进行读取,请参阅this answer。