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

StackOverflow https://stackoverflow.com/questions/802499

Вопрос

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

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

Это было полезно?

Решение

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

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall

Дополнительную информацию о структуре дерева реестра можно найти здесь..

Вам необходимо использовать Winreg API в Python для чтения значений из реестра.

Другие советы

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

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

В репозитории сценариев 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

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

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

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

Код 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"]);
        }

Я знаю, что этот вопрос старый, в ОП упоминается 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.Как я это пропустил?РЖУ НЕ МОГУ

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top