views:

87

answers:

4

I have a solution, mostly C#, but with a few VC++ projects, that is pushed through our standard release process (perl and bash scripts on Unix boxes). Currently the initiative is to validate DLL and EXE versions as they pass through the process. All the versioning is set so that File Version is of the format $Id: $ (between the colon and the second dollar should be a git commit hash), and the Product Version is of the format $Hudson Build: $ (between the colon and the second dollar should be a string representing the hudson build details).

Currently this system works extremely well for the C# projects because this version information is stored as plain strings within the compiled code (you can literally use the unix strings command and see the version information); the problem is that the VC++ projects do not expose this information as strings (I have used a windows system to verify that the version information is correctly being set), so I'm not sure how to extract the version on a unix system. Any suggestions for either A) Getting a string representation of the version embedded in the compiled code, or B) A utility/script which can extract this information?

+1  A: 

Assuming you have an accessor in your DLL for the information you need to verify, you could write a small program that runs under wine and outputs the necessary information to standard output. One such sample program is available under the dynamic link library heading on Wikipedia.

Another option is to figure out how MSVC++ is encoding that information so that you can decode or query it with standard unix tools.

Kaleb Pederson
I was looking at the wine option, unfortunately it's not feasible. Decoding the information is, unfortunately, the nut I think I have to crack.
Guildencrantz
+1  A: 

Windows executables and shared libraries (DLLs) encode version information as binary data (VERSIONINFO) in the resources section.

Take a look at this question to see the win32 APIs which can be used to query version information. Though you need to make a small change to that code. The FindResource and LoadResource APIs should be passed in the handle to the EXE/DLL (already loaded in memory) whose version information you want. Passing in NULL gets the version information associated with the EXE from where this code is being called (this is not what you want).

You need to call LoadLibrary to load an EXE or DLL file on disk and get its handle then pass this handle to the above mentioned API functions as the hModule parameter. And may be also print out the required information to console after you have obtained the required VERSIONINFO.

SDX2000
A: 

Any reason why you couldn't simply use a string containing $Id: $ - like this:

const char version[] = "$Id: $"

Sure, you've got the version IDs in two places, but they're driven from the same source.

Eric Brown
My msbuild foo is low (this is on VS2008, where vcproj files aren't really msbuild projects), so the issue then becomes how to expand `$Id: $` to the commit hash at build time.
Guildencrantz
My Git-fu is low, but VS2008 has a pre-build command that would allow you to run an executable that would expand the IDs to the commit hash.Second question is to ask how the VERSIONINFO resources are built in the first place.
Eric Brown
+1  A: 

The version information for natively compiled code on Windows is stored in UTF-16, ie wide strings, in the binary. You can still use the strings command, but you need to tell it to look for wide strings before it'll find them, using the -e l option.

For example, on my system, RMB > Properties on C:\Windows\notepad.exe gives the file version as 5.1.2600.5512 (xpsp.080413-2105). I copied it to a Linux box, and as you say, strings doesn't find it with the default flags

$ strings notepad.exe | grep xpsp
$

but if you set the encoding it comes out fine:

$ strings -e l notepad.exe | grep xpsp
5.1.2600.5512 (xpsp.080413-2105)
Andy Mortimer
Ooh, I'm glad I didn't have time to do any other work on this first! Thanks for the simple solution.
Guildencrantz