为什么枚举安装的MSI包这么慢?

时间:2008-10-16 12:31:41

标签: windows-installer wmi

这是question的后续跟进。

我正在使用这个稍微修改过的脚本来枚举所有已安装的MSI包:

strComputer = "."

Set objWMIService = GetObject("winmgmts:" & _
    "{impersonationLevel=impersonate}!\\" & _
    strComputer & _
    "\root\cimv2")

Set colSoftware = objWMIService.ExecQuery _
    ("SELECT * FROM Win32_Product")   

If colSoftware.Count > 0 Then
    For Each objSoftware in colSoftware
        WScript.Echo objSoftware.Caption & vbtab & _
        objSoftware.Version
    Next
Else
    WScript.Echo "Cannot retrieve software from this computer."
End If

然而令人惊讶的是它的糟糕表现。在我的XP盒子上枚举34个已安装的MSI软件包需要3到5分钟!

相比之下,除此之外的Linux盒子需要花费7秒才能枚举1400+ RPM ... 叹息

有关此的任何线索吗?

5 个答案:

答案 0 :(得分:6)

极端缓慢是枚举Win32_Products

的已知/常见问题

如果您需要备用解决方案,请考虑使用“卸载”注册表项构建您自己的产品列表(如您所提到的original question的一个答案中所述)。

枚举Uninstall的一般参考:

要远程执行 ,请使用WMI注册表类StdRegProv。 TechNet甚至可以方便地提供一个使用StdRegProv来完成您想要的事情的简单示例: How do I list all the installed applications on a given machine

答案 1 :(得分:4)

Win32_Product WMI类是如此之慢,因为它正在进行一致性检查 - 每次使用时都使用Msiexec.exe处理每个包。

在此页面上使用更好的方法查看问题和vbscript代码:http://csi-windows.com/toolkit/288-win32product-wmi-class-replacement

答案 2 :(得分:2)

当您使用在msi.h中声明的api函数时,您的速度很快。 我正在使用api作为我的软件software-uptodate,并且枚举数百个数据包需要一秒钟。

答案 3 :(得分:1)

我怀疑网络问题,Wireshark证明我是对的。

Windows Installer似乎很乐意尝试重新打开所有原始.msi文件,包括那些生活在网络共享上的文件。

答案 4 :(得分:1)

这对我有用,并且避免了WMI方法的缓慢:

Dim installer
Set installer = CreateObject("WindowsInstaller.Installer")
Dim productCode, productName
For Each productCode In installer.Products
    productName = installer.ProductInfo(productCode, "ProductName")
    WScript.Echo productCode & " , " & productName
Next

http://msdn.microsoft.com/en-us/library/windows/desktop/aa369432(v=vs.85).aspx

了解有关Installer对象的更多信息