WMI – Auswahl aus Win32_Product dauert sehr lange

Ich liste installierte Anwendungen mit WMI auf, und dieser Block dauert relativ lange, unabhängig von seiner Struktur. Es dauert jedes Mal 13 Sekunden in meiner Umgebung. Gibt es einen besseren (schnelleren) Weg, um zu überprüfen, ob ein Programm installiert ist? (Ich verwende iTunes als Beispielprogramm, um nachzusehen)

private static string Timestamp { get { return DateTime.Now.ToString("HH:mm:ss.ffff"); } } private static void LoadInstalledPrograms() { List installedPrograms = new List(); Console.WriteLine("0 - {0}", Timestamp); ManagementObjectSearcher mos = new ManagementObjectSearcher("SELECT * FROM Win32_Product"); Console.WriteLine("1 - {0}", Timestamp); ManagementObjectCollection managementObjectCollection = mos.Get(); Console.WriteLine("2 - {0}", Timestamp); foreach (ManagementObject mo in managementObjectCollection) { installedPrograms.Add(mo["Name"].ToString()); } Console.WriteLine("3 - {0}", Timestamp); Console.WriteLine("Length - {0}", installedPrograms.Count); } 

SELECT * FROM Win32_Product

 0 - 08:08:51.3762 1 - 08:08:51.3942 2 - 08:08:51.4012 3 - 08:09:04.8326 Length - 300 

SELECT * FROM Win32_Product WHERE name = “iTunes”

 0 - 08:14:17.6529 1 - 08:14:17.6709 2 - 08:14:17.6779 3 - 08:14:31.0332 Length - 1 

SELECT * FROM Win32_Product WO Name wie “iTunes”

 0 - 08:16:38.2719 1 - 08:16:38.2899 2 - 08:16:38.2999 3 - 08:16:51.5113 Length - 1 

SELECT name FROM Win32_Product, wo Name wie “iTunes” ist

 0 - 08:19:53.9144 1 - 08:19:53.9324 2 - 08:19:53.9394 3 - 08:20:07.2794 Length - 1 

    WMI braucht Zeit, wie Sie es bereits bemerkt haben. Iterieren durch die Registry könnte für Sie den Trick tun.

    Sie können sich bei stackoverflow unter Installierte Anwendungen in einem System herunterladen, wo beide Methoden erwähnt werden.

    Wenn Sie “Win32_product” abfragen, überprüft und validiert das msi-installer jedes Produkt.

    Der KB-Artikel http://support.microsoft.com/kb/974524 zeigt:

    Win32_product-class ist nicht abfrageoptimiert. Bei Abfragen wie “select * from Win32_Product, wobei (Name wie” Sniffer% “)” muss WMI den MSI-Provider verwenden, um alle installierten Produkte aufzulisten und anschließend die vollständige Liste sequenzieren, um die “where” -Klausel zu behandeln. Dieser process leitet auch eine Konsistenzprüfung der installierten Pakete ein, wobei die Installation überprüft und repariert wird. Bei einem Konto mit nur Benutzerrechten kann das Benutzerkonto möglicherweise nicht auf einige Standorte zugreifen. Dies kann zu einer Verzögerung beim Anwendungsstart und zu einem Ereignis 11708 führen, das einen Installationserrors angibt.

    Win32reg_AddRemovePrograms ist eine wesentlich einfachere und effektivere Möglichkeit, dies zu tun, wodurch die Aufrufe zur Durchführung einer Ausfallsicherheit vermieden werden, insbesondere in einer gesperrten Umgebung. Wenn Sie also Win32reg_AddRemovePrograms verwenden, rufen wir msiprov.dll nicht auf und initiieren keine Ausfallsicherheitsprüfung.

    Seien Sie also vorsichtig mit “Win32_product”.

    Update: Schöner Artikel https://sdmsoftware.com/group-policy-blog/wmi/why-win32_product-is-bad-news/

    Sie sollten SELECT Name FROM Win32_Product in WMI Query verwenden, es funktioniert für mich

    SELECT * make Lädt alle Datenmitglieder, sodass die Verwendung viel Zeit in SELECT * nimmt

    Wie Bernhard darauf hinweist, initiiert WMI die Verwendung von Win32_Product eine Integritätsprüfung des Pakets und wird daher nur langsam verwendet. In besonderen Fällen kann dies eine MSI-Selbstreparatur auslösen (auf meinen Maschinen habe ich dies noch nie gesehen). .

    Anstelle von WMI können Sie die MSI-Automatisierungsschnittstelle direkt verwenden, um die über Windows Installer-Pakete (MSI-Dateien) auf dem Computer installierten Anwendungen aufzulisten. Dies ist sehr schnell und berührt WMI überhaupt nicht.

    Sehen Sie sich dieses Beispiel an : So erfahren Sie, welche Produkte installiert sind – neuere Produkte sind bereits mit MSI-Fenstern installiert ( vollständige, aber grundlegende und leicht verständliche VBScript-Beispiele – überprüfen Sie es ). Es gibt viele Eigenschaften, die Sie für jedes Produkt abrufen können . Informationen zur MSI-Automatisierungsschnittstelle finden Sie in der MSDN-Dokumentation . Der verknüpfte VBScript-Beispielcode und die MSDN-Dokumentation zusammen sollten Ihnen helfen, sich schnell zu bewegen, hoffe ich.

    PS: Ich weiß, dass dies eine alte Frage ist, aber dieses Problem wird immer wieder angesprochen (insbesondere die Langsamkeit von WMI) – nur als Referenz für die Zukunft.

    Wie hier erwähnt, ist Registry nicht zuverlässig und WMI ist langsam. Daher war für mich die beste Option die Windows Installer-API. Fügen Sie msi.dll zu Ihren Referenzen hinzu und passen Sie den folgenden Code an Ihre Anforderungen an:

     public static string GetVersionOfInstalledApplication(string queryName) { string name; string version; Type type = Type.GetTypeFromProgID("WindowsInstaller.Installer"); Installer installer = Activator.CreateInstance(type) as Installer; StringList products = installer.Products; foreach (string productGuid in products) { string currName = installer.ProductInfo[productGuid, "ProductName"]; string currVersion = installer.ProductInfo[productGuid, "VersionString"]; if (currName == queryName) { name = currName; version = currVersion; return version; } } return null; }