如何使用 C++ Builder 获取版本信息条目

How to get Version Info entries using C++ Builder

How to get version info的线程显示了获取FileVersion的代码,我需要获取其他值,包括我自己添加到VersionInfo中的一些值table。

如何使用 C++Builder 10.2(东京)获取它们?

我曾经在 C++Builder 6.0 中使用 VerQueryValue 方法获取它们,但它在类型上引发了太多异常。

我不知道如何将代码更改为 C++Builder 10.2。

下面是我使用的实际代码:

class.h

struct TransArray
{
    WORD LanguageID, CharacterSet;
};
DWORD VerInfo, VerSize;
HANDLE MemHandle;
LPVOID MemPtr, BufferPtr;
UINT BufferLength;
TransArray *Array;
char QueryBlock[255];
String FFileVersion ;

class.cpp

// this one of the methods which have errors
String __fastcall TAppVersion::GetFileVersion(void)
{
    String Result ;
    BufferPtr = NULL ;

    // Get the product version.
    wsprintf(QueryBlock, "\StringFileInfo\%04x%04x\FileVersion",
                    Array[0].LanguageID, Array[0].CharacterSet);
    VerQueryValue(MemPtr, QueryBlock, &BufferPtr, &BufferLength);

    if(BufferPtr) Result = (char *)BufferPtr;

    return(Result);
}
//---------------------------------------------------
__fastcall TAppVersion::TAppVersion()
{
    FFileName = Application->ExeName ;
    VerSize = GetFileVersionInfoSize(FFileName.c_str(), &VerInfo);
    if (VerSize > 0) {
        MemHandle = GlobalAlloc(GMEM_MOVEABLE, VerSize);
        MemPtr = GlobalLock(MemHandle);
        GetFileVersionInfo(FFileName.c_str(), VerInfo, VerSize, MemPtr);
        VerQueryValue(MemPtr, "\VarFileInfo\Translation", &BufferPtr,
                                &BufferLength);
        Array = (TransArray *)BufferPtr;

        FFileVersion = GetFileVersion();
    }
}
//-----------------------------------------------

前一段时间我玩过这个。它不完整,我将其称为 beta 1。但它就在这里。

header:

class TAppVerInfo
{
public:
    __fastcall TAppVerInfo(const wchar_t* pModPath);
    __fastcall virtual ~TAppVerInfo(void);

    __property System::String LanguagesCodePage                         = {read = GetCodePage};
    __property System::String Comments[System::String LanId]            = {read = GetComments};
    __property System::String InternalName[System::String LanId]        = {read = GetInternalName};
    __property System::String ProductName[System::String LanId]         = {read = GetProductName};
    __property System::String CompanyName[System::String LanId]         = {read = GetCompanyName};
    __property System::String LegalCopyright[System::String LanId]      = {read = GetLegalCopyright};
    __property System::String ProductVersion[System::String LanId]      = {read = GetProductVersion};
    __property System::String FileDescription[System::String LanId]     = {read = GetFileDescription};
    __property System::String LegalTrademarks[System::String LanId]     = {read = GetLegalTrademarks};
    __property System::String PrivateBuild[System::String LanId]        = {read = GetPrivateBuild};
    __property System::String FileVersion[System::String LanId]         = {read = GetFileVersion};
    __property System::String OriginalFilename[System::String LanId]    = {read = GetOriginalFilename};
    __property System::String SpecialBuild[System::String LanId]        = {read = GetSpecialBuild};

protected:
    void *VerInfo;

    System::String __fastcall GetCodePage(void);
    System::String __fastcall GetComments(System::String LanId);
    System::String __fastcall GetInternalName(System::String LanId);
    System::String __fastcall GetProductName(System::String LanId);
    System::String __fastcall GetCompanyName(System::String LanId);
    System::String __fastcall GetLegalCopyright(System::String LanId);
    System::String __fastcall GetProductVersion(System::String LanId);
    System::String __fastcall GetFileDescription(System::String LanId);
    System::String __fastcall GetLegalTrademarks(System::String LanId);
    System::String __fastcall GetPrivateBuild(System::String LanId);
    System::String __fastcall GetFileVersion(System::String LanId);
    System::String __fastcall GetOriginalFilename(System::String LanId);
    System::String __fastcall GetSpecialBuild(System::String LanId);
    System::String __fastcall GetValue(const System::String& LanId, const wchar_t* pName);
};

菲律宾共产党:

__fastcall TAppVerInfo::TAppVerInfo(const wchar_t* pModPath)
{
    DWORD dwUnused;
    DWORD VerInfoSize = GetFileVersionInfoSize(pModPath, &dwUnused);

    VerInfo = malloc(VerInfoSize);
    if(VerInfo)
    {
        if(0 == GetFileVersionInfo(pModPath, 0, VerInfoSize, VerInfo))
        {
            free(VerInfo);
            VerInfo = NULL;
            throw Exception(SysErrorMessage(GetLastError()));
        }
    } //040904E4
}
//---------------------------------------------------------------------------
__fastcall TAppVerInfo::~TAppVerInfo(void)
{
    if(VerInfo)
        free(VerInfo);
}
//---------------------------------------------------------------------------
System::String __fastcall TAppVerInfo::GetCodePage(void)
{
    System::String retVal;

    if(VerInfo)
    {
        struct LANGANDCODEPAGE
        {
            WORD wLanguage;
            WORD wCodePage;
        } *lpTranslate;
        UINT cbTranslate;
        TAutoStringList tStr(new TStringList);
        UINT i;

        VerQueryValue(VerInfo,L"\VarFileInfo\Translation", (LPVOID*)&lpTranslate, &cbTranslate);
        for(i = 0; i < (cbTranslate/sizeof(LANGANDCODEPAGE)); i++)
            tStr->Add(System::String().sprintf(L"%04x%04x", lpTranslate[i].wLanguage, lpTranslate[i].wCodePage));
        retVal = tStr->CommaText;
    }
    return retVal;
}
//---------------------------------------------------------------------------
System::String __fastcall TAppVerInfo::GetComments(System::String LanId)
{
    return GetValue(LanId, L"Comments");
}
//---------------------------------------------------------------------------
System::String __fastcall TAppVerInfo::GetInternalName(System::String LanId)
{
    return GetValue(LanId, L"InternalName");
}
//---------------------------------------------------------------------------
System::String __fastcall TAppVerInfo::GetProductName(System::String LanId)
{
    return GetValue(LanId, L"ProductName");
}
//---------------------------------------------------------------------------
System::String __fastcall TAppVerInfo::GetCompanyName(System::String LanId)
{
    return GetValue(LanId, L"CompanyName");
}
//---------------------------------------------------------------------------
System::String __fastcall TAppVerInfo::GetLegalCopyright(System::String LanId)
{
    return GetValue(LanId, L"LegalCopyright");
}
//---------------------------------------------------------------------------
System::String __fastcall TAppVerInfo::GetProductVersion(System::String LanId)
{
    return GetValue(LanId, L"ProductVersion");
}
//---------------------------------------------------------------------------
System::String __fastcall TAppVerInfo::GetFileDescription(System::String LanId)
{
    return GetValue(LanId, L"FileDescription");
}
//---------------------------------------------------------------------------
System::String __fastcall TAppVerInfo::GetLegalTrademarks(System::String LanId)
{
    return GetValue(LanId, L"LegalTrademarks");
}
//---------------------------------------------------------------------------
System::String __fastcall TAppVerInfo::GetPrivateBuild(System::String LanId)
{
    return GetValue(LanId, L"PrivateBuild");
}
//---------------------------------------------------------------------------
System::String __fastcall TAppVerInfo::GetFileVersion(System::String LanId)
{
    return GetValue(LanId, L"FileVersion");
}
//---------------------------------------------------------------------------
System::String __fastcall TAppVerInfo::GetOriginalFilename(System::String LanId)
{
    return GetValue(LanId, L"OriginalFilename");
}
//---------------------------------------------------------------------------
System::String __fastcall TAppVerInfo::GetSpecialBuild(System::String LanId)
{
    return GetValue(LanId, L"SpecialBuild");
}
//---------------------------------------------------------------------------
System::String __fastcall TAppVerInfo::GetValue(const System::String& LanId, const wchar_t* pName)
{
    System::String retVal;

    if(VerInfo)
    {
        System::String aPath(System::String().sprintf(L"\StringFileInfo\%s\%s", LanId.c_str(), pName));
        wchar_t *pBuf;
        UINT uLen;

        if(VerQueryValue(VerInfo, aPath.c_str(), (void**)&pBuf, &uLen))
            retVal = System::String(pBuf);
    }
    return retVal;
}

您的代码错误地混合了 ANSI 和 UNICODE 逻辑。 VerQueryValue() 是一个预处理器宏,根据是否定义了 UNICODE 分别映射到 VerQueryValueW()VerQueryValueA()。您的代码假设正在使用 VerQueryValueA() ,但情况并非总是如此。在现代版本的 C++Builder 中,默认情况下会使用 VerQueryValueW()

尝试更像这样的东西:

struct TransArray
{
    WORD LanguageID, CharacterSet;
};

DWORD VerInfo, VerSize;
LPVOID MemPtr, BufferPtr;
UINT BufferLength;
TransArray *Array;
String FFileName, FFileVersion;

...

#include <tchar.h>

String __fastcall TAppVersion::GetFileVersion(void)
{
    String Result;

    if (MemPtr && Array)
    {
        // Get the product version.
        TCHAR QueryBlock[40];
        _stprintf(QueryBlock, _T("\StringFileInfo\%04x%04x\FileVersion"), Array[0].LanguageID, Array[0].CharacterSet);
        if (VerQueryValue(MemPtr, QueryBlock, &BufferPtr, &BufferLength)) {
            Result = String(static_cast<TCHAR*>(BufferPtr), BufferLength).Trim();
        }
    }

    return Result;
}
//---------------------------------------------------
__fastcall TAppVersion::TAppVersion()
{
    MemPtr = NULL;
    Array = NULL;

    FFileName = Application->ExeName;

    DWORD Unused;
    VerSize = GetFileVersionInfoSize(FFileName.c_str(), &Unused);
    if (VerSize == 0) return;

    MemPtr = new BYTE[VerSize];
    if (GetFileVersionInfo(FFileName.c_str(), Unused, VerSize, MemPtr)) {
        if (VerQueryValue(MemPtr, TEXT("\VarFileInfo\Translation"), &BufferPtr, &BufferLength) {
            Array = (TransArray *) BufferPtr;
            FFileVersion = GetFileVersion();
        }
    }
}
//-----------------------------------------------
__fastcall TAppVersion::~TAppVersion()
{
    delete[] static_cast<BYTE*>(MemPtr);
}
//-----------------------------------------------

尽管如此,在现代代码中您根本不应该依赖 TCHAR

struct TransArray
{
    WORD LanguageID, CharacterSet;
};

DWORD VerInfo, VerSize;
LPVOID MemPtr, BufferPtr;
UINT BufferLength;
TransArray *Array;
UnicodeString FFileName, FFileVersion;

...

UnicodeString __fastcall TAppVersion::GetFileVersion(void)
{
    UnicodeString Result;

    if (MemPtr && Array)
    {
        // Get the product version.
        WCHAR QueryBlock[40];
        swprintf(QueryBlock, L"\StringFileInfo\%04x%04x\FileVersion", Array[0].LanguageID, Array[0].CharacterSet);
        if (VerQueryValueW(MemPtr, QueryBlock, &BufferPtr, &BufferLength)) {
            Result = UnicodeString(static_cast<WCHAR*>(BufferPtr), BufferLength).Trim();
        }
    }

    return Result;
}
//---------------------------------------------------
__fastcall TAppVersion::TAppVersion()
{
    MemPtr = NULL;
    Array = NULL;

    FFileName = Application->ExeName;

    DWORD Unused;
    VerSize = GetFileVersionInfoSizeW(FFileName.c_str(), &Unused);
    if (VerSize == 0) return;

    MemPtr = new BYTE[VerSize];
    if (GetFileVersionInfoW(FFileName.c_str(), Unused, VerSize, MemPtr)) {
        if (VerQueryValueW(MemPtr, L"\VarFileInfo\Translation", &BufferPtr, &BufferLength) {
            Array = (TransArray *) BufferPtr;
            FFileVersion = GetFileVersion();
        }
    }
}
//-----------------------------------------------
__fastcall TAppVersion::~TAppVersion()
{
    delete[] static_cast<BYTE*>(MemPtr);
}
//-----------------------------------------------