News:

Download Pelles C here: http://www.smorgasbordet.com/pellesc/

Main Menu

GetVersionInfo()

Started by DMac, April 04, 2006, 10:40:55 PM

Previous topic - Next topic

DMac

I looked around for some way to easily echo version info in my application's about box.  I found this function on Code Project and adapted it to work with Pelles (Originally MFC).

The CP article is referenced in the comments.

Enjoy
No one cares how much you know,
until they know how much you care.

EdPellesC99

Hi DMac,

  Realize this is old but time flies!

  I downloaded this, I get a lot of errors if I try to compile with the new PellesC, by opening the project.

If I simply try to compile from scratch, I only get one error:

C:\Program Files\PellesC\Include\Win\winnt.h(558): fatal error #1014: #error: "No target architecture".

Any ideas?

I am trying to look at your work !

Tx, Ed

TimoVJL

Use compiler option -Ze Enable Microsoft extensions ?
May the source be with you

DMac

I downloaded and compiled this using 6.50.8 Release Candidate #4 32 bit.

I got an error for a typo "NUL" instead of "NULL".  Fixed that and got one warning and a successful compile.

Are you using the 64 bit version?

Whatever the case if you go to Project>Project Options>Compiler Tab>in the dropdown labled "Machine:" Choose X86 and it should compile fine.
No one cares how much you know,
until they know how much you care.

EdPellesC99

Ok,

I found the NUL, changed it to NULL
The compiler tab is already set to X86.

I am using the 32 bit version, I still get:
C:\Program Files\PellesC\Include\Win\winnt.h(558): fatal error #1014: #error: "No target architecture".

Timo if I now add the -Ze option, I get these errors:
Building main.obj.
D:\SGV1\C _RCDATA cmd into win32_exe Using TempFldr\Fr DMac GetVersionInfo\main.c(79): warning #2030: '=' used in a conditional expression.
D:\SGV1\C _RCDATA cmd into win32_exe Using TempFldr\Fr DMac GetVersionInfo\main.c(44): warning #2229: Local 'csRet' is potentially used without being initialized.
Building main.exe.
POLINK: error: Unresolved external symbol '__imp__VerQueryValueA@16'.
POLINK: fatal error: 1 unresolved external(s).
*** Error code: 1 ***
Done.

Tx for the speedy replies DMac and Timo, Ed (DMac I am using the identical release)

CommonTater

Do you have the calling convention set to stdcall on your compiler tab?
(Most windows calls us stdcall for x86, fastcall for x64)


EdPellesC99

Well it was stdcall.

I notice if I disable Microsoft extentions, I cannot set it to stdcall.

ten minutes later....

Ok, DMac was right. It compiles.

I went back to using DMac's project file, (which I should have done before after correcting "NULL", instead of building w a new project).

DMac does use  _cdecl as the Calling conv, for the x86

but he checks *three* boxes:

Enable Microsoft extentions
Enable Pelles, and
Define compatibility names.

I did not have the second two checked.

Problem Solved.

Thanks you three !

Ed

TimoVJL

#7
Another version using example from // http://www.catch22.net/content/snippets
From MicroSoft:
QuoteTo retrieve the appropriate resource, before you call VerQueryValue, you must first call the GetFileVersionInfoSize function, and then the GetFileVersionInfo function.
look here too:
http://blogs.msdn.com/b/oldnewthing/archive/2006/12/26/1365215.aspx
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winver.h>
#include <stdio.h>

#pragma comment(lib, "version.lib")
#pragma comment(lib, "user32.lib")

LPSTR GetVersionInfo(TCHAR *szValue, TCHAR *szBuffer, ULONG nLength)
{
LPSTR csRet;
DWORD len;
TCHAR szFileName[MAX_PATH];

csRet = NULL;
if (GetModuleFileName(NULL, szFileName, sizeof(szFileName)))
{
len = GetFileVersionInfoSize(szFileName, 0);
csRet = NULL;
LPVOID ver = LocalAlloc(LPTR, len);
//LPVOID ver = GlobalAlloc(LPTR, len);
//ver = LocalLock(ver);

if (ver != NULL)
{
DWORD *codepage;
char fmt[256];
PVOID ptr = 0;
if (GetFileVersionInfo(szFileName, 0, len, ver))
{
if (VerQueryValue(ver, "\\VarFileInfo\\Translation", (LPVOID) & codepage, &len))
{
//wsprintf(fmt, "\\StringFileInfo\\%04x%04x\\%s", (*codepage) & 0xFFFF, (*codepage) >> 16, szValue);
wsprintf(fmt, "\\StringFileInfo\\%08x\\%s", (*codepage) << 16 | (*codepage) >> 16, szValue);
if (VerQueryValue(ver, fmt, &ptr, &len))
{
lstrcpyn(szBuffer, (TCHAR *)ptr, min(nLength, len));
csRet = szBuffer;
}
}
}
LocalFree(ver);
//GlobalFree(ver);
}
}
return csRet;
}

int __cdecl main(int argc, char *argv[])
{
char szTmp[260];

printf("%s\n",GetVersionInfo("Comments", szTmp, sizeof(szTmp)));
printf("%s\n",GetVersionInfo("CompanyName", szTmp, sizeof(szTmp)));
printf("%s\n",GetVersionInfo("FileDescription", szTmp, sizeof(szTmp)));
printf("%s\n",GetVersionInfo("InternalName", szTmp, sizeof(szTmp)));
printf("%s\n",GetVersionInfo("LegalCopyright", szTmp, sizeof(szTmp)));
printf("%s\n",GetVersionInfo("LegalTrademarks", szTmp, sizeof(szTmp)));
printf("%s\n",GetVersionInfo("OriginalFilename", szTmp, sizeof(szTmp)));
printf("%s\n",GetVersionInfo("PrivateBuild", szTmp, sizeof(szTmp)));
printf("%s\n",GetVersionInfo("ProductName", szTmp, sizeof(szTmp)));
printf("%s\n",GetVersionInfo("ProductVersion", szTmp, sizeof(szTmp)));
printf("%s\n",GetVersionInfo("SpecialBuild", szTmp, sizeof(szTmp)));

// And now for something we did not include in the version info
printf("\n%s\n",GetVersionInfo("FileName", szTmp, sizeof(szTmp)));
return 0;
}

If you still want do that with LoadResource without UNICODE, try this with allocated buffer:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winver.h>
#include <stdio.h>

#pragma comment(lib, "version.lib")
#pragma comment(lib, "user32.lib")

LPSTR GetVersionInfo(TCHAR *szValue, TCHAR *szBuffer, ULONG nLength)
{
LPSTR csRet;

csRet = NULL;
HRSRC hVersion = FindResource(GetModuleHandle(NULL),
MAKEINTRESOURCE(VS_VERSION_INFO), RT_VERSION);
DWORD dwSize = SizeofResource(GetModuleHandle(NULL), hVersion);
if (hVersion != NULL)
{
HGLOBAL hGlobal = LoadResource(GetModuleHandle(NULL), hVersion);

if (hGlobal != NULL)
{
//LPVOID ver = LockResource(hGlobal);
LPVOID ver = LocalAlloc(LPTR, dwSize*2);

if (ver != NULL)
{
memcpy(ver, hGlobal, dwSize);
DWORD *codepage;
UINT len;
char fmt[0x40];
PVOID ptr = 0;
if (VerQueryValue(ver, "\\VarFileInfo\\Translation", (LPVOID) & codepage, &len))
{
//wsprintf(fmt, "\\StringFileInfo\\%04x%04x\\%s", (*codepage) & 0xFFFF, (*codepage) >> 16, csEntry);
wsprintf(fmt, "\\StringFileInfo\\%08x\\%s", (*codepage) << 16 | (*codepage) >> 16, szValue);
if (VerQueryValue(ver, fmt, &ptr, &len))
{
lstrcpyn(szBuffer, (TCHAR*)ptr, min(nLength, len));
csRet = szBuffer;
}
}
LocalFree(ver);
}
FreeResource(hGlobal);
}
}
return csRet;
}

int main(int argc, char *argv[])
{
char szTmp[260];
printf("%s\n",GetVersionInfo("Comments", szTmp, sizeof(szTmp)));
printf("%s\n",GetVersionInfo("CompanyName", szTmp, sizeof(szTmp)));
printf("%s\n",GetVersionInfo("FileDescription", szTmp, sizeof(szTmp)));
printf("%s\n",GetVersionInfo("InternalName", szTmp, sizeof(szTmp)));
printf("%s\n",GetVersionInfo("LegalCopyright", szTmp, sizeof(szTmp)));
printf("%s\n",GetVersionInfo("LegalTrademarks", szTmp, sizeof(szTmp)));
printf("%s\n",GetVersionInfo("OriginalFilename", szTmp, sizeof(szTmp)));
printf("%s\n",GetVersionInfo("PrivateBuild", szTmp, sizeof(szTmp)));
printf("%s\n",GetVersionInfo("ProductName", szTmp, sizeof(szTmp)));
printf("%s\n",GetVersionInfo("ProductVersion", szTmp, sizeof(szTmp)));
printf("%s\n",GetVersionInfo("SpecialBuild", szTmp, sizeof(szTmp)));

// And now for something we did not include in the version info
printf("\n%s\n",GetVersionInfo("FileName", szTmp, sizeof(szTmp)));
return 0;
}
May the source be with you

EdPellesC99

Tx Timo,

  Will be studying this over.

Appreciate much.

..Ed