Pelles C forum

C language => Tips & tricks => Topic started by: DMac on April 04, 2006, 10:40:55 PM

Title: GetVersionInfo()
Post by: DMac on April 04, 2006, 10:40:55 PM
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
Title: Re: GetVersionInfo()
Post by: EdPellesC99 on September 06, 2011, 04:32:40 PM
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
Title: Re: GetVersionInfo()
Post by: TimoVJL on September 06, 2011, 05:40:18 PM
Use compiler option -Ze Enable Microsoft extensions ?
Title: Re: GetVersionInfo()
Post by: DMac on September 06, 2011, 05:56:37 PM
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.
Title: Re: GetVersionInfo()
Post by: EdPellesC99 on September 07, 2011, 12:30:49 AM
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)
Title: Re: GetVersionInfo()
Post by: CommonTater on September 07, 2011, 12:46:33 AM
Do you have the calling convention set to stdcall on your compiler tab?
(Most windows calls us stdcall for x86, fastcall for x64)

Title: Re: GetVersionInfo()
Post by: EdPellesC99 on September 07, 2011, 05:58:07 AM
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
Title: Re: GetVersionInfo()
Post by: TimoVJL on September 07, 2011, 12:45:52 PM
Another version using example from // http://www.catch22.net/content/snippets (http://forum.pellesc.de// http://www.catch22.net/content/snippets)
From MicroSoft:
Quote
To 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 (http://blogs.msdn.com/b/oldnewthing/archive/2006/12/26/1365215.aspx)
Code: [Select]
#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:
Code: [Select]
#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;
}
Title: Re: GetVersionInfo()
Post by: EdPellesC99 on September 07, 2011, 03:59:55 PM
Tx Timo,

  Will be studying this over.

Appreciate much.

..Ed