Comment puis-je énumérer / lister toutes les applications installées dans Windows XP?

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

Question

Lorsque je dis "application installée", je veux dire essentiellement toute application visible dans le [Panneau de configuration] - > [Ajout / Suppression de programmes].

Je préférerais le faire en Python, mais C ou C ++ convient également.

Était-ce utile?

La solution

Si vous voulez parler de la liste des applications installées affichée dans Ajouter / Supprimer des programmes dans le panneau de configuration, vous pouvez la trouver dans la clé de registre:

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall

vous trouverez plus d'informations sur la structure de l'arborescence du registre .

Vous devez utiliser l’ API Winreg en python pour lire les valeurs de le registre.

Autres conseils

Découvrez le Win32_Product WMI (Windows Instrumentation de gestion). Voici un tutoriel sur l'utilisation de WMI en Python.

Le Panneau de configuration utilise Win32 COM api, méthode officielle (voir Groupes Google, Win32)
Ne vous fiez jamais au registre.

Le référentiel de scripts Microsoft comporte un script permettant de répertorier tous les logiciels installés.

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

La meilleure implémentation de registre que j’ai vue est celle écrite par Chris Wright (chris128) et publiée sur http://www.vbforums.com/showthread.php?t=598355 . Il utilise plusieurs clés de registre et est beaucoup plus complexe que toutes les réponses actuellement affichées ici. Il semble produire des résultats identiques à ceux de l'application Ajout / Suppression de programmes. Comme l'application ARP, il offre également la possibilité d'inclure les mises à jour.

Bien qu’il soit implémenté dans VB.NET, il devrait être facile de convertir en d’autres langages .NET comme C # ou IronPython. J'imagine que convertir d'abord vers IronPython devrait faciliter assez le portage vers Python normal si c'est ce que vous voulez, mais je l'ai seulement converti moi-même en C #, puis j'ai un peu nettoyé le code.

Un seul petit bogue à signaler: GetUserInstallerKeyPrograms () n'ajoute pas la version des programmes utilisateur à la liste, même s'il l'extrait. C’est facile à résoudre cependant.

Code C # .net permettant d'obtenir la liste des logiciels installés à l'aide de WMI sous xp et win7 (wmi est le seul moyen sous win7)

    WqlObjectQuery wqlQuery =
      new WqlObjectQuery("SELECT * FROM Win32_Product");
        ManagementObjectSearcher searcher =
            new ManagementObjectSearcher(wqlQuery);

        foreach (ManagementObject software in searcher.Get()) {
            Console.WriteLine(software["Caption"]);
        }

Je sais que cette question est ancienne, le PO mentionnait XP et également Python, C ou C ++, mais j’ai constaté que beaucoup d’informations sur le réseau concernant ce sujet étaient incomplètes ou incorrectes. Un exemple de ce dernier est la suggestion d'utiliser WMI - spécifiquement, la classe Win32_Product ; Cependant, comme indiqué ailleurs, cette méthode est lente , en partie parce que, croyez-le ou non, chaque MSI trouvée exécute sa réparation. J'appelle cette solution incorrecte à cause de sa lenteur et de son effet secondaire désagréable. Par exemple, vous avez déjà choisi de désactiver le service Windows d'un programme, mais l'appel de select * from Win32_Product , afin de garantir que la réparation MSI s'exécute, réactivera apparemment le service.

Pour ce qui en vaut la peine, voici ce que je considère comme l’exemple le plus complet à ce jour, bien qu’en C # (je l’ai compilé avec Framework 4.6.1 mais des versions plus basses peuvent également fonctionner.) Il répertorie les versions 32 bits et 64 programmes installés binaires; il dispose des clés de registre qu'il utilise et s'exécute en moins d'une seconde, au moins après la mise en cache. Si vous pouvez proposer des améliorations, proposez-les plutôt que de simplement voter, et je mettrai à jour le code.

Il manque encore des mises à jour . Par exemple, lorsque je l'exécute sur mon système Windows 10 et que je le compare à Panneau de configuration | Programmes et fonctionnalités | Mises à jour installées, je remarque qu’il n’apparaît pas la Mise à jour de sécurité pour Adobe Flash Player pour une raison quelconque.

Je n’ai aucune bonne raison d’utiliser la méthode anonyme, c’est exactement ce que je pensais à l’époque - une sorte de solution méthode-dans-une-méthode.

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

[Soupir] et puis j'ai vu la réponse de @ PolyTekPatrick. Comment ai-je manqué ça? LOL

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top