用c#读取windows系统上所有安装的软件
为了保证程序的最大兼容性,选择了编译成32位应用程序,在64位操作系统上,是有两个注册表的,一个32位的,一个64位的,所以32位程序访问注册表的key时,操作系统会自动转向到32位的注册表上,导致我们无法获取到64位注册表上的软件信息
用win32 API设置注册表不自动转向来读取
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
namespace Tools
{
class SystemSoft
{
static UIntPtr HKEY_CLASSES_ROOT = (UIntPtr)0x80000000;
static UIntPtr HKEY_CURRENT_USER = (UIntPtr)0x80000001;
static UIntPtr HKEY_LOCAL_MACHINE = (UIntPtr)0x80000002;
static UIntPtr HKEY_USERS = (UIntPtr)0x80000003;
static UIntPtr HKEY_CURRENT_CONFIG = (UIntPtr)0x80000005;
static int ERROR_NO_MORE_ITEMS = 259;
static long KEY_NOT_FOUND = 2;
[DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool Wow64DisableWow64FsRedirection(ref IntPtr ptr);
// 开启64位(文件系统)的操作转向
[DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool Wow64RevertWow64FsRedirection(IntPtr ptr);
// 获取操作Key值句柄
[DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern uint RegOpenKeyEx(UIntPtr hKey, string lpSubKey, uint ulOptions,
int samDesired, out IntPtr phkResult);
//关闭注册表转向(禁用特定项的注册表反射)
[DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern long RegDisableReflectionKey(IntPtr hKey);
//使能注册表转向(开启特定项的注册表反射)
[DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern long RegEnableReflectionKey(IntPtr hKey);
//获取Key值(即:Key值句柄所标志的Key对象的值)
[DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern int RegQueryValueEx(IntPtr hKey, string lpValueName, int lpReserved,
out uint lpType, StringBuilder lpData,
ref uint lpcbData);
[DllImport("Advapi32.dll", CharSet = CharSet.Auto, SetLastError = true, EntryPoint = "RegEnumKeyEx")]
private static extern long RegEnumKeyEx(IntPtr hKey, uint index, StringBuilder lpName, ref uint lpcbName, IntPtr reserved,
IntPtr lpClass, IntPtr lpcbClass, out long lpftLastWriteTime);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern int RegCloseKey(IntPtr hKey);
public static string AddressWithIs32or64()
{
try
{
ConnectionOptions oConn = new ConnectionOptions();
System.Management.ManagementScope oMs = new System.Management.ManagementScope("\\\\localhost", oConn);
System.Management.ObjectQuery oQuery = new System.Management.ObjectQuery("select AddressWidth from Win32_Processor");
ManagementObjectSearcher oSearcher = new ManagementObjectSearcher(oMs, oQuery);
ManagementObjectCollection oReturnCollection = oSearcher.Get();
string addressWidth = null;
foreach (ManagementObject oReturn in oReturnCollection)
{
addressWidth = oReturn["AddressWidth"].ToString();
}
return addressWidth;
}
catch (Exception ex)
{
return "32";
}
}
private static UIntPtr TransferKeyName(string keyName)
{
switch (keyName)
{
case "HKEY_CLASSES_ROOT":
return HKEY_CLASSES_ROOT;
case "HKEY_CURRENT_USER":
return HKEY_CURRENT_USER;
case "HKEY_LOCAL_MACHINE":
return HKEY_LOCAL_MACHINE;
case "HKEY_USERS":
return HKEY_USERS;
case "HKEY_CURRENT_CONFIG":
return HKEY_CURRENT_CONFIG;
}
return HKEY_CLASSES_ROOT;
}
public static void Get32BitRegistrySubKey(Dictionary<string, AppItem> dict, string parentKeyName, string subKeyName)
{
int KEY_WOW64_32KEY = (0x0200);
GetRegistrySubKey(dict, parentKeyName, subKeyName, KEY_WOW64_32KEY);
}
public static void Get64BitRegistrySubKey(Dictionary<string, AppItem> dict, string parentKeyName, string subKeyName)
{
int KEY_WOW64_64KEY = (0x0100);
GetRegistrySubKey(dict, parentKeyName, subKeyName, KEY_WOW64_64KEY);
}
public static void GetRegistrySubKey(Dictionary<string, AppItem> dict, string parentKeyName, string subKeyName, int KEY_WOW64_KEY)
{
int KEY_QUERY_VALUE = (0x0001);
int KEY_WOW64_64KEY = KEY_WOW64_KEY;
int KEY_ENUMERATE_SUB_KEYS = (0x0008);
int KEY_ALL_WOW64 = (KEY_QUERY_VALUE | KEY_WOW64_64KEY | KEY_ENUMERATE_SUB_KEYS);
try
{
//将Windows注册表主键名转化成为不带正负号的整形句柄(与平台是32或者64位有关)
UIntPtr hKey = TransferKeyName(parentKeyName);
//声明将要获取Key值的句柄
IntPtr pHKey = IntPtr.Zero;
//记录读取到的Key值
StringBuilder result = new StringBuilder();
//关闭文件系统转向
IntPtr oldWOW64State = new IntPtr();
if (Wow64DisableWow64FsRedirection(ref oldWOW64State))
{
//获得操作Key值的句柄
uint ret = RegOpenKeyEx(hKey, subKeyName, 0, KEY_ALL_WOW64, out pHKey);
if (ret != KEY_NOT_FOUND)
{
//关闭注册表转向(禁止特定项的注册表反射)
RegDisableReflectionKey(pHKey);
uint index = 0;
StringBuilder sb = new StringBuilder("".PadLeft(1024));
uint MAX_REG_KEY_SIZE = 1024;
long writetime = 1024;
long re = RegEnumKeyEx(pHKey, index, sb, ref MAX_REG_KEY_SIZE, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, out writetime);
if (re != KEY_NOT_FOUND) //键不存在
{
while (re != ERROR_NO_MORE_ITEMS)
{
string subKey = subKeyName + "\\" + sb.ToString();
AppItem appitem = GetRegistryKey(parentKeyName, subKey, KEY_WOW64_KEY);
if (appitem != null)
{
string key = sb.ToString();
appitem.identifier = key;
if (!dict.ContainsKey(key))
{
dict.Add(sb.ToString(), appitem);
}
}
sb = new StringBuilder("".PadLeft(1024));
MAX_REG_KEY_SIZE = 1024;
index = index + 1;
re = RegEnumKeyEx(pHKey, index, sb, ref MAX_REG_KEY_SIZE, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, out writetime);
}
}
//打开注册表转向(开启特定项的注册表反射)
RegEnableReflectionKey(pHKey);
}
//关闭注册句柄
RegCloseKey(pHKey);
}
//打开文件系统转向
Wow64RevertWow64FsRedirection(oldWOW64State);
return;
}
catch (Exception ex)
{
return;
}
}
public static AppItem GetRegistryKey(string parentKeyName, string subKeyName, int KEY_WOW64_KEY)
{
int KEY_QUERY_VALUE = (0x0001);
int KEY_WOW64_64KEY = KEY_WOW64_KEY;
int KEY_ENUMERATE_SUB_KEYS = (0x0008);
int KEY_ALL_WOW64 = (KEY_QUERY_VALUE | KEY_WOW64_64KEY | KEY_ENUMERATE_SUB_KEYS);
AppItem appitem = null;
try
{
//将Windows注册表主键名转化成为不带正负号的整形句柄(与平台是32或者64位有关)
UIntPtr hKey = TransferKeyName(parentKeyName);
//声明将要获取Key值的句柄
IntPtr pHKey = IntPtr.Zero;
//关闭文件系统转向
IntPtr oldWOW64State = new IntPtr();
if (Wow64DisableWow64FsRedirection(ref oldWOW64State))
{
//获得操作Key值的句柄
uint re = RegOpenKeyEx(hKey, subKeyName, 0, KEY_ALL_WOW64, out pHKey);
if (re != KEY_NOT_FOUND)
{
//关闭注册表转向(禁止特定项的注册表反射)
RegDisableReflectionKey(pHKey);
//获取访问的Key值
//记录读取到的Key值
uint lpType = 0;
uint resultSize = 1024;
StringBuilder sys = new StringBuilder("".PadLeft(1024));
int ret = RegQueryValueEx(pHKey, "SystemComponent", 0, out lpType, sys, ref resultSize);
if (ret == KEY_NOT_FOUND) //键不存在,说明非系统软件
{
StringBuilder name = new StringBuilder("".PadLeft(1024));
ret = RegQueryValueEx(pHKey, "DisplayName", 0, out lpType, name, ref resultSize);
if (name.ToString().Trim() != "")
{
StringBuilder publisher = new StringBuilder("".PadLeft(1024));
ret = RegQueryValueEx(pHKey, "Publisher", 0, out lpType, publisher, ref resultSize);
StringBuilder version = new StringBuilder("".PadLeft(1024));
ret = RegQueryValueEx(pHKey, "DisplayVersion", 0, out lpType, version, ref resultSize);
StringBuilder installDate = new StringBuilder("".PadLeft(1024));
ret = RegQueryValueEx(pHKey, "InstallDate", 0, out lpType, installDate, ref resultSize);
appitem = new AppItem();
appitem.publisher = publisher.ToString();
appitem.version = version.ToString();
appitem.name = name.ToString();
string installTime = installDate.ToString().Trim();
appitem.installTime = TimeFormat(installTime);
}
}
//打开注册表转向(开启特定项的注册表反射)
RegEnableReflectionKey(pHKey);
//关闭注册句柄
}
RegCloseKey(pHKey);
}
//打开文件系统转向
Wow64RevertWow64FsRedirection(oldWOW64State);
//返回Key值
}
catch (Exception ex)
{
}
return appitem;
}
public static string TimeFormat(string installTime)
{
string time = "";
if (installTime == "")
{
return time;
}
try
{
time = installTime.Substring(0, 4) + "-" + installTime.Substring(4, 2) + "-" + installTime.Substring(6, 2);
}
catch (Exception e)
{
time = "";
}
return time;
}
public static List<AppItem> GetWindowsSoft()
{
Dictionary<string, AppItem> dict = new Dictionary<string, AppItem>();
string sIs64or32System = AddressWithIs32or64();
if (sIs64or32System.Equals("32"))
{
Get32BitWindowsSoft(dict);
}
else
{
Get32BitRegistrySubKey(dict, "HKEY_LOCAL_MACHINE", @"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall");
Get32BitRegistrySubKey(dict, "HKEY_CURRENT_USER", @"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall");
Get64BitRegistrySubKey(dict, "HKEY_LOCAL_MACHINE", @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall");
Get64BitRegistrySubKey(dict, "HKEY_CURRENT_USER", @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall");
}
//Get32BitWindowsSoft(dict);
List<AppItem> list = new List<AppItem>();
foreach (AppItem item in dict.Values)
{
list.Add(item);
}
return list;
}
public static Dictionary<string, AppItem> Get32BitWindowsSoft(Dictionary<string, AppItem> dict)
{
string key = string.Empty;
RegistryKey localMachine;
RegistryKey Uninstall;
IntPtr ptr = new IntPtr();
IntPtr ptr2 = new IntPtr();
key = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
localMachine = Registry.LocalMachine;
Uninstall = localMachine.OpenSubKey(key, false);
GetInstallSofts(Uninstall,dict);
Uninstall.Close();
localMachine = Registry.CurrentUser;
Uninstall = localMachine.OpenSubKey(key, false);
GetInstallSofts(Uninstall,dict);
Uninstall.Close();
return dict;
}
private static void GetInstallSofts(RegistryKey Uninstall, Dictionary<string, AppItem> dict)
{
foreach (string subkey in Uninstall.GetSubKeyNames())
{
try
{
if (subkey == null)
{
continue;
}
else
{
RegistryKey currentKey = Uninstall.OpenSubKey(subkey);
AppItem appitem = new AppItem();
string name = (string)currentKey.GetValue("DisplayName");
string version = (string)currentKey.GetValue("DisplayVersion");
string publisher = (string)currentKey.GetValue("publisher");
string installTime = (string)currentKey.GetValue("InstallDate");
object sys = currentKey.GetValue("SystemComponent");
currentKey.Close();
if (sys == null)
{
if (dict.ContainsKey(subkey))
{
continue;
}
if (name == "" || name == null)
{
continue;
}
appitem.name = name;
appitem.version = version;
appitem.publisher = publisher;
appitem.installTime = TimeFormat(installTime);
appitem.identifier = subkey;
dict.Add(subkey, appitem);
}
}
}
catch (Exception ex)
{
}
}
return;
}
}
}
评论
暂无评论~~