17

プログラムの入手に関する情報をたくさん読みました。どのアルゴリズムも私が望むことをしませんでした。コントロールパネルとまったく同じようにプログラムをインストールする必要があります。

だから私は使用しました:

  1. WMIWin32_Productクラス。msiがインストールされているプログラムのみが表示されます。
  2. レジストリキー。HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall。繰り返しますが、一部のプログラムはコントロールパネルに表示されません。一部のプログラムは、このレジストリノードにないコントロールパネルに表示されます。

では、この世界で、インストールされているプログラムを表示するためにコントロールパネルを使用するアルゴリズムを知っている人はいますか?

UPD1:はい、64ビットを使用しています。64ビットでインストールされたプログラム「HKLM \ SOFTWARE \ Wow6432Node \ Microsoft \ Windows \ CurrentVersion \ Uninstall」に別のノードがあることはわかっていますが、次のコードはtwise HKLM \ SOFTWARE \ Wow6432Node \ Microsoft \Windows\を列挙しています。 CurrentVersion \ Uninstallセクション、奇妙な...

var programs = new List(); string Registry_key = @ "SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Uninstall"; using(Microsoft.Win32.RegistryKey key = Registry.LocalMachine.OpenSubKey(registry_key)){foreach(string subkey_name in key.GetSubKeyNames()){using(RegistryKey subkey = key.OpenSubKey(subkey_name)){var name =(string) subkey.GetValue( "DisplayName"); if(!string.IsNullOrEmpty(name)){programs.Add(name); }}}} Registry_key = @ "SOFTWARE \ Wow6432Node \ Microsoft \ Windows \ CurrentVersion \ Uninstall"; using(Microsoft.Win32.RegistryKey key = Registry.LocalMachine.OpenSubKey(registry_key)){foreach(string subkey_nameinkey。GetSubKeyNames()){using(RegistryKey subkey = key.OpenSubKey(subkey_name)){var name =(string)subkey.GetValue( "DisplayName"); if(!string.IsNullOrEmpty(name)){programs.Add(name); }}}} foreach(プログラム内のvarプログラム.OrderBy(x => x)){Console.WriteLine(program); } x)){Console.WriteLine(program); } x)){Console.WriteLine(program); }
4

4 に答える 4

33

OK gyus、私はホットフィックスやアップデートなしでレジストリからインストールされたプログラムを取得できるクラスを書きました。それでも、コントロールパネルとまったく同じではありませんが、ほとんどです。これが他の人の役に立つことを願っています。

public static class InstalledPrograms
{{
    const string Registry_key = @ "SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Uninstall";

public static List<string> GetInstalledPrograms() { var result = new List<string>(); result.AddRange(GetInstalledProgramsFromRegistry(RegistryView.Registry32)); result.AddRange(GetInstalledProgramsFromRegistry(RegistryView.Registry64)); return result; } private static IEnumerable<string> GetInstalledProgramsFromRegistry(RegistryView registryView) { var result = new List<string>(); using (RegistryKey key = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, registryView).OpenSubKey(registry_key)) { foreach (string subkey_name in key.GetSubKeyNames()) { using (RegistryKey subkey = key.OpenSubKey(subkey_name)) { if(IsProgramVisible(subkey)) { result.Add((string)subkey.GetValue("DisplayName")); } } } } return result; } private static bool IsProgramVisible(RegistryKey subkey) { var name = (string)subkey.GetValue("DisplayName"); var releaseType = (string)subkey.GetValue("ReleaseType"); //var unistallString = (string)subkey.GetValue("UninstallString"); var systemComponent = subkey.GetValue("SystemComponent"); var parentName = (string)subkey.GetValue("ParentDisplayName"); return !string.IsNullOrEmpty(name) && string.IsNullOrEmpty(releaseType) && string.IsNullOrEmpty(parentName) && (systemComponent == null); } }

于 2013-03-21T06:12:03.393 に答える
4

MelnikovIの答えは、ほとんどの目的に十分です。リストには144個のアイテムがありましたが、プログラムと機能には143個ありました。 レビューのために、彼の解決策はこれらのレジストリの場所をヒットすることです:

  • HKLM \ Software \ Microsoft \ Windows \ CurrentVersion \ Uninstall
  • HKCU \ Software \ Microsoft \ Windows \ CurrentVersion \ Uninstall
  • HKLM \ Software \ Wow6432Node \ Microsoft \ Windows \ CurrentVersion \ Uninstall

資格を得るには、各サブキーに次のものが必要です。

  • DisplayNameREG_SZ値

そして持ってはいけない:

  • SystemComponent REG_DWORD(ゼロ以外)
  • ParentKeyNameまたはParentDisplayNameREG_SZ値
  • ReleaseTypeREG_SZ値

私が見つけた追加の拡張機能の1つは、次のように定義されたWindowsインストーラーエントリ用です。

  • キー名は標準のGUID文字列です
  • WindowsInstaller REG_DWORDが存在します(ゼロ以外)

このようなエントリの場合、 msi.dllからWin32関数MsiGetProductInfoWを使用し、キーで表されるGUIDの「VersionString」プロパティを要求するという追加の手順を実行できます

この関数が1605:ERROR_UNKNOWN_PRODUCTを返す場合は、エントリがWindowsインストーラに従ってインストールされていないため、表示から除外する必要があることを意味します。

このマイナーな調整を実装した後、私のリストはプログラムと機能と同じになりました。

于 2015-10-22T05:40:00.310 に答える
2

MelnikovIが書いたコード(これは非常に役に立ちました)を取り、いくつか追加しました。まず、レジストリ内の4つの場所を検索します。

HKLM \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Uninstall

HKLM \ SOFTWARE \ Wow6432Node \ Microsoft \ Windows \ CurrentVersion \ Uninstall

HKCU \ SOFTWARE \ Microsoft \ Windows \ CurrentVersion \ Uninstall

HKCU \ SOFTWARE \ Wow6432Node \ Microsoft \ Windows \ CurrentVersion \ Uninstall

また、サブキーがあるかどうかを確認します。ない場合は、サブキーをスキップします。

最後に、特定の文字セット[^ a-zA-Z0-9。()+-]のみを許可する正規表現を実行します。

私はC#から始めているだけなので、4つのregの場所すべてをループする方法がわからなかったので、2つのループがあります(1つはHKLM用、もう1つはHKCU用)。

public static class InstalledPrograms
    {
      public static List<string> GetInstalledPrograms()
        {
            var result = new List<string>();
            result.AddRange(GetInstalledProgramsFromRegistry(RegistryView.Registry32));
            result.AddRange(GetInstalledProgramsFromRegistry(RegistryView.Registry64));
            result.Sort();
            return result;
        }
        private static string cleanText(string dirtyText)
        {
            Regex rgx = new Regex("[^a-zA-Z0-9 .()+-]");
            string result = rgx.Replace(dirtyText, "");
            return result;
        }
        private static IEnumerable<string> GetInstalledProgramsFromRegistry(RegistryView registryView)
        {
            var result = new List<string>();
            List<string> uninstall = new List<string>();
            uninstall.Add(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall");
            uninstall.Add(@"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall");
            foreach (string registry_key in uninstall)
            {
               using (RegistryKey key = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, registryView).OpenSubKey(registry_key))
               {
                    foreach (string subkey_name in key.GetSubKeyNames())
                    {
                        using (RegistryKey subkey = key.OpenSubKey(subkey_name))
                        {
                            if (IsProgramVisible(subkey))
                            {
                                result.Add(cleanText(subkey.GetValue("DisplayName").ToString()).ToString());
                            }
                        }
                    }
                }
                using (RegistryKey key = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, registryView).OpenSubKey(registry_key))
                {
                    if (key != null)
                    {
                        foreach (string subkey_name in key.GetSubKeyNames())
                        {
                            using (RegistryKey subkey = key.OpenSubKey(subkey_name))
                            {
                                if (IsProgramVisible(subkey))
                                {
                                    result.Add(cleanText(subkey.GetValue("DisplayName").ToString()).ToString());
                                }
                            }
                        }
                    }
                }
            }

            return result;
        }

興味のある方は、使用しているPowerShellと結果を比較しましたが、同じです。

##Get list of Add/Remove programs
if (!([Diagnostics.Process]::GetCurrentProcess().Path -match '\\syswow64\\'))
{
$uninstallPath = "\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\"
$uninstallWow6432Path = "\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\"
@(
if (Test-Path "HKLM:$uninstallWow6432Path" ) { Get-ChildItem "HKLM:$uninstallWow6432Path"}
if (Test-Path "HKLM:$uninstallPath" ) { Get-ChildItem "HKLM:$uninstallPath" }
if (Test-Path "HKCU:$uninstallWow6432Path") { Get-ChildItem "HKCU:$uninstallWow6432Path"}
if (Test-Path "HKCU:$uninstallPath" ) { Get-ChildItem "HKCU:$uninstallPath" }
) |
ForEach-Object { Get-ItemProperty $_.PSPath } |
Where-Object {
$_.DisplayName -and !$_.SystemComponent -and !$_.ReleaseType -and !$_.ParentKeyName -and ($_.UninstallString -or $_.NoRemove)
} |
Sort-Object DisplayName |
Select-Object DisplayName
}
else
{
"You are running 32-bit Powershell on 64-bit system. Please run 64-bit Powershell instead." | Write-Host -ForegroundColor Red
}
于 2015-09-14T21:48:18.477 に答える
0

ここで他のいくつかの回答で説明されているSystemComponentレジストリキーは、通常、0または1の可能な値を持つREG_DWORDです。ただし、SystemComponentがデータのないREG_SZであるインスタンス(MicrosoftVisio2010やMicrosoftProject2010など)をいくつか見ました。 。したがって、SystemComponentをintにキャストするソリューションは、これらの状況で例外をスローする傾向があります。

于 2019-04-18T16:36:12.157 に答える