Reputation: 10951
Is there a way to extract information from VS_VERSION_INFO (e.g. FILEVERSION) inside the same application?
I know, you probably thinking in a path of:
1. GetModuleFileName(...)
2. GetFileVersionInfoSize(...)
3. GetFileVersionInfo(...)
4. VerQueryValue(...)
BUT! There is a "twist": I need to make activex control to extract it's own version. So GetModuleFileName would not return the correct filename, it will be parent application name, so the version info will be from parent application too, not the activex control.
Any ideas?
Upvotes: 0
Views: 3450
Reputation: 10951
Here is the code which eventiuly worked for me (and Yes, it is for MFC ActiveX control):
CString modFilename;
if(GetModuleFileName(AfxGetInstanceHandle(), modFilename.GetBuffer(MAX_PATH), MAX_PATH) > 0)
{
modFilename.ReleaseBuffer(MAX_PATH);
DWORD dwHandle = 0;
DWORD dwSize = GetFileVersionInfoSize(modFilename, &dwHandle);
if(dwSize > 0)
{
LPBYTE lpInfo = new BYTE[dwSize];
ZeroMemory(lpInfo, dwSize);
if(GetFileVersionInfo(modFilename, 0, dwSize, lpInfo))
{
//// Use the version information block to obtain the FILEVERSION.
//// This will extract language specific part of versio resources. 040904E4 is English(US) locale,
//// it should match to your project
//UINT valLen = MAX_PATH;
//LPVOID valPtr = NULL;
//if(::VerQueryValue(lpInfo,
// TEXT("\\StringFileInfo\\040904E4\\FileVersion"),
// &valPtr,
// &valLen))
//{
// CString valStr((LPCTSTR)valPtr);
// AfxMessageBox(valStr);
//}
//// This will extract so called FIXED portion of the version info
UINT valLen = MAX_PATH;
LPVOID valPtr = NULL;
if(::VerQueryValue(lpInfo,
TEXT("\\"),
&valPtr,
&valLen))
{
VS_FIXEDFILEINFO* pFinfo = (VS_FIXEDFILEINFO*)valPtr;
// convert to text
CString valStr;
valStr.Format(_T("%d.%d.%d.%d"),
(pFinfo->dwFileVersionMS >> 16) & 0xFFFF,
(pFinfo->dwFileVersionMS) & 0xFFFF,
(pFinfo->dwFileVersionLS >> 16) & 0xFFFF,
(pFinfo->dwFileVersionLS) & 0xFFFF
);
AfxMessageBox(valStr);
}
}
delete[] lpInfo;
}
}
Upvotes: 2
Reputation: 5256
At step 1 you can call GetModuleFileName and pass in the hModule of your DLL. You get the hModule in DllMain():
extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
DWORD length = ::GetModuleFileName(hInstance, fullFilename, MAX_PATH);
// ...
}
}
Upvotes: 1