对于我想用Mingw-w64构建的开放式Windows源项目,如果应用程序意识到其版本,那就太好了。
为此,我复制/粘贴/编辑了一个小的包装,该包装将从应用程序自己的资源中读取版本信息。 在Visual Studio环境(使用vcvars32.bat)中完成此代码后,该代码可以很好地构建。
但是,当我尝试使用MinGw构建它时,编译器可以很好地运行,但是链接器却不能。错误,找不到version.dll中的函数:
VersSample.cpp:(.text+0x14f): undefined reference to VerQueryValueW
我确实在构建命令行中添加了–lversion编译器开关,但它似乎无法正常工作。 有人提示,我想念什么?
build命令如下:
set PATH=C:\Tools\MinGw\mingw64\bin\;%PATH%
windres VersSample.rc -O coff -o VersSample.res
g++ -o VersSample.exe -mwindows -static-libgcc -static-libstdc++ -lversion VersSample.cpp VersSample.res
顺便说一句:我不想根据需要将其放大,但是如果有什么有趣的地方,我可以发布整个功能。
答案 0 :(得分:1)
我知道了。
我不知道为什么,但是 -lversion 的位置似乎很重要。我将其放在g ++调用的末尾,并且有效:
g++ -o VersSample.exe -mwindows -static-libgcc -static-libstdc++ VersSample.cpp VersSample.res -lversion
对于任何感兴趣的人,整个功能如下:
void AddVersionInfo(WCHAR* pszwOutput, const WCHAR* pszwEntry) {
/** Variables: */
DWORD vLen, langD;
BOOL retVal;
LPVOID retbuf = NULL;
WCHAR fileEntry[256];
/** Fetch-Code: */
HRSRC hVersion = FindResource(NULL, MAKEINTRESOURCE(VS_VERSION_INFO), RT_VERSION);
if (hVersion != NULL) {
HGLOBAL hGlobal = LoadResource(NULL, hVersion);
if (hGlobal != NULL) {
LPVOID versionInfo = LockResource(hGlobal);
if (versionInfo != NULL) {
swprintf(fileEntry, L"\\VarFileInfo\\Translation");
retVal = VerQueryValue(versionInfo, fileEntry, &retbuf, (UINT *)&vLen);
if (retVal && vLen == 4) {
memcpy(&langD, retbuf, 4);
#ifdef _MSC_VER
swprintf(fileEntry, L"\\StringFileInfo\\%02X%02X%02X%02X\\%s",
(langD & 0xff00) >> 8, langD & 0xff, (langD & 0xff000000) >> 24,
(langD & 0xff0000) >> 16, pszwEntry);
#else
swprintf(fileEntry, L"\\StringFileInfo\\%02X%02X%02X%02X\\%S",
(langD & 0xff00) >> 8, langD & 0xff, (langD & 0xff000000) >> 24,
(langD & 0xff0000) >> 16, pszwEntry);
#endif
}else{
swprintf(fileEntry, L"\\StringFileInfo\\%04X04B0\\%s",
GetUserDefaultLangID(), pszwEntry);
}
if (VerQueryValue(versionInfo, fileEntry, &retbuf, (UINT *)&vLen)) {
wcscat(pszwOutput, (WCHAR*)retbuf);
}
}
}
UnlockResource(hGlobal);
FreeResource(hGlobal);
}
}
请注意,我不得不添加一个编译器开关来区分MS VS和MinGw环境,因为它们似乎在sprintf(或swprintf)中处理标记的方式有所不同。
有了这个,假设资源中有完整的VersionInfo块,则可以访问数据并将其用作:
AddVersionInfo(buffer, L"FileVersion");