代码之家  ›  专栏  ›  技术社区  ›  esac

如何获取已安装软件产品的列表?

  •  4
  • esac  · 技术社区  · 14 年前

    如何获取安装在系统上的软件产品列表。我的目标是遍历这些,并获得其中一些的安装路径。

    伪代码(组合多种语言:)

    foreach InstalledSoftwareProduct
        if InstalledSoftwareProduct.DisplayName LIKE *Visual Studio*
            print InstalledSoftwareProduct.Path
    
    4 回复  |  直到 10 年前
        1
  •  14
  •   Dirk Vollmar    14 年前

    可以使用MSIAPI函数枚举所有已安装的产品。下面您将找到这样做的示例代码。

    在我的代码中,我首先枚举所有产品,获取产品名称,如果它包含字符串“visualstudio”,我将检查 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);
                }
            }
        }
    }
    
        2
  •  8
  •   Remus Rusanu    14 年前

    你可以问警察 Installed applications classes Win32_Products 类表示Windows Installer安装的所有产品。例如,以下PS脚本将检索Windows Installer安装的本地计算机上安装的所有prodcuts:

    Get-WmiObject -Class Win32_Product -ComputerName .
    

    看到了吗 Working with Software Installations . 将PS查询移植到等效的WMI API(换句话说 Using WMI with the .NET Framework

        3
  •  0
  •   Blam    14 年前

    如果您需要的所有程序都将其安装路径存储在注册表中,您可以使用以下方法: http://visualbasic.about.com/od/quicktips/qt/regprogpath.htm (我知道这是VB,但原理是一样的)。

    我肯定有一种方法可以通过.NET获取程序列表,如果有些人不存储他们的安装路径(或者不清楚地进行安装),但我不知道。

        4
  •  -1
  •   Domenico Zinzi    7 年前

    通过注册表的最简单方法

    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();
            }
    
    
        }
    }