Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何获取已安装软件产品的列表?_C#_Windows - Fatal编程技术网

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

C# 如何获取已安装软件产品的列表?,c#,windows,C#,Windows,如何获取系统上安装的软件产品列表。我的目标是迭代这些,并获得其中一些的安装路径 伪代码(组合多种语言:)) 如果您需要的所有程序都将其安装路径存储在注册表中,您可以使用以下方法: (我知道这是VB,但原理相同) 我确信,如果有些人没有存储安装路径(或不清楚地存储),可能有办法通过.NET获取程序列表,但我不知道。您可以询问WMI:该类表示Windows Installer安装的所有产品。例如,以下PS脚本将检索Windows Installer安装的本地计算机上安装的所有prodcuts: Ge

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

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


如果您需要的所有程序都将其安装路径存储在注册表中,您可以使用以下方法: (我知道这是VB,但原理相同)

我确信,如果有些人没有存储安装路径(或不清楚地存储),可能有办法通过.NET获取程序列表,但我不知道。

您可以询问WMI:该类表示Windows Installer安装的所有产品。例如,以下PS脚本将检索Windows Installer安装的本地计算机上安装的所有prodcuts:

Get-WmiObject -Class Win32_Product -ComputerName .

看。将PS查询移植到等效的C#使用WMI API(换句话说)留给读者作为练习。

您可以使用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);
            }
        }
    }
}

最简单的方法是通过注册表

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


    }
}

我严重怀疑你能在Windows系统上做到这一点。大多数程序都提供自己的安装程序,对于如何检测是否安装了软件没有留下任何标准。@mathepic:实际上,绝大多数程序提供的安装程序都是一个shell或另一个shell,而不是一个.msi安装程序(又称.Windows installer)。非常棒的Powershell命令!我很高兴编写了一个脚本,可以比较a和B计算机上安装的东西,而不是C和D计算机上安装的东西(在第一组上工作,但在第二组上不工作:)。注意使用Win32_产品,因为这里记录了一些令人讨厌的副作用,如w/WiX,这似乎并没有列举所有产品。这有什么原因吗
MsiEnumProducts
doc似乎没有提到这方面的任何内容。因此,我最终坚持使用注册表方式(迭代
Microsoft\Windows\CurrentVersion\Uninstall
键)。
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();
        }


    }
}