更新:

查找组件的安装位置:有没有办法检测安装位置而不卸载注册表或C:\Windows\Installer?

Implementation :MSI如何存储这些东西是不应该被干预、试图修改或直接用于任何目的的实现细节--这一点非常清楚。您应该阅读MSI ,它是以Win32 functions的形式实现的,具有互补的COM wrappers,以便通过脚本语言进行访问。

MSI数据库主要存储在注册表中,但磁盘上也有组件--例如,%SystemDrive%\Windows\Installer (一个不应该以任何方式修改的超级隐藏文件夹)。MSI数据库存储在整个注册表的多个位置:

HKCR\InstallerHKCU\Software\Microsoft\InstallerHKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\InstallerHKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\UninstallHKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\UninstallHKLM\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\InstallerEtc...有些是真实的,有些是别名,有些是合并。一切都有点模糊。再说一遍:implementation details --这是我们大家都熟知的委婉说法:“现在放弃吧,你?”:-)只需应用MSI获取所需的信息即可。

MSI API:上面要阅读的东西很多,可以通过MSI获取有关目录解析的信息。我们要做的是有点异国情调,我们必须为已安装的产品旋转一个会话对象,并运行两个标准操作(来自微软的内置MSI操作),以便解析所涉MSI (关于“成本”)的目录表和安装目录。以下是一个实际的样本:

请记录在案:

如何找到已安装的MSI安装程序的产品GUID?如何比较两个(或更多) MSI文件的内容? (在Orca和其他免费的MSI工具上)在不使用msiexec的情况下从命令行卸载MSI文件 (卸载MSI软件包的各种方法)代码语言:javascript复制Set installer = CreateObject("WindowsInstaller.Installer")

' Other test product codes: {2F73A7B2-E50E-39A6-9ABC-EF89E4C62E36}

productcode = Trim(InputBox("Please paste or type in the product code you want to look up details for:", _

"Find Product Details (test GUID provided):", "{766AD270-A684-43D6-AF9A-74165C9B5796}"))

If search = vbCancel Or Trim(productcode) = "" Then

WScript.Quit(0)

End If

Set session = installer.OpenProduct(productcode)

' Crucially, resolve the directory table and properties by running "MSI Costing"

session.DoAction("CostInitialize")

session.DoAction("CostFinalize")

' Can be any directory property from the Directory table in the MSI:

MsgBox session.Property("INSTALLFOLDER")

' Open the MSI in Orca to find the directory folder property names在如何列出MSI文件中的表上添加一个指向旧答案的链接。

解决了所有的:有点抓走了,然后再进行一次更新来解析所有已安装的软件包的所有目录。下面是一个脚本(测试不多):

代码语言:javascript复制' https://stackoverflow.com/questions/17543132/how-can-i-resolve-msi-paths-in-vbscript

' On Error resume Next

Set installer = CreateObject("WindowsInstaller.Installer")

' Other test product codes: {2F73A7B2-E50E-39A6-9ABC-EF89E4C62E36}

const READONLY = 0

Dim DirList

productcode = Trim(InputBox("Please paste or type in the product code you want to look up details for:", _

"Find Product Details (test GUID provided):", "{766AD270-A684-43D6-AF9A-74165C9B5796}"))

If search = vbCancel Or Trim(productcode) = "" Then

WScript.Quit(0)

End If

Set session = installer.OpenProduct(productcode)

session.DoAction("CostInitialize")

session.DoAction("CostFinalize")

set view = session.Database.OpenView("SELECT * FROM Directory")

view.Execute

set record = view.Fetch

Do until record is Nothing

ResolvedDir = session.Property(record.StringData(1))

DirList = DirList + record.StringData(1) + " => " + ResolvedDir + vbCrLf

set record = view.Fetch

Loop

' Dismiss dialog with ESC key if it falls off screen

WScript.Echo DirList ' Use WScript.Echo due to MsgBox restrictions (number of characters)链接

如何在VBScript中解析MSI路径?