在Windows系统中,已安装软件的信息都保存在注册表中

那种绿色免安装包还不知道怎么获取

32位系统存在以下两个位置:

HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall

64位系统在32位系统上多出一处,也就是WOW6432Node的节点下

HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall

如何区分哪个是补丁哪个是安装程序

1.如果注册表项下面有"SystemComponent"字段并且值等于1时,表示这是个系统组件,而不是应用软件。
2.如果注册表项下面有"ParentKeyName"字段则表示该项是某个分类下的子项,一般情况补丁才会有"ParentKeyName"字段。
比如这个"Update for  (KB2504637)"

具体实现代码

  • 拿64位系统举例

    要做的就是分别循环3个注册列表里面的值

HKEY hKey;
HRESULT hr = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, UNINSTALL_SOFT32, 0, KEY_READ | KEY_WOW64_64KEY, &hKey);
HRESULT hr2 = ::RegOpenKeyEx(HKEY_CURRENT_USER, UNINSTALL_SOFT32, 0, KEY_READ | KEY_WOW64_64KEY, &hKey);
HRESULT hr3 = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, UNINSTALL_SOFT64, 0, KEY_READ | KEY_WOW64_64KEY, &hKey);
RegistryHandler(hKey, installers);

  • 定义一个核心处理函数

    void installser::CInstallerHandler::RegistryHandler(HKEY &hKey, std::vector<tagInstaller> & installers)//函数处理终端
    {
    unsigned long index;
    TCHAR buffer[MAX_PATH];
    for (index = 0;; index++)
    {
    memset(buffer, 0, sizeof(buffer));
    DWORD len = sizeof(buffer);
    HRESULT hr = RegEnumKeyEx(hKey, index, buffer, &len, 0, NULL, NULL, NULL);//枚举指定的打开注册表项的子项
    if (hr == ERROR_SUCCESS){
    tagInstaller itl;
    if (DumpSoftware(itl, buffer, hKey)){
    if (itl.name != ""){
    installers.push_back(itl);
    }
    }

    }
    else if (hr == ERROR_NO_MORE_ITEMS){
    RegCloseKey(hKey);
    break;
    }
    else{
    RegCloseKey(hKey);
    break;
    }

    }
    }
  • 核心代码打开注册表循环提取里面的值

bool CInstallerHandler::DumpSoftware(tagInstaller & itl, LPCTSTR szKey, HKEY hParent)//注册列表相应信息查询函数
{
LRESULT lr;
HKEY hKey;
LONG size;
TCHAR buffer[MAX_PATH];
lr = RegOpenKey(hParent, szKey, &hKey);//hParent表示注册列表的健值,szKey要打开的注册表项的名称,hKey打开注册列表后返回指定表的指针

//不能打开注册表
if (lr != ERROR_SUCCESS)
{
logger::record() << "Cannot open key";
return false;
}


size = sizeof(buffer);
lr = GetValue(hKey, _T("DisplayName"), &buffer[0], &size);
if (lr == ERROR_SUCCESS)
{
if (size > 0)
{
itl.name = buffer;
}


}
else
{
size = sizeof(buffer);
lr = GetValue(hKey, _T("QuietDisplayName"), &buffer[0], &size);
if (ERROR_SUCCESS == lr && size > 0)
{
itl.name = buffer;
}
/*else
return false;*/
}

if (itl.name.empty())
{
RegCloseKey(hKey);
return false;
}

size = sizeof(buffer);
lr = GetValue(hKey, _T("SystemComponent"), &buffer[0], &size);//判断是否是其他程序安装的
if (lr == ERROR_SUCCESS)
{
if (buffer>0){
return false;
}


}
size = sizeof(buffer);
lr = GetValue(hKey, _T("ParentKeyName"), &buffer[0], &size);//判断是否是补丁
if (lr == ERROR_SUCCESS)
{
if (buffer>0){
return false;
}


}


size = sizeof(buffer);
lr = GetValue(hKey, _T("InstallLocation"), &buffer[0], &size);
if (ERROR_SUCCESS == lr && size > 0)
{
itl.install_path = buffer;
itl.install_path = CStringUtil::StringToUTF8(itl.install_path);
//logger::record() << itl.install_path;
}
else//如果找不到安装路径就找lcon图标路径
{
lr = GetValue(hKey, _T("DisplayIcon"), &buffer[0], &size);
if (ERROR_SUCCESS == lr && size > 0)
{

itl.install_path = buffer;
itl.install_path=StringProcess(itl.install_path);
itl.install_path = CStringUtil::StringToUTF8(itl.install_path);
}
else//如果还是找不到就找卸载路径
{
lr = GetValue(hKey, _T("UninstallString"), &buffer[0], &size);
if (ERROR_SUCCESS == lr && size > 0)
{
itl.install_path = buffer;
itl.install_path = StringProcess(itl.install_path);
itl.install_path = CStringUtil::StringToUTF8(itl.install_path);
}
}
}


DWORD dwValue, dwType;
DWORD dwBufLen = 255;
std::string install_data;
if (RegQueryValueEx(hKey, _T("InstallDate"), NULL, &dwType, (LPBYTE)&buffer, &dwBufLen) == ERROR_SUCCESS)
{
if (dwType == 4){
DWORD dwSize = 0;
lr = GetDword(hKey, _T("InstallDate"), dwSize);
if (ERROR_SUCCESS == lr){
time_t t = dwSize;
auto p = gmtime(&t);
char s[80];
strftime(s, 80, "%Y-%m-%d %H:%M:%S", p);
itl.install_data = s;
}
}
else{
size = sizeof(buffer);
lr = GetValue(hKey, _T("InstallDate"), &buffer[0], &size);


if (ERROR_SUCCESS == lr && size > 0)
{
itl.install_data = buffer;

if (itl.install_data.length() == 8){
std::string temp = itl.install_data.substr(0, 4);
temp.append("-");
temp.append(itl.install_data.substr(4, 2));
temp.append("-");
temp.append(itl.install_data.substr(6, 2));
temp.append(" 00:00:00");
itl.install_data = temp;
}
else{
itl.install_data = "";
}
}
else
itl.install_data = "";
}
}




DWORD dwSize = 0;
lr = GetDword(hKey, _T("EstimatedSize"), dwSize);
if (ERROR_SUCCESS == lr && size > 0)
{
auto temp = dwSize / 1024;
char buf[64] = {0};

_itoa_s(temp, buf, sizeof(buf), 10);
itl.package_size = buf;
}

size = sizeof(buffer);
lr = GetValue(hKey, _T("DisplayVersion"), &buffer[0], &size);
if (ERROR_SUCCESS == lr && size > 0)
{
itl.version = buffer;
}

size = sizeof(buffer);
lr = GetValue(hKey, _T("Publisher"), &buffer[0], &size);
if (ERROR_SUCCESS == lr && size > 0)
{

itl.publisher = buffer;
itl.publisher = CStringUtil::StringToUTF8(itl.publisher);
}

itl.name = CStringUtil::StringToUTF8(itl.name);

RegCloseKey(hKey);

return true;

}