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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3526449/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 15:04:17  来源:igfitidea点击:

How to get a list of installed software products?

c#windows

提问by esac

How do I get a list of software products which are installed on the system. My goal is to iterate through these, and get the installation path of a few of them.

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

PSEUDOCODE ( combining multiple languages :) )

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

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

回答by Dirk Vollmar

You can use MSI api functions to enumerate all installed products. Below you will find sample code which does that.

您可以使用 MSI api 函数来枚举所有已安装的产品。您将在下面找到执行此操作的示例代码。

In my code I first enumerate all products, get the product name and if it contains the string "Visual Studio" I check for the InstallLocationproperty. However, this property is not always set. I don't know for certain whether this is not the right property to check for or whether there is another property that always contains the target directory. Maybe the information retrieved from the InstallLocationproperty is sufficient for you?

在我的代码中,我首先枚举所有产品,获取产品名称,如果它包含字符串“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);
            }
        }
    }
}

回答by Remus Rusanu

You can ask the WMI Installed applications classes: the Win32_Productsclass represents all products installed by Windows Installer. For instance the following PS script will retrieve all prodcuts installed on local computer that were installed by Windows Installer:

您可以询问 WMI安装的应用程序类Win32_Products该类代表 Windows Installer 安装的所有产品。例如,以下 PS 脚本将检索本地计算机上安装的由 Windows Installer 安装的所有产品:

Get-WmiObject -Class Win32_Product -ComputerName .

See Working with Software Installations. POrting the PS query to the equivalent C# use of WMI API (in other words Using WMI with the .NET Framework) is left as an exercise to the reader.

请参阅使用软件安装。将 PS 查询移植到等效的 C# 使用 WMI API(换句话说,将 WMI 与 .NET Framework 一起使用)作为练习留给读者。

回答by Blam

Well if all the programs you need store their install paths on the registry you can use something like: http://visualbasic.about.com/od/quicktips/qt/regprogpath.htm(I know it's VB but same principle).

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

I'm sure there probably is a way to get the Program list via .NET if some don't store their install paths (or do it obscurely), but I don't know it.

我敢肯定,如果有些人不存储他们的安装路径(或隐蔽地这样做),可能有一种方法可以通过 .NET 获取程序列表,但我不知道。

回答by Domenico Zinzi

The simplest methods via registry

通过注册表最简单的方法

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


    }
}