プログラムの入手に関する情報をたくさん読みました。どのアルゴリズムも私が望むことをしませんでした。私はインストールされたプログラムを取得する必要があります正確にコントロールパネルのように。
だから私は使用しました:
Win32_Product
クラス。 msiがインストールされているプログラムのみが表示されます。HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
。繰り返しますが、一部のプログラムはコントロールパネルに表示されません。一部のプログラムは、このレジストリノードにないコントロールパネルに表示されます。では、この世界で、インストールされているプログラムを表示するためにコントロールパネルを使用するアルゴリズムを知っている人はいますか?
UPD1:はい、64ビットを使用しています。64ビットのインストール済みプログラム「HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall」に別のノードがあることはわかっていますが、次のコードは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))
{
プログラム.Add(name);
}
}
}
}
registry_key = @"SOFTWARE\Wow6432Node\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);
}
}
}
}
foreach (var program in programs.OrderBy(x => x))
{
Console.WriteLine(program);
}
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);
}
}
MelnikovIの答えは、ほとんどの目的に十分です。リストには144個のアイテムがありましたが、プログラムと機能には143個ありました。 レビュー用、彼の解決策はこれらのレジストリの場所をヒットすることです:
資格を得るには、各サブキーに次のものが必要です。
そして持ってはいけません:
1つの追加の機能強化私が見つけたのはWindowsインストーラーエントリ用で、次のように定義されています。
このようなエントリの場合、Win32関数MsiGetProductInfoW from msi.dllを使用し、GUID。
この関数が1605:ERROR_UNKNOWN_PRODUCTを返す場合は、エントリがWindowsインストーラに従ってインストールされていないため、表示から除外する必要があることを意味します。
このマイナーな調整を実装した後、私のリストはプログラムと機能と同じになりました。
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
}
ここで他のいくつかの回答で説明されているSystemComponentレジストリキーは通常 0または1の可能な値を持つREG_DWORDです。ただし、いくつかのインスタンス(Microsoft Visio2010やMicrosoftProject 2010など)を見てきました。 SystemComponentは、データのないREG_SZです。したがって、SystemComponentをintにキャストするソリューションは、これらの状況で例外をスローする傾向があります。