5

C++ 获取已安装程序笔记

 3 years ago
source link: https://www.ascotbe.com/2019/11/14/C++GetInstalledProgramNotes/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
C++ 获取已安装程序笔记

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

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

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

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

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

powershell
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;

}


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK