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

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

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


person sharkin    schedule 29.04.2009    source источник
comment
Как вы определяете установленное приложение?   -  person    schedule 29.04.2009


Ответы (7)


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

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall

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

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

person Aziz    schedule 29.04.2009
comment
Этот ключ пуст в моей системе. Проверьте расположение ОС внизу вашей ссылки, и вы увидите, что это не для WinXP. - person sharkin; 29.04.2009
comment
@ R.A, этот раздел реестра содержит множество подразделов (вложенных папок). Каждый представляет собой программу в списке удаления. Пожалуйста, прочтите о структуре этого ключа по указанной ссылке. - person Aziz; 29.04.2009
comment
Да, извините, я на самом деле нахожу их в этом регкейке, моя система на время зависла, и я быстро вынес решение, так как ссылка, которую вы дали, не упоминала XP. Думаю, статья просто старая. - person sharkin; 29.04.2009
comment
Он используется как в XP, так и в Vista: vistax64.com/attachments/tutorials/ - person Aziz; 29.04.2009
comment
В этой статье базы знаний перечислены более старые версии ОС. Это может работать или не работать в более новых версиях. Если вы не найдете его задокументированным в библиотеке MSDN, вам, вероятно, не стоит на него полагаться. Я бы посмотрел на WMI, как предлагают другие ответы. - person Adrian McCarthy; 14.05.2009

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

person Tamas Czinege    schedule 29.04.2009
comment
Я поддерживаю это. Привыкание к WMI поможет вам с другими задачами, связанными с администратором Windows. Недавно я написал образец того, как использовать WMI из C ++. blog.emptycrate.com/node/376 ​​ - person lefticus; 29.04.2009
comment
Однако есть некоторые предостережения. WMI можно отключить на некоторых ПК. Кроме того, в нем перечислены не все приложения, видимые в апплете панели управления, а только те, которые установлены совместимым установщиком. - person atzz; 13.07.2009

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

person Community    schedule 29.04.2009
comment
С опозданием на много лет, но -1 за то, что не сказал, какой COM API использовался. Группа usenet большая; сказать "иди, гугл" в ответе недостаточно. - person andlabs; 11.08.2016
comment
Панель управления использует COM API, но я предполагаю, что API затем читает из реестра. Что косвенно означает, что он полагается на реестр. - person i486; 15.05.2018

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

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

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

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

person PolyTekPatrick    schedule 18.03.2012
comment
Спасибо, это очень полезно. - person Min Lin; 01.04.2013

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

OP упомянул 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. Как я это пропустил?

person Craig Silver    schedule 15.05.2018