I am using this code to make a list of all the installed programs:
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);
}
}
}
}
On a 64-bit windows, this redirects to Wow6432Node \\Microsoft\\Windows\\CurrentVersion\\Uninstall. But some program entries are still located in the original path and the list is incomplete. How can I avoid redirection and read the values from both paths on a 64-bit Windows installation (and only the first one on a 32-bit windows)?
Change your code to the following:
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);
}
}
}
}
}
And you can either specify
RegistryView.Registry64
or
RegistryView.Registry32
explicitly, rather than letting it default to whatever it likes.
I see two options here:
1) Upgrade to .NET 4 or later and follow Avoid Registry Wow6432Node Redirection .
2) Stay on .NET 2 and call the Win32 API directly as described in Disabling registry redirection for a registry key on an x64 platform .
Managed to get this working after a LOT of trial and error - this is the only place I can see to get the "size" component of the add remove programs.
Runs pretty quickly comparsed to the WMI Win32_Programs counterpart
Might need to be clean up a few if these includes ;-)
#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;
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.