如何在不安装msi的情况下从msi文件获取产品版本?

时间:2014-12-24 09:16:36

标签: c winapi windows-installer

我正在寻找一个获取msi路径的C API,并返回产品版本(主要版本和次要版本),而不安装API。

谢谢, 埃坦

2 个答案:

答案 0 :(得分:2)

我不会使用开放包的东西 - 这是一个静态数据库,所以MsiOpenDatabase和SQL是要走的路。缺少一些包括,但这工作正常:

#include "stdafx.h"
UINT GetProperty (MSIHANDLE dbHand, LPCTSTR  propname, LPTSTR strVal)
{
    PMSIHANDLE viewH = NULL;
    WCHAR qry [100] = {0};
    StringCchCat (qry, 100, L"Select `Value` from `Property` where `Property`='" );
    StringCchCat (qry, 100, propname);
    StringCchCat (qry, 100, L"'");
    UINT res = MsiDatabaseOpenView (dbHand, qry, &viewH);
    if (ERROR_SUCCESS!=res)
        return res;
    res = MsiViewExecute (viewH, 0); 
    if (ERROR_SUCCESS!=res)
    {
        MsiCloseHandle (viewH);
        return res;
    }
    PMSIHANDLE recH=NULL; 
    res = MsiViewFetch (viewH, &recH); 
    if (ERROR_SUCCESS!=res)
    {
        MsiCloseHandle (viewH);
        return res;
    }
    WCHAR buff [50] = {0}; 
    DWORD dwlen = 50;
    res = MsiRecordGetString (recH, 1, buff, &dwlen);
    if (ERROR_SUCCESS!=res)
    {
        MsiCloseHandle (viewH);
        MsiCloseHandle (recH); 
        return res;
    }
    StringCchCopy (strVal, dwlen+1, buff);
    MsiViewClose (viewH);
    MsiCloseHandle (recH); 
    return (ERROR_SUCCESS);

}

int _tmain(int argc, _TCHAR* argv[])
{
    PMSIHANDLE dbH=NULL;
    UINT res = MsiOpenDatabase (L"C:\\Phil\\MyDD\\Samples Setup\\GetMsiProperty\\Set2.msi", MSIDBOPEN_READONLY, &dbH);
     WCHAR pversion [512] = {0}; 
     res = GetProperty (dbH, L"ProductVersion", pversion); 
    WCHAR ubuff [50] = {0}; 
    res = GetProperty(dbH, L"UpgradeCode", ubuff); 
    WCHAR pbuff [50] = {0}; 
     res = GetProperty(dbH, L"ProductCode", pbuff); 
     WCHAR prodName [512] = {0}; 
     res = GetProperty (dbH, L"ProductName", prodName); 
     WCHAR prodLang [512] = {0}; 
     res = GetProperty (dbH, L"ProductLanguage", prodLang); 
    return 0;
}

答案 1 :(得分:1)

MsiGetFileVersion()从普通文件(exe,dll等)读取版本信息,而不是MSI数据库中的产品版本。

要从MSI内部获取产品版本,您可以使用MsiOpenPackage获取MSI的句柄,然后使用该句柄调用MsiGetProductProperty,请求ProductVersion属性。< / p>

CoInitialize(NULL);

MSIHANDLE hPackage = NULL;
UINT retVal = MsiOpenPackage(_T("TortoiseSVN-1.8.10.26129-x64-svn-1.8.11.msi"), &hPackage);
if (retVal != ERROR_SUCCESS)
{
    return retVal;
}

TCHAR versionBuf[64] = { 0 };
DWORD versionBufSize = sizeof(versionBuf) / sizeof(versionBuf[0]);

MsiGetProductProperty(hPackage, _T("ProductVersion"), versionBuf, &versionBufSize);

MsiCloseHandle(hPackage);