Holy cow, I wrote a book!
A customer was writing a test to verify that their patching system
was working properly, but they found that even after the patch
a call to VerQueryValue reported that the
file was still the original version.
Why was the VerQueryValue function reporting
the wrong version?
Recall that the version resource is, well, a resource.
And one of the things that happens with resources is that
they can get redirected based on the language the user is running.
When you ask for the resources of a
the loader redirects your request to the appropriate language-specific
That way, if you're running on an English system, the resources
come from the DLL with English resources,
whereas if you're running on a German system,
the resources come from the DLL with German resources.
The customer's patch updated only the language-neutral DLL
(since it was a code fix that involved no resource changes).
When the GetFileVersionInfo function loaded the
DLL and asked for its resources,
the loader redirected the request to the English satellite DLL.
To disable this redirection,
you can use the GetFileVersionInfo function
and don't pass the FILE_VER_GET_LOCALIZED flag
covered this a few years ago.
If you use the plain
the version information that comes back is a blend of the language-neutral
and the localized information:
The binary version information comes from the language-neutral DLL,
whereas the string version information comes from the localized DLL.
The strings come from the localized DLL because you want the
information like FileDescription
to be something meaningful to the user.
It does mean, though, that if you are extracting version information
for testing and verification purposes,
you need to be mindful of where you are getting them from
so that you get the values you expect.