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

如何枚举/列出Windows XP中安装的所有应用程序?

  •  7
  • sharkin  · 技术社区  · 16 年前

    当我说“已安装的应用程序”时,我基本上是指在[控制面板]->[添加/删除程序]中可见的任何应用程序。

    我更喜欢用Python来做,但是C或C++也很好。

    7 回复  |  直到 7 年前
        1
  •  11
  •   Aziz    16 年前

    如果您是指“控制面板”中“添加/删除程序”中显示的已安装应用程序列表,则可以在注册表项中找到该列表:

    HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall
    

    more info about how the registry tree is structured can be found here .

    你需要使用 winreg API 在python中从注册表中读取值。

        2
  •  10
  •   Tamas Czinege    16 年前

    退房 Win32_Product WMI(Windows Management Instrumentation)类。 Here's a tutorial 在python中使用wmi。

        3
  •  8
  •   malik    16 年前

    控制面板使用win32 com api,这是正式的方法(请参阅google groups,win32)
    永远不要依赖注册表。

        4
  •  6
  •   Yvette    7 年前

    Microsoft脚本存储库有一个用于列出所有已安装软件的脚本。

    import win32com.client
    strComputer = "."
    objWMIService = win32com.client.Dispatch("WbemScripting.SWbemLocator")
    objSWbemServices = objWMIService.ConnectServer(strComputer,"root\cimv2")
    colItems = objSWbemServices.ExecQuery("Select * from Win32_Product")
    for objItem in colItems:
        print "Caption: ", objItem.Caption
        print "Description: ", objItem.Description
        print "Identifying Number: ", objItem.IdentifyingNumber
        print "Install Date: ", objItem.InstallDate
        print "Install Date 2: ", objItem.InstallDate2
        print "Install Location: ", objItem.InstallLocation
        print "Install State: ", objItem.InstallState
        print "Name: ", objItem.Name
        print "Package Cache: ", objItem.PackageCache
        print "SKU Number: ", objItem.SKUNumber
        print "Vendor: ", objItem.Vendor
        print "Version: ", objItem.Version
    
        5
  •  4
  •   PolyTekPatrick Leandro Conca    13 年前

    我见过的最好的基于注册表的实现是ChrisWright(Chris128)在 http://www.vbforums.com/showthread.php?t=598355 . 它使用多个注册表项,比当前发布的任何答案都要复杂得多。它似乎产生了与添加/删除程序应用程序相同的结果,并且像ARP应用程序一样,它也提供了包含更新的选项。

    尽管它是在vb.net中实现的,但它应该很容易转换为其他.NET语言,如C或Ironpython。我认为,如果您愿意的话,首先转换为Ironpython可以使移植到常规的python变得相当容易,但是我只是自己将其转换为c,然后稍微清理一下代码。

    只有一个小错误需要指出:getUserInstallerKeyPrograms()不会将用户程序的版本添加到列表中,即使它会将其提取出来。不过,这很容易解决。

        6
  •  3
  •   mujjiga    15 年前

    C.NET代码,用于获取在xp和win7中使用wmi的已安装软件列表(wmi是win7中的唯一方法)

        WqlObjectQuery wqlQuery =
          new WqlObjectQuery("SELECT * FROM Win32_Product");
            ManagementObjectSearcher searcher =
                new ManagementObjectSearcher(wqlQuery);
    
            foreach (ManagementObject software in searcher.Get()) {
                Console.WriteLine(software["Caption"]);
            }
    
        7
  •  0
  •   Craig    7 年前

    我知道这个问题是旧的,OP提到XP,也提到了Python,C或C++,但是我发现网上关于这个主题的很多信息是不完整的或不正确的。后者的一个例子是建议使用wmi——特别是 Win32_Product 类;但是,正如其他地方指出的,该方法是 缓慢的 一部分是因为,不管你信不信由你,每个MSI都会运行它的修复程序。我认为这个解决方案是错误的,因为它的速度太慢,而且它的副作用很严重。例如,您已经选择禁用程序的Windows服务,但是调用 select * from Win32_Product 作为确保MSI修复运行的一部分,显然将重新启用该服务。

    值得一提的是,下面是我认为是迄今为止最完整的示例,尽管在C语言中(我是根据框架4.6.1编译的,但较低版本也可以工作。)它列出了32位和64位安装的程序;它处理了它使用的注册表项,并在一秒钟内运行,至少在缓存启动之后。如果您可以提供改进,请建议他们而不是直接投反对票,我将更新代码。

    一件事 仍然缺少一些更新。例如,当我在我的Windows10系统上运行它并将它与控制面板程序和功能安装的更新进行比较时,我注意到它没有显示 Security Update for Adobe Flash Player 出于某种原因。

    对于匿名方法,我没有任何好的理由,这只是我当时的想法——一种方法内方法的解决方案。

    using System;
    using System.Collections.Generic;
    using System.Runtime.InteropServices;
    using System.Text;
    using System.Text.RegularExpressions;
    using Microsoft.Win32;
    
    class Program
    {
        static void Main(string[] args)
        {
            var result = InstalledProgram.GetAllInstalledPrograms();
    
            result.Sort((a, b) => a.DisplayName.CompareTo(b.DisplayName));
    
            foreach(var program in result)
            {
                if(!program.IsSystemComponent && !program.IsKB) Console.WriteLine(program.Dump());
            }
        }
    }
    
    public enum PlatformTypes
    {
        x86,
        amd64
    }
    
    public class InstalledProgram
    {
        [DllImport("advapi32.dll")]
        extern public static int RegQueryInfoKey(
            Microsoft.Win32.SafeHandles.SafeRegistryHandle hkey,
            StringBuilder lpClass,
            ref uint lpcbClass,
            IntPtr lpReserved,
            IntPtr lpcSubKeys,
            IntPtr lpcbMaxSubKeyLen,
            IntPtr lpcbMaxClassLen,
            IntPtr lpcValues,
            IntPtr lpcbMaxValueNameLen,
            IntPtr lpcbMaxValueLen,
            IntPtr lpcbSecurityDescriptor,
            out long lpftLastWriteTime
        );
    
        public string DisplayName { get; private set; }
        public string UninstallString { get; private set; }
        public string KBNumber { get; private set; }
        public string DisplayIcon { get; private set; }
        public string Version { get; private set; }
        public DateTime InstallDate { get; private set; }
        public PlatformTypes Platform { get; private set; }
        public bool IsSystemComponent { get; private set; }
        public bool IsKB { get { return !string.IsNullOrWhiteSpace(KBNumber); } }
    
        public static List<InstalledProgram> GetAllInstalledPrograms()
        {
            var result = new List<InstalledProgram>();
    
            Action<PlatformTypes, RegistryKey, string> getRegKeysForRegPath = (platform, regBase, path) =>
            {
                using(var baseKey = regBase.OpenSubKey(path))
                {
                    if(baseKey != null)
                    {
                        string[] subKeyNames = baseKey.GetSubKeyNames();
                        foreach(string subkeyName in subKeyNames)
                        {
                            using(var subKey = baseKey.OpenSubKey(subkeyName))
                            {
                                object o;
    
                                o = subKey.GetValue("DisplayName");
                                string displayName = o != null ? o.ToString() : "";
                                o = subKey.GetValue("UninstallString");
                                string uninstallString = o != null ? o.ToString() : "";
                                o = subKey.GetValue("KBNumber");
                                string kbNumber = o != null ? o.ToString() : "";
                                o = subKey.GetValue("DisplayIcon");
                                string displayIcon = o != null ? o.ToString() : "";
                                o = subKey.GetValue("DisplayVersion");
                                string version = o != null ? o.ToString() : "";
                                o = subKey.GetValue("InstallDate");
                                DateTime installDate = o != null ? parseInstallDate(o.ToString()) : default(DateTime);
                                o = subKey.GetValue("SystemComponent");
                                bool isSystemComponent = o != null ? o.ToString() == "1" : false;
    
                                // Sometimes, you need to get the KB number another way.
                                if(kbNumber == "")
                                {
                                    var match = Regex.Match(displayName, @".*?\((KB\d+?)\).*");
                                    if(match.Success) kbNumber = match.Groups[1].ToString();
                                }
    
                                // Sometimes, the only way you can get install date is from the last write
                                // time on the registry key.
                                if(installDate == default(DateTime))
                                {
                                    string keyFull = baseKey + "\\" + subkeyName + "\\DisplayVersion";
                                    var sb = new StringBuilder(64);
                                    uint sbLen = 65;
    
                                    RegQueryInfoKey(
                                            subKey.Handle
                                            , sb
                                            , ref sbLen
                                            , IntPtr.Zero
                                            , IntPtr.Zero
                                            , IntPtr.Zero
                                            , IntPtr.Zero
                                            , IntPtr.Zero
                                            , IntPtr.Zero
                                            , IntPtr.Zero
                                            , IntPtr.Zero
                                            , out long lastWriteTime);
    
                                    installDate = DateTime.FromFileTime(lastWriteTime);
                                }
    
                                if(displayName != "" && uninstallString != "")
                                {
                                    result.Add(new InstalledProgram
                                    {
                                        DisplayName = displayName,
                                        UninstallString = uninstallString,
                                        KBNumber = kbNumber,
                                        DisplayIcon = displayIcon,
                                        Version = version,
                                        InstallDate = installDate,
                                        Platform = platform,
                                        IsSystemComponent = isSystemComponent
                                    });
                                }
                            }
                        }
                    }
                }
            };
    
            getRegKeysForRegPath(PlatformTypes.amd64, Registry.LocalMachine, @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall");
            getRegKeysForRegPath(PlatformTypes.amd64, Registry.CurrentUser, @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall");
            if(Environment.Is64BitOperatingSystem)
            {
                getRegKeysForRegPath(PlatformTypes.x86, Registry.LocalMachine, @"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall");
                getRegKeysForRegPath(PlatformTypes.x86, Registry.CurrentUser, @"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall");
            }
    
            return result;
        }
    
        public string Dump()
        {
            return Platform + "\t" + DisplayName + "\t" + InstallDate + "\t" + DisplayIcon + "\t" + Version + "\t" + KBNumber + "\t" + UninstallString;
        }
    
        private static DateTime parseInstallDate(string installDateStr)
        {
            DateTime.TryParseExact(
                    installDateStr
                    , format: "yyyyMMdd"
                    , provider: new System.Globalization.CultureInfo("en-US")
                    , style: System.Globalization.DateTimeStyles.None
                    , result: out DateTime result);
    
            return result;
        }
    
        public override string ToString()
        {
            return DisplayName;
        }
    }
    

    [叹息]然后我看到了@polytekpatrick的答案。我是怎么错过的?英雄联盟