如何使用 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);
}
//-----------------------------------------------
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);
}
//-----------------------------------------------