Windows XP にインストールされているすべてのアプリケーションを列挙/リストするにはどうすればよいですか?

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

質問

「インストールされているアプリケーション」とは、基本的に [コントロール パネル] -> [プログラムの追加と削除] に表示されるアプリケーションを指します。

Python で実行したいと思っていますが、C または C++ でも問題ありません。

役に立ちましたか?

解決

コントロールパネルの[アプリケーションの追加と削除]に表示されるインストール済みアプリケーションのリストを意味する場合は、レジストリキーで見つけることができます。

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Uninstall

レジストリツリーの構造の詳細については、こちらをご覧ください

値を読み取るには、Pythonで winreg API を使用する必要がありますレジストリ。

他のヒント

Win32_Product WMI(Windows Management Instrumentation)クラス。 PythonでのWMIの使用に関するチュートリアルをご覧ください。

コントロールパネルは、公式の方法であるWin32 COM APIを使用します(Googleグループ、Win32を参照)
レジストリに依存しないでください。

Microsoft Script Repositoryには、インストールされているすべてのソフトウェアをリストするためのスクリプトがあります。

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

私が見た最高のレジストリベースの実装は、 http://www.vbforums.com/showthread.php?t=598355 。複数のレジストリキーを使用し、ここに現在掲載されている回答よりもはるかに複雑です。 [プログラムの追加と削除]アプリと同じ結果が得られるようです。また、ARPアプリと同様に、更新プログラムを含めるオプションも提供します。

VB.NETに実装されていますが、C#やIronPythonなどの他の.NET言語に簡単に変換できるはずです。 IronPythonに変換することで、必要に応じて通常のPythonに簡単に移植できるはずですが、自分でC#に変換してからコードを少しクリーンアップしただけです。

指摘すべき小さなバグは1つだけです。GetUserInstallerKeyPrograms()は、ユーザープログラムのバージョンを抽出しますが、リストに追加しません。これは簡単に修正できます。

xpおよびwin7でWMIを使用してインストール済みソフトウェアのリストを取得するためのC#.netコード(win7ではwmiが唯一の方法です)

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

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

この質問が古いことは知っていますが、OP では XP について言及し、Python、C、または C++ についても言及していましたが、このトピックに関するネット上の多くの情報が不完全か不正確であることがわかりました。後者の例としては、WMI を使用するという提案があります。 Win32_Product クラス;ただし、他の場所で述べたように、その方法は 遅い, 信じられないかもしれませんが、見つかった各 MSI が実際に修復を実行しているためです。私は、その解決策が非常に遅いことと、厄介な副作用があるため、その解決策は間違っていると呼んでいます。たとえば、プログラムの Windows サービスを無効にすることをすでに選択しているが、 select * from Win32_Product, は、MSI 修復を確実に実行する一環として、サービスを再び有効にするようです。

価値があるものとして、以下は、C# ではありますが、これまでで最も完全な例であると考えられるものです (私は Framework 4.6.1 に対してコンパイルしましたが、それより古いバージョンでも動作する可能性があります)。インストールされている 32 ビットと 64 ビットがリストされています。プログラム。使用するレジストリ キーを破棄し、少なくともキャッシュが開始された後は 1 秒以内に実行されます。改善点を提案できる場合は、単に反対票を投じるのではなく、提案してください。コードを更新します。

一つそれは いくつかのアップデートがまだ欠けています。たとえば、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