windows系统安装的软件在注册表中有记录,路径为:注册表根句柄HKEY_LOCAL_MACHINE,路径为"Software\Microsoft\Windows\CurrentVersion\Uninstall",涉及到32位应用和64位应用,如果是64位系统,32位的应用则存放在"Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall",64位应用则存放在"Software\Microsoft\Windows\CurrentVersion\Uninstall",如果是32位系统,只能安装32位应用,存放在"Software\Microsoft\Windows\CurrentVersion\Uninstall"
参考代码 SoftInfo.h
#pragma once
#include <string>
#include <vector>
using namespace std;
typedef struct softInfo
{
string m_strSoftName; //软件名
string m_strSoftVersion; //软件版本号
string m_strInstallLocation;//软件安装目录
string m_strPublisher; //软件发布商
string m_strMainProPath; //主程序所在路径
string m_strUninstallPath; //卸载软件所在路径
string m_strInstallDate; //安装事件
}SOFTINFO;
class CSoftInfo
{
public:
vector<SOFTINFO > m_vecSoftInfo;
string m_strError;
public:
CSoftInfo();
~CSoftInfo();
public:
bool GetSoftInfo();
};
class Ctest :CSoftInfo
{
public:
Ctest() {};
~Ctest() {};
};
参考代码 SoftInfo.cpp
#include "pch.h"
#include "SoftInfo.h"
#include <windows.h>
CSoftInfo::CSoftInfo()
{
}
CSoftInfo::~CSoftInfo()
{
}
BOOL Is64BitSystem()
{
typedef VOID(WINAPI *FUN_GetNativeSystemInfo)(LPSYSTEM_INFO lpSystemInfo);
SYSTEM_INFO si;
FUN_GetNativeSystemInfo pfn = (FUN_GetNativeSystemInfo)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "GetNativeSystemInfo");
if (pfn)
{
pfn(&si);
if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 ||
si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64)
{
return TRUE;
}
}
return FALSE;
}
bool CSoftInfo::GetSoftInfo()
{
LONG lRet;
int nIndex;
HKEY hKey = HKEY_LOCAL_MACHINE;
HKEY hResultKey;
HKEY hSubResultKey;
char cSubKeyName[255] = { 0 };//注册表项名称
DWORD lSubKeyName = 255;
char cValueBuffer[512] = { 0 };
DWORD dwBufferLen = 512;
DWORD dwValueType;
DWORD dwSize;
string strKeyPath = "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall";
string strSubKeyPath = strKeyPath;
m_vecSoftInfo.clear(); //清空当前的应用列表
if (Is64BitSystem())
{
//32位应用跳转到WOW64_32NODE
lRet = RegOpenKeyExA(hKey, strKeyPath.c_str(), 0, KEY_READ | KEY_WOW64_32KEY, &hResultKey);
if (lRet != 0)
{
m_strError = "打开注册表失败, 错误码:" + to_string(lRet);
return false;
}
nIndex = 0;
while ((lRet = RegEnumKeyExA(hResultKey, nIndex, cSubKeyName, &lSubKeyName, 0, NULL, NULL, NULL)) == ERROR_SUCCESS)
{
strSubKeyPath = strKeyPath;
strSubKeyPath = strSubKeyPath + "\\" + cSubKeyName;
if (RegOpenKeyExA(hKey, strSubKeyPath.c_str(), 0, KEY_READ | KEY_WOW64_32KEY, &hSubResultKey) == ERROR_SUCCESS)
{
SOFTINFO stSoftInfoItem = { "" };
lRet = RegQueryValueExA(hSubResultKey, (char *)("DisplayName"), 0, &dwValueType, (LPBYTE)cValueBuffer, &dwBufferLen);
if (lRet == ERROR_SUCCESS)
{
stSoftInfoItem.m_strSoftName = cValueBuffer;
}
memset(cValueBuffer, 0, sizeof(char)* dwBufferLen);
dwBufferLen = 255;
lRet = RegQueryValueExA(hSubResultKey, (char *)("DisplayVersion"), 0, &dwValueType, (LPBYTE)cValueBuffer, &dwBufferLen);
if (lRet == ERROR_SUCCESS)
{
stSoftInfoItem.m_strSoftVersion = cValueBuffer;
}
memset(cValueBuffer, 0, sizeof(char)* dwBufferLen);
dwBufferLen = 255;
lRet = RegQueryValueExA(hSubResultKey, (char *)("InstallLocation"), 0, &dwValueType, (LPBYTE)cValueBuffer, &dwBufferLen);
if (lRet == ERROR_SUCCESS)
{
stSoftInfoItem.m_strInstallLocation = cValueBuffer;
}
memset(cValueBuffer, 0, sizeof(char)* dwBufferLen);
dwBufferLen = 255;
lRet = RegQueryValueExA(hSubResultKey, (char *)("Publisher"), 0, &dwValueType, (LPBYTE)cValueBuffer, &dwBufferLen);
if (lRet == ERROR_SUCCESS)
{
stSoftInfoItem.m_strPublisher = cValueBuffer;
}
memset(cValueBuffer, 0, sizeof(char)* dwBufferLen);
dwBufferLen = 255;
lRet = RegQueryValueExA(hSubResultKey, (char *)("InstallLocation"), 0, &dwValueType, (LPBYTE)cValueBuffer, &dwBufferLen);
if (lRet == ERROR_SUCCESS)
{
stSoftInfoItem.m_strMainProPath = cValueBuffer;
}
memset(cValueBuffer, 0, sizeof(char)* dwBufferLen);
dwBufferLen = 255;
lRet = RegQueryValueExA(hSubResultKey, (char *)("UninstallString"), 0, &dwValueType, (LPBYTE)cValueBuffer, &dwBufferLen);
if (lRet == ERROR_SUCCESS)
{
stSoftInfoItem.m_strUninstallPath = cValueBuffer;
}
memset(cValueBuffer, 0, sizeof(char)* dwBufferLen);
dwBufferLen = 255;
lRet = RegQueryValueExA(hSubResultKey, (char *)("InstallDate"), 0, &dwValueType, (LPBYTE)cValueBuffer, &dwBufferLen);
if (lRet == ERROR_SUCCESS)
{
stSoftInfoItem.m_strInstallDate = cValueBuffer;
}
memset(cValueBuffer, 0, sizeof(char)* dwBufferLen);
dwBufferLen = 255;
if (stSoftInfoItem.m_strSoftName != "")
{
m_vecSoftInfo.push_back(stSoftInfoItem);
}
}
if (hSubResultKey != NULL)
{
RegCloseKey(hSubResultKey);
}
nIndex++;
memset(cSubKeyName, 0, sizeof(char)*lSubKeyName);
lSubKeyName = 255;
}
if (hResultKey != NULL)
{
RegCloseKey(hResultKey);
}
//64位应用访问注册表
lRet = RegOpenKeyExA(hKey, strKeyPath.c_str(), 0, KEY_READ | KEY_WOW64_64KEY, &hResultKey);
if (lRet != 0)
{
m_strError = "打开注册表失败, 错误码:" + to_string(lRet);
return false;
}
nIndex = 0;
while ((lRet = RegEnumKeyExA(hResultKey, nIndex, cSubKeyName, &lSubKeyName, 0, NULL, NULL, NULL)) == ERROR_SUCCESS)
{
strSubKeyPath = strKeyPath;
strSubKeyPath = strSubKeyPath + "\\" + cSubKeyName;
if (RegOpenKeyExA(hKey, strSubKeyPath.c_str(), 0, KEY_READ | KEY_WOW64_64KEY, &hSubResultKey) == ERROR_SUCCESS)
{
SOFTINFO stSoftInfoItem = { "" };
lRet = RegQueryValueExA(hSubResultKey, (char *)("DisplayName"), 0, &dwValueType, (LPBYTE)cValueBuffer, &dwBufferLen);
if (lRet == ERROR_SUCCESS)
{
stSoftInfoItem.m_strSoftName = cValueBuffer;
}
memset(cValueBuffer, 0, sizeof(char)* dwBufferLen);
dwBufferLen = 255;
lRet = RegQueryValueExA(hSubResultKey, (char *)("DisplayVersion"), 0, &dwValueType, (LPBYTE)cValueBuffer, &dwBufferLen);
if (lRet == ERROR_SUCCESS)
{
stSoftInfoItem.m_strSoftVersion = cValueBuffer;
}
memset(cValueBuffer, 0, sizeof(char)* dwBufferLen);
dwBufferLen = 255;
lRet = RegQueryValueExA(hSubResultKey, (char *)("InstallLocation"), 0, &dwValueType, (LPBYTE)cValueBuffer, &dwBufferLen);
if (lRet == ERROR_SUCCESS)
{
stSoftInfoItem.m_strInstallLocation = cValueBuffer;
}
memset(cValueBuffer, 0, sizeof(char)* dwBufferLen);
dwBufferLen = 255;
lRet = RegQueryValueExA(hSubResultKey, (char *)("Publisher"), 0, &dwValueType, (LPBYTE)cValueBuffer, &dwBufferLen);
if (lRet == ERROR_SUCCESS)
{
stSoftInfoItem.m_strPublisher = cValueBuffer;
}
memset(cValueBuffer, 0, sizeof(char)* dwBufferLen);
dwBufferLen = 255;
lRet = RegQueryValueExA(hSubResultKey, (char *)("InstallLocation"), 0, &dwValueType, (LPBYTE)cValueBuffer, &dwBufferLen);
if (lRet == ERROR_SUCCESS)
{
stSoftInfoItem.m_strMainProPath = cValueBuffer;
}
memset(cValueBuffer, 0, sizeof(char)* dwBufferLen);
dwBufferLen = 255;
lRet = RegQueryValueExA(hSubResultKey, (char *)("UninstallString"), 0, &dwValueType, (LPBYTE)cValueBuffer, &dwBufferLen);
if (lRet == ERROR_SUCCESS)
{
stSoftInfoItem.m_strUninstallPath = cValueBuffer;
}
memset(cValueBuffer, 0, sizeof(char)* dwBufferLen);
dwBufferLen = 255;
lRet = RegQueryValueExA(hSubResultKey, (char *)("InstallDate"), 0, &dwValueType, (LPBYTE)cValueBuffer, &dwBufferLen);
if (lRet == ERROR_SUCCESS)
{
stSoftInfoItem.m_strInstallDate = cValueBuffer;
}
memset(cValueBuffer, 0, sizeof(char)* dwBufferLen);
dwBufferLen = 255;
if (stSoftInfoItem.m_strSoftName != "")
{
m_vecSoftInfo.push_back(stSoftInfoItem);
}
}
if (hSubResultKey != NULL)
{
RegCloseKey(hSubResultKey);
}
nIndex++;
memset(cSubKeyName, 0, sizeof(char)*lSubKeyName);
lSubKeyName = 255;
}
if (hResultKey != NULL)
{
RegCloseKey(hResultKey);
}
}
return true;
}
新建工程测试代码 main.cpp
#include "pch.h"
#include <iostream>
#include "softinfo.h"
#include <iomanip>
using namespace std;
int main()
{
CSoftInfo clsSoftInfo;
clsSoftInfo.GetSoftInfo();
cout << clsSoftInfo.m_vecSoftInfo.size() << endl;
char *cPrint;
for (int i = 0; i < clsSoftInfo.m_vecSoftInfo.size(); i++)
{
cPrint = new char[sizeof(clsSoftInfo.m_vecSoftInfo[i])+1];//"%60s%10s%30s%60s%10s"
memset(cPrint, 0, sizeof(clsSoftInfo.m_vecSoftInfo[i])+1);
sprintf(cPrint, ("%40s%10s%30s%40s%10s\n"), clsSoftInfo.m_vecSoftInfo[i].m_strSoftName.c_str(), clsSoftInfo.m_vecSoftInfo[i].m_strSoftVersion.c_str(), clsSoftInfo.m_vecSoftInfo[i].m_strPublisher.c_str(), clsSoftInfo.m_vecSoftInfo[i].m_strInstallLocation.c_str(), clsSoftInfo.m_vecSoftInfo[i].m_strInstallDate.c_str());
cout << cPrint;
delete cPrint;
cPrint = NULL;
}
}
测试结果: