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

发布于 2024-07-07 05:09:22 字数 835 浏览 5 评论 0原文

这是此问题的后续内容。

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

对此有任何线索吗?

This is a follow up from this question.

I'm using this slightly modified script to enumerate all installed MSI packages:

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

What is surprising however, is its abysmal performance. Enumerating the 34 installed MSI packages on my XP box takes between 3 and 5 minutes !

By comparison, the Linux box that sits besides is taking 7s to enumerate 1400+ RPMs... sigh

Any clues on this ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

作妖 2024-07-14 05:09:22

极其缓慢是枚举 Win32_Products 的一个已知/常见问题。

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

枚举卸载的一些常规参考:

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

Extreme slowness is a known/common problem for enumerating Win32_Products

If you need an alternate solution, consider building your own list of products using the 'Uninstall' registry entries (as suggested in one of the answers to the original question you referred to).

Some general references for enumerating Uninstall:

And to do it remotely, use the WMI registry class, StdRegProv.
TechNet even conveniently provides a simple example of using StdRegProv to do the very thing you want:
How do I list all the installed applications on a given machine

瑾兮 2024-07-14 05:09:22

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

在本页查看问题和 vbscript 代码以使用更好的方法来完成此操作:http://csi-windows.com/toolkit/288-win32product-wmi-class-replacement

Win32_Product WMI class is so slow because it is doing a Consistency Check - processing every package using Msiexec.exe - everytime you use it.

Check out the issues and vbscript code to do it using a better method at this page: http://csi-windows.com/toolkit/288-win32product-wmi-class-replacement

一花一树开 2024-07-14 05:09:22

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

When you are using the api functions which are declared in msi.h you are at light speed.
i'm using the api for my software software-uptodate and enumerating hundreds of packets takes a second at all.

命硬 2024-07-14 05:09:22

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

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

I suspected a network issue and Wireshark proved me right.

It seems that Windows Installer happily attempts to reopen all the original .msi files, including those who lived on network shares.

花落人断肠 2024-07-14 05:09:22

这对我有用,并且避免了 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

This works for me and avoids the slowness of the WMI approach:

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

Find out more about the Installer object from http://msdn.microsoft.com/en-us/library/windows/desktop/aa369432(v=vs.85).aspx

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文