// This function will check for the presence of old versions of the converter UINT __stdcall DetectPreviousConverters(MSIHANDLE hInstall) { int productsCount = sizeof(ProductsToDetect) / sizeof(ProductsToDetect[0]); for (int i=0;i<productsCount;i++) { TCHAR sBuf[512]; DWORD dwBufSize = sizeof(sBuf) / sizeof(sBuf[0]); int nRet = MsiGetProductInfo(ProductsToDetect[i].ProductCode, INSTALLPROPERTY_PRODUCTNAME, sBuf, &dwBufSize); switch (nRet) { case ERROR_SUCCESS: // Product is installed OutputDebugString(_T("Product detected : ")); OutputDebugString(ProductsToDetect[i].ProductProperty); OutputDebugString(_T("\n")); nRet = MsiSetProperty(hInstall, ProductsToDetect[i].ProductProperty, _T("True")); if (nRet != ERROR_SUCCESS) { DisplayError(nRet, _T("MsiSetProperty")); } break; case ERROR_UNKNOWN_PRODUCT: // Product is not installed OutputDebugString(_T("Product NOT detected : ")); OutputDebugString(ProductsToDetect[i].ProductProperty); OutputDebugString(_T("\n")); break; default: DisplayError(nRet, _T("MsiGetProductInfo")); break; } } return ERROR_SUCCESS; }
static int filter(void *self, KDictionary const *fields, KAdd add, void *target) { char const *product = k_dictionary_get(fields, "product"); char const *feature = k_dictionary_get(fields, "feature"); char const *href = k_dictionary_get(fields, "href"); INSTALLSTATE state; state = MsiQueryProductState(product); state = MsiQueryFeatureState(product, feature); char version[256]; char instloc[256]; MsiGetProductInfo(product, INSTALLPROPERTY_VERSION, version, NULL); MsiGetProductInfo(product, INSTALLPROPERTY_INSTALLLOCATION, instloc, NULL); printf("%s version %s\n", product, version); printf("%s instloc %s\n", product, instloc); }
void InstallChecker::getInstalledVersion(std::wstring upgradeCode,std::wstring &version) { TCHAR prodCode[40]; version = L"none"; const wchar_t *code =upgradeCode.c_str(); if (ERROR_SUCCESS != MsiEnumRelatedProducts(code,0,0,prodCode)) return; DWORD sz; TCHAR version_prop[100]; sz = sizeof(version_prop) / sizeof(*version_prop); MsiGetProductInfo(prodCode,INSTALLPROPERTY_VERSIONSTRING, version_prop,&sz); version = version_prop; }
QString InstallChecker::installedVersion( const QString &upgradeCode ) { WCHAR prodCode[40]; const WCHAR *code = (const WCHAR*)upgradeCode.constData(); if( ERROR_SUCCESS != MsiEnumRelatedProducts( code, 0, 0, prodCode ) ) return "none"; DWORD sz; WCHAR version_prop[100]; sz = sizeof(version_prop) / sizeof(*version_prop); MsiGetProductInfo( prodCode, INSTALLPROPERTY_VERSIONSTRING, version_prop, &sz ); return QString::fromWCharArray( version_prop ); }
//通过MSI SDK来获取MSI安装信息 BOOL GetSoftwareFromMSI(LPCTSTR szKeySub, LPTSTR lpDisplayName) { TCHAR szProductGUID[MAX_PATH] = {0}; TCHAR szDisplayName[MAX_PATH] = {0}; DWORD dwLen = MAX_PATH; int iEnumIndex = 0; //MsiEnumProducts函数列举目前广告或安装的所有产品 //iEnumIndex:指定的商品检索的索引,szProductGUID:一个缓冲区,它接收乘积码的指针 UINT uRe = MsiEnumProducts(iEnumIndex, szProductGUID); while(ERROR_NO_MORE_ITEMS != uRe) { if( 0 == lstrcmp(szKeySub, szProductGUID) ) { dwLen = MAX_PATH; memset(szDisplayName, 0, sizeof(szDisplayName)); //返回的产品信息发布和安装的产品 MsiGetProductInfo(szProductGUID, INSTALLPROPERTY_INSTALLEDPRODUCTNAME, szDisplayName, &dwLen); if ( lstrlen(szDisplayName) > 0 ) { //TCHAR szDisplayVersion[MAX_PATH] = {0}; //TCHAR szPublisher[MAX_PATH] = {0}; //TCHAR szInstallDate[MAX_PATH] = {0}; //缓冲区字符长度大于0,将值复制,返回TRUE结束 lstrcpy(lpDisplayName, szDisplayName); return TRUE; } } //匹配失败,索引加1,继续列举 iEnumIndex++; memset(szProductGUID,0,sizeof(szProductGUID)); uRe = MsiEnumProducts(iEnumIndex,szProductGUID); } return FALSE; }
DWORD findPlexLocation(WCHAR* szPlexLocation, DWORD *sizeBuff) { UINT uiStatus = ERROR_SUCCESS; DWORD dwIndex = 0; WCHAR wszAssignmentType[10] = {0}; WCHAR wszProductCode[cchGUID+1] = {0}; WCHAR szSid[128] = L"s-1-1-0"; DWORD cchSid; DWORD cchAssignmentType = sizeof(wszAssignmentType)/sizeof(wszAssignmentType[0]); DWORD cchProductName = MAX_PATH; WCHAR* lpProductName = new WCHAR[cchProductName]; MSIINSTALLCONTEXT dwInstalledContext; bool foundPlex = false; do { uiStatus = MsiEnumProductsEx(NULL, NULL, MSIINSTALLCONTEXT_USERMANAGED | MSIINSTALLCONTEXT_USERUNMANAGED | MSIINSTALLCONTEXT_MACHINE, dwIndex, wszProductCode, &dwInstalledContext, szSid, &cchSid); if(ERROR_SUCCESS == uiStatus) { // obtain the user friendly name of the product UINT uiReturn = MsiGetProductInfo(wszProductCode,INSTALLPROPERTY_PRODUCTNAME,lpProductName,&cchProductName); if (ERROR_MORE_DATA == uiReturn) { // try again, but with a larger product name buffer delete [] lpProductName; // returned character count does not include // terminating NULL ++cchProductName; lpProductName = new WCHAR[cchProductName]; if (!lpProductName) { uiStatus = ERROR_OUTOFMEMORY; break; } uiReturn = MsiGetProductInfo(wszProductCode,INSTALLPROPERTY_PRODUCTNAME,lpProductName,&cchProductName); } if (ERROR_SUCCESS != uiReturn) { // This halts the enumeration and fails. Alternatively the error // could be logged and enumeration continued for the // remainder of the products uiStatus = ERROR_FUNCTION_FAILED; break; } if(wcscmp(lpProductName, L"Plex Media Server") == 0) { // output information wprintf(L" Product %s:\n", lpProductName); //Enumerate All Components DWORD dwComponentIdx = 0; DWORD dwClientIdx = 0; DWORD maxPath = MAX_PATH; WCHAR lpComponentCode[cchGUID+1] = {0}; WCHAR* lpClientName = new WCHAR[cchGUID+1]; WCHAR* lpComponentPath = new WCHAR[maxPath]; WCHAR* lpComponentSubPath; do { uiStatus = MsiEnumComponents(dwComponentIdx, lpComponentCode); UINT clientStatus = ERROR_SUCCESS; UINT pathStatus = ERROR_SUCCESS; //For each component, enumerate the clients do { clientStatus = MsiEnumClients(lpComponentCode, dwClientIdx, lpClientName); //Only get the path if a matching client is found if(clientStatus == ERROR_SUCCESS && 0 == wcscmp(lpClientName, wszProductCode)) { maxPath = MAX_PATH; pathStatus = MsiGetComponentPath(wszProductCode, lpComponentCode, lpComponentPath, &maxPath); if(pathStatus == INSTALLSTATE_LOCAL && wcslen(lpComponentPath) > 0) { //We need to compare the end string to ensure it matches the name of the app //This just does some pointer arithmetic lpComponentSubPath = lpComponentPath + maxPath - APP_NAME_LEN; if(0 == wcscmp(APP_NAME, lpComponentSubPath)) { foundPlex = true; wcscpy_s(szPlexLocation, *sizeBuff, lpComponentPath); } } } dwClientIdx++; }while(ERROR_SUCCESS == clientStatus && !foundPlex); dwClientIdx = 0; dwComponentIdx++; }while(ERROR_SUCCESS == uiStatus && !foundPlex); delete [] lpClientName; delete [] lpComponentPath; lpClientName = lpComponentPath = lpComponentSubPath = NULL; cchProductName = MAX_PATH; } } dwIndex++; } while (ERROR_SUCCESS == uiStatus && !foundPlex); if (lpProductName) { delete [] lpProductName; lpProductName = NULL; } if(foundPlex && szPlexLocation) { *sizeBuff = (DWORD)wcslen(szPlexLocation); return TRUE; } return FALSE; }