我读了很多关于获取程序的信息。所有算法都没有做我想做的事。我需要安装与控制面板完全一样的程序。
所以我用:
Win32_Product
类。它只显示已安装的msi程序。HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
。同样,某些程序没有显示在控制面板中,有些程序显示在控制面板中,而不是在此注册表节点中。那么,世界上有谁知道哪种算法使用控制面板来显示已安装的程序呢?
UPD1 1:是的,我使用64位,我知道64位安装程序"HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall“还有另一个节点,但是下面的代码列举了twise HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall部分,奇怪的是.
var registry_key =新列表();string registry_key=registry_key使用(Microsoft.Win32.RegistryKey key = Registry.LocalMachine.OpenSubKey(registry_key)) { foreach (string subkey_name in key.GetSubKeyNames()) { name (RegistryKey subkey =key.OpenSubKey(Subkey_name){ var名称= (string)subkey.GetValue("DisplayName");如果(!string.IsNullOrEmpty(名称)){programs.Add(名称);} registry_key =programs.Add使用(Microsoft.Win32.RegistryKey键= Registry.LocalMachine.OpenSubKey(registry_key)) { foreach (key.GetSubKeyNames()中的字符串subkey_name ){ var (RegistryKey subkey =key.OpenSubKey(Subkey_name){var name = (string)subkey.GetValue("DisplayName");if (!string.IsNullOrEmpty(名称)){programs.Add(名称);} foreach ( programs.OrderBy(x => x)中的var程序){Console.WriteLine(程序);}
发布于 2015-10-22 05:40:00
MelnikovI的答案在大多数情况下都足够了--我的列表中有144项,而程序和特性中有143项。用于审查,他的解决方案是访问以下注册表位置:
要符合条件,每个子项必须具有:
也不得拥有:
我发现的one增强是用于Windows条目,定义为:
对于这些条目,您可以采取其他步骤,从MsiGetProductInfoW msi.dll中使用Win32函数,并为键表示的GUID请求"VersionString“属性。
如果此函数返回1605: ERROR_UNKNOWN_PRODUCT,则意味着该条目不是根据Windows安装的,应该从显示中排除。
在实现这个小调整之后,我的列表现在与程序和功能相同。
发布于 2015-09-14 21:48:18
我使用了MelnikovI编写的代码(这非常有用),并添加了一些内容。首先,它搜索注册表中的四个位置:
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#开始,所以我不知道如何遍历所有四个区域,所以我有两个循环(一个用于HKLM,一个用于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
}
发布于 2019-04-18 16:36:12
其他几个答案中讨论的SystemComponent注册表项通常是一个可能值为0或1的REG_DWORD。然而,我看到了一些实例(比如Microsoft 2010和Microsoft 2010),其中SystemComponent是一个没有数据的REG_SZ。因此,任何将SystemComponent转换为int的解决方案都可能在这些情况下引发异常。
https://stackoverflow.com/questions/15524161
复制相似问题