尝试使用具有管理员权限的MsiEnumProduct获取所有已安装产品的列表,但发现它没有列出所有产品,很少有产品错过。下面是我使用的代码。
以下是用于枚举已安装产品的功能,并获取产品的详细信息,如名称,版本,位置和发布商。
bool MsiQueryProperty(LPCTSTR szProductCode,
LPCTSTR szUserSid,
MSIINSTALLCONTEXT dwContext,
LPCTSTR szProperty, wchar_t* szValue, DWORD valueSize)
{
DWORD cchValue = 0;
UINT ret2 = ::MsiGetProductInfoEx(
szProductCode,
szUserSid,
dwContext,
szProperty,
NULL,
&cchValue);
if (ret2 == ERROR_SUCCESS)
{
cchValue++;
if (cchValue <= valueSize)
{
ret2 = ::MsiGetProductInfoEx(
szProductCode,
szUserSid,
dwContext,
szProperty,
(LPTSTR)szValue,
&cchValue);
}
}
return true;
}
void MsiEnum()
{
UINT ret = 0;
DWORD dwIndex = 0;
TCHAR szInstalledProductCode[39] = { 0 };
TCHAR szSid[128] = { 0 };
DWORD cchSid;
MSIINSTALLCONTEXT dwInstalledContext;
do
{
memset(szInstalledProductCode, 0, sizeof(szInstalledProductCode));
cchSid = sizeof(szSid) / sizeof(szSid[0]);
ret = ::MsiEnumProductsEx(
NULL, // all the products in the context
_T("s-1-1-0"), // i.e.Everyone, all users in the system
MSIINSTALLCONTEXT_USERMANAGED | MSIINSTALLCONTEXT_USERUNMANAGED | MSIINSTALLCONTEXT_MACHINE,
dwIndex,
szInstalledProductCode,
&dwInstalledContext,
szSid,
&cchSid);
if (ret == ERROR_SUCCESS)
{
wchar_t name[BUFSIZ] = { 0 };
MsiQueryProperty(
szInstalledProductCode,
cchSid == 0 ? NULL : szSid,
dwInstalledContext,
INSTALLPROPERTY_INSTALLEDPRODUCTNAME, name, BUFSIZ);
wchar_t publisher[BUFSIZ] = { 0 };
MsiQueryProperty(
szInstalledProductCode,
cchSid == 0 ? NULL : szSid,
dwInstalledContext,
INSTALLPROPERTY_PUBLISHER, publisher, BUFSIZ);
wchar_t version[BUFSIZ] = { 0 };
MsiQueryProperty(
szInstalledProductCode,
cchSid == 0 ? NULL : szSid,
dwInstalledContext,
INSTALLPROPERTY_VERSIONSTRING, version, BUFSIZ);
wchar_t location[BUFSIZ] = { 0 };
MsiQueryProperty(
szInstalledProductCode,
cchSid == 0 ? NULL : szSid,
dwInstalledContext,
INSTALLPROPERTY_INSTALLLOCATION, location, BUFSIZ);
dbg_print(L"Installed Program Name:%s", name);
dbg_print(L"publisher:%s", publisher);
dbg_print(L"version:%s", version);
dbg_print(L"location:%s", location);
dwIndex++;
}
} while (ret == ERROR_SUCCESS);
}