我正在使用此代码列出所有已安装的程序:
object line;
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))
{
line = subkey.GetValue("DisplayName");
if (line != null)
{
listBox1.Items.Add(line);
}
}
}
}
在64位窗口上,重定向到 Wow6432Node \ Microsoft \ Windows \ CurrentVersion \ Uninstall。但是一些程序条目仍然位于原始路径中,并且列表不完整。如何在64位Windows安装上避免重定向并从两个路径读取值(并且只在32位窗口上显示第一个)?
答案 0 :(得分:3)
将您的代码更改为以下内容:
object line;
string registry_key = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
using (var baseKey = Microsoft.Win32.RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64))
{
using (var key = baseKey.OpenSubKey(registry_key))
{
foreach (string subkey_name in key.GetSubKeyNames())
{
using (var subKey = key.OpenSubKey(subkey_name))
{
line = subKey.GetValue("DisplayName");
if (line != null)
{
listBox1.Items.Add(line);
}
}
}
}
}
您可以指定
RegistryView.Registry64
或
RegistryView.Registry32
明确地,而不是让它默认为它喜欢的任何东西。
答案 1 :(得分:2)
我在这里看到两个选项:
1)升级到.NET 4或更高版本并按照Avoid Registry Wow6432Node Redirection。
2)继续使用.NET 2并按Disabling registry redirection for a registry key on an x64 platform。
中所述直接调用Win32 API答案 2 :(得分:0)
经过大量的反复试验后设法使它起作用-这是我唯一看到的添加删除程序的“大小”组件的地方。
与WMI Win32_Programs同类产品相比,运行速度相当快
如果其中包括;-)
,可能需要清理一些#include "shobjidl_core.h"
#include <shlobj.h>
#include <atlbase.h>
#include <atlalloc.h>
#include <propsys.h>
#include <stdio.h>
#include <objbase.h>
#include <ole2.h>
#include <shlwapi.h>
#include <propkey.h>
#include "shlguid.h"
void IterateAddRemovePrograms()
{
CComPtr<IShellItem> spPrograms;
SHCreateItemFromParsingName(
L"::{26EE0668-A00A-44D7-9371-BEB064C98683}\\8\\"
L"::{7B81BE6A-CE2B-4676-A29E-EB907A5126C5}", nullptr,
IID_PPV_ARGS(&spPrograms));
CComPtr<IEnumShellItems> spEnum;
spPrograms->BindToHandler(nullptr, BHID_EnumItems, IID_PPV_ARGS(&spEnum));
for (CComPtr<IShellItem> spProgram; spEnum->Next(1, &spProgram, nullptr) == S_OK; spProgram.Release())
{
DiskUsageItem d;
LPWSTR name;
spProgram->GetDisplayName(SIGDN_NORMALDISPLAY, &name);
LPWSTR size;
CComQIPtr<IShellItem2>(spProgram)->GetString(PKEY_Size, &size);
cout << name << " " << size << endl;
}
}