Как я могу перечислить / перечислить все установленные приложения в Windows XP? - PullRequest
7 голосов
/ 29 апреля 2009

Когда я говорю «установленное приложение», я имею в виду любое приложение, видимое в [Панель управления] -> [Установка и удаление программ].

Я бы предпочел сделать это на Python, но C или C ++ тоже подойдут.

Ответы [ 7 ]

11 голосов
/ 29 апреля 2009

Если вы имеете в виду список установленных приложений, который отображается в разделе «Установка и удаление программ» на панели управления, вы можете найти его в разделе реестра:

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall

больше информации о том, как структурировано дерево реестра, можно найти здесь .

Вам нужно использовать winreg API в python для чтения значений из реестра.

10 голосов
/ 29 апреля 2009

Ознакомьтесь с классом Win32_Product WMI (инструментарий управления Windows). Вот учебник по использованию WMI в Python.

8 голосов
/ 29 апреля 2009

Панель управления использует Win32 COM API, который является официальным методом (см. Google Groups, Win32)
Никогда не полагайтесь на реестр.

6 голосов
/ 30 апреля 2009

В хранилище скриптов 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
4 голосов
/ 18 марта 2012

Лучшая из основанных на реестре реализаций, которую я видел, написана Крисом Райтом (chris128) и размещена по адресу http://www.vbforums.com/showthread.php?t=598355.. Она использует несколько разделов реестра и намного сложнее, чем любой из ответов, размещенных здесь в данный момент , Похоже, что он дает идентичные результаты для приложения «Установка и удаление программ», и, как и приложение ARP, он также предоставляет возможность включать обновления.

Хотя это реализовано в VB.NET, его должно быть легко преобразовать в другие языки .NET, такие как C # или IronPython. Я полагаю, что сначала преобразование в IronPython должно облегчить перенос на обычный Python, если вы этого хотите, но я только преобразовал его в C #, а затем немного очистил код.

Только одна небольшая ошибка, на которую следует указать: GetUserInstallerKeyPrograms () не добавляет версию для пользовательских программ в список, даже если она извлекает ее. Это легко исправить, хотя.

3 голосов
/ 18 августа 2010

C # .net код для получения списка установленных программ с использованием WMI в xp и win7 (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"]);
        }
0 голосов
/ 15 мая 2018

Я знаю, что этот вопрос старый, ОП упоминал XP, а также упоминал Python, C или C ++, но я обнаружил, что много информации в сети по этой теме либо неполно, либо неверно. Примером последнего является предложение использовать WMI, в частности, класс Win32_Product; однако, как отмечалось в другом месте, этот метод является медленным , отчасти потому, что, хотите верьте, хотите нет, каждый найденный MSI фактически выполняет свое восстановление. Я называю это решение неправильным из-за того, насколько оно мучительно медленно и из-за его неприятного побочного эффекта. Например, вы уже решили отключить службу Windows программы, но вызов select * from Win32_Product, как часть гарантии того, что восстановление MSI выполняется, по-видимому, снова включит службу.

Ниже приведен пример, который я бы назвал наиболее полным на сегодняшний день, хотя и в C # (я скомпилировал его для Framework 4.6.1, но могут работать и более низкие версии.) В нем перечислены 32-битные и 64-битные версии. -бит установленных программ; он располагает ключами реестра, которые он использует, и запускается менее чем за секунду, по крайней мере, после того, как кешируется. Если вы можете предложить улучшения, предложите их вместо простого понижения голосов, и я обновлю код.

Одна вещь, которую по-прежнему отсутствует, это некоторые обновления. Например, когда я запускаю его в своей системе Windows 10 и сравниваю его с Панелью управления | Программы и возможности | Установленные обновления, замечаю, что по какой-то причине не отображается 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. Как я это пропустил? LOL

...