0

My dll built in c++ has a .rc file that contains this:

VS_VERSION_INFO VERSIONINFO
 FILEVERSION 1,0,8,7
 PRODUCTVERSION 1,0,8,7

I wish read the FILEVERSION value to log into my code.. how can I do? I read something, but all the posts are relative to read other dll or exe, I need to read my current dll

thanks

ghiboz
  • 7,863
  • 21
  • 85
  • 131
  • Reading your own version resource is a lot simpler than reading another file's resource. You can't get a file-not-found error. GetFileVersionInfo() needs the path, use GetModuleFileName() to get it. The HMODULE you need is passed to you in DllMain(). If you use macros to create your .rc file then you don't need it at all. Google "use macro to set .rc file version number" for hints. – Hans Passant Jun 06 '18 at 21:27
  • thanks, but I don't wnat SET a fileversion, but read it – ghiboz Jun 06 '18 at 21:36
  • Yes, that was obvious. The "don't need it at all" angle is the way to do it without having to use GetFileVersionInfo(). Code that is not written can never fail and doesn't have to be maintained. – Hans Passant Jun 06 '18 at 21:40
  • @ghiboz if you use preprocessor defines in a `.h` file to specify the version numbers in the `.rc` file, you can use the same `.h` file in your `.cpp` code as well, then you don't need to query the version numbers dynamically at runtime, they will already be available to your code at compile-time. I think that is what Hans was hinting at – Remy Lebeau Jun 06 '18 at 22:59

1 Answers1

3

Using GetFileVersionInfo() and VerQueryValue() is the safe and official way to read any file's version data. The DLL can get its own path + filename by calling GetModuleFileName() with the HINSTANCE provided to its DllMain() entry point.

That being said, it is more efficient for the DLL to just read the version data out of its own version resource directly, using (Find|Load|Lock)Resource() instead of GetFileVersionInfo(). However, there are caveats with doing this:

  • it is not an approach that is officially supported by Microsoft.

  • the memory pointer that is obtained from LockResouce() cannot be passed to VerQueryValue(). You must allocate a copy of the resource block, and then you can pass the copy to VerQueryValue().

  • however, the only version data that you can safely query from the copied resource block using VerQueryValue() is the root VS_FIXEDFILEINFO structure, which is good enough to get the FileVersion and ProductVersion fields. Querying any of the localized version data requires fixups that are normally performed by GetFileVersionInfo(), and even VerQueryValue() itself in coordination with GetFileVersionInfo().

There are several answers on StackOverflow that explain how to use this approach, and some of them have code snippets, including:

https://stackoverflow.com/a/48577200/65863

https://stackoverflow.com/a/13942403/65863

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770