3

这是这个问题的后续。

我正在使用这个稍作修改的脚本来枚举所有已安装的 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...叹息

这有什么线索吗?

4

5 回答 5

6

极慢是枚举 Win32_Products 的已知/常见问题

如果您需要替代解决方案,请考虑使用“卸载”注册表项构建您自己的产品列表(如您提到的原始问题的答案之一中所建议的那样)。

枚举卸载的一些一般参考:

远程执行此操作,请使用 WMI 注册表类StdRegProv。TechNet 甚至方便地提供了一个使用 StdRegProv 做你想做的事情的简单示例: 如何列出给定机器上所有已安装的应用程序

于 2009-12-01T20:02:11.417 回答
4

Win32_Product WMI 类非常慢,因为它正在执行一致性检查 - 每次使用它时都使用 Msiexec.exe 处理每个包。

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

于 2011-04-19T20:02:34.670 回答
2

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

于 2008-12-31T11:41:45.687 回答
1

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

Windows Installer 似乎很高兴地尝试重新打开所有原始 .msi 文件,包括那些存在于网络共享上的文件。

于 2008-10-16T13:04:29.613 回答
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对象的更多信息

于 2013-03-21T03:30:36.890 回答