2010-08-19 91 views
4

如何獲取系統上安裝的軟件產品列表。我的目標是遍歷這些,並獲得其中一些的安裝路徑。如何獲取已安裝軟件產品的列表?

僞代碼(結合多國語言:))

foreach InstalledSoftwareProduct 
    if InstalledSoftwareProduct.DisplayName LIKE *Visual Studio* 
     print InstalledSoftwareProduct.Path 
+1

我嚴重懷疑,你可以在Windows系統中最簡單的方法。大多數程序都提供他們自己的安裝程序,而沒有關於如何檢測軟件是否安裝的標準。 – alternative 2010-08-19 21:40:45

+0

@mathepic:實際上絕大多數程序都提供了一個安裝程序,它是通過.msi安裝(又稱Windows安裝程序)安裝的一個或另一個安裝程序。 – 2010-08-19 21:51:08

回答

11

您可以使用MSI API函數來枚舉所有已安裝的產品。下面你會找到這樣的示例代碼。

在我的代碼中,我首先枚舉所有產品,獲取產品名稱,如果它包含字符串「Visual Studio」,則檢查InstallLocation屬性。但是,此屬性並不總是設置。我不確定這是不是要檢查的正確屬性,還是有另一個屬性始終包含目標目錄。也許從InstallLocation屬性中檢索到的信息對您來說已經足夠了?

using System; 
using System.Collections.Generic; 
using System.Runtime.InteropServices; 
using System.Text; 

class Program 
{ 
    [DllImport("msi.dll", CharSet = CharSet.Unicode)] 
    static extern Int32 MsiGetProductInfo(string product, string property, 
     [Out] StringBuilder valueBuf, ref Int32 len); 

    [DllImport("msi.dll", SetLastError = true)] 
    static extern int MsiEnumProducts(int iProductIndex, 
     StringBuilder lpProductBuf); 

    static void Main(string[] args) 
    { 
     StringBuilder sbProductCode = new StringBuilder(39); 
     int iIdx = 0; 
     while (
      0 == MsiEnumProducts(iIdx++, sbProductCode)) 
     { 
      Int32 productNameLen = 512; 
      StringBuilder sbProductName = new StringBuilder(productNameLen); 

      MsiGetProductInfo(sbProductCode.ToString(), 
       "ProductName", sbProductName, ref productNameLen); 

      if (sbProductName.ToString().Contains("Visual Studio")) 
      { 
       Int32 installDirLen = 1024; 
       StringBuilder sbInstallDir = new StringBuilder(installDirLen); 

       MsiGetProductInfo(sbProductCode.ToString(), 
        "InstallLocation", sbInstallDir, ref installDirLen); 

       Console.WriteLine("ProductName {0}: {1}", 
        sbProductName, sbInstallDir); 
      } 
     } 
    } 
} 
0

你需要存儲其上,你可以使用類似註冊表安裝路徑,那麼,如果所有的節目: http://visualbasic.about.com/od/quicktips/qt/regprogpath.htm(我知道這是VB,但同樣的原則) 。

我敢肯定,如果有一些不存儲他們的安裝路徑(或者晦澀地執行),我確定有可能通過.NET獲取程序列表,但我不知道。

8

您可以問WMI Installed applications classesWin32_Products類代表Windows安裝程序安裝的所有產品。例如下面的PS腳本將檢索安裝在本地計算機上的所有農資由Windows安裝程序安裝的:

Get-WmiObject -Class Win32_Product -ComputerName . 

Working with Software Installations。將PS查詢指向等效的C#使用WMI API(換句話說Using WMI with the .NET Framework)作爲練習留給讀者。

+0

Awesome Powershell命令!我很高興編寫了一個腳本,用來比較計算機A和B上安裝的內容,但不是C和D(第一組中的某些內容,但不是第二組內容))。 – 2010-10-19 18:42:22

+1

請注意使用Win32_Product,因爲這裏記錄了一些令人討厭的副作用[link](http://sdmsoftware.com/wmi/why-win32_product-is-bad-news/) – 2013-03-19 17:17:10

+0

@BobM:http://support.microsoft .com/kb/974524的確如此。 – 2013-03-19 21:04:25

0

通過註冊表

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 && subkey.GetValue("DisplayName").ToString().Contains("Visual Studio")) 
          { 
           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(); 
     } 


    } 
} 
相關問題