WMI:获取已安装软件的列表

我需要使用wmi调用来获取远程Windows主机上安装的软件列表。 我曾尝试使用Win32_ProductWin32Reg_AddRemovePrograms类。

使用Win32_Product优点是,它显示所有安装在机器上的软件,但是它非常慢,不能在90%以上的主机上工作(给出错误 – NTSTATUS: NT code 0xc002001b - NT code 0xc002001b )。 另一方面, Win32Reg_AddRemovePrograms更快,并且在大多数主机上运行得非常好,但是却漏掉了大量的软件。

有没有其他的Win32类可以有效地做同样的事情?

Solutions Collecting From Web of "WMI:获取已安装软件的列表"

你可以使用wmic。

例:

 wmic product get name,version /format:csv wmic /node:localhost /output:d:\programlist.htm product get name,version /format:htable.xsl wmic product get name,version wmic softwareelement get name,version wmic softwarefeature get name,version wmic wmic:root\cli>/output:c:\ProgramList.txt product get name,version 

或者,您可以像“添加/删除程序”一样阅读所有卸载注册表项:

 HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall 

在64位Windows上,请记住还要检查:

 HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\ 

要返回计算机上安装的所有软件的列表,无论是否通过Windows安装程序:

 Const HKLM = &H80000002 'HKEY_LOCAL_MACHINE strComputer = "." strKey = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\" strEntry1a = "DisplayName" strEntry1b = "QuietDisplayName" strEntry2 = "InstallDate" strEntry3 = "VersionMajor" strEntry4 = "VersionMinor" strEntry5 = "EstimatedSize" Set objReg = GetObject("winmgmts://" & strComputer & _ "/root/default:StdRegProv") objReg.EnumKey HKLM, strKey, arrSubkeys WScript.Echo "Installed Applications" & VbCrLf For Each strSubkey In arrSubkeys intRet1 = objReg.GetStringValue(HKLM, strKey & strSubkey, _ strEntry1a, strValue1) If intRet1 <> 0 Then objReg.GetStringValue HKLM, strKey & strSubkey, _ strEntry1b, strValue1 End If If strValue1 <> "" Then WScript.Echo VbCrLf & "Display Name: " & strValue1 End If objReg.GetStringValue HKLM, strKey & strSubkey, _ strEntry2, strValue2 If strValue2 <> "" Then WScript.Echo "Install Date: " & strValue2 End If objReg.GetDWORDValue HKLM, strKey & strSubkey, _ strEntry3, intValue3 objReg.GetDWORDValue HKLM, strKey & strSubkey, _ strEntry4, intValue4 If intValue3 <> "" Then WScript.Echo "Version: " & intValue3 & "." & intValue4 End If objReg.GetDWORDValue HKLM, strKey & strSubkey, _ strEntry5, intValue5 If intValue5 <> "" Then WScript.Echo "Estimated Size: " & Round(intValue5/1024, 3) & " megabytes" End If Next 

在C#中的编码版本是基于系统注册表窗口中的读数。

 using Microsoft.Win32; using System; using System.Collections.Generic; using System.Text; using System.IO; namespace SoftwareInventory { class Program { static void Main(string[] args) { //!!!!! Must be launched with a domain administrator user!!!!! Console.ForegroundColor = ConsoleColor.Green; StringBuilder sbOutFile = new StringBuilder(); Console.WriteLine("DisplayName;IdentifyingNumber"); sbOutFile.AppendLine("Machine;DisplayName;Version"); //Retrieve machine name from the file :File_In/collectionMachines.txt //string[] lines = new string[] { "NameMachine" }; string[] lines = File.ReadAllLines(@"File_In/collectionMachines.txt"); foreach (var machine in lines) { //Retrieve the list of installed programs for each extrapolated machine name var registry_key = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"; using (Microsoft.Win32.RegistryKey key = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, machine).OpenSubKey(registry_key)) { foreach (string subkey_name in key.GetSubKeyNames()) { using (RegistryKey subkey = key.OpenSubKey(subkey_name)) { //Console.WriteLine(subkey.GetValue("DisplayName")); //Console.WriteLine(subkey.GetValue("IdentifyingNumber")); if (subkey.GetValue("DisplayName") != null) { Console.WriteLine(string.Format("{0};{1};{2}", machine, subkey.GetValue("DisplayName"), subkey.GetValue("Version"))); sbOutFile.AppendLine(string.Format("{0};{1};{2}", machine, subkey.GetValue("DisplayName"), subkey.GetValue("Version"))); } } } } } //CSV file creation var fileOutName = string.Format(@"File_Out\{0}_{1}.csv", "Software_Inventory", DateTime.Now.ToString("yyyy_MM_dd_HH_mmssfff")); using (var file = new System.IO.StreamWriter(fileOutName)) { file.WriteLine(sbOutFile.ToString()); } //Press enter to continue Console.WriteLine("Press enter to continue !"); Console.ReadLine(); } } }