Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
192 views
in Technique[技术] by (71.8m points)

c++ - Can't read FileVersionInfo with Code Page mismatch

I have some reasonably tried and tested code which uses the Windows API calls to read FileVersionInfo strings, like "FileVersion" and "CompanyName".

I found it failed with one particular 3rd party DLL. The problem seems to be this:

Reading the VarFileInfoTranslation value, I get 040904B0 (US English, Unicode). But when I then attempt to call VerQueryValue on StringFileInfo40904B0CompanyName, it returns false.

But tweaking the code to use the Windows Latin-1 ANSI codepage works: StringFileInfo40904E4CompanyName.

So, the code page in the string table doesn't match the VarFileInfoTranslation value.

According to the example resource at the bottom of MSDN's VERSIONINFO resource documentation, this is an appropriate thing to do!

Given this, can I use the published VersionInfo APIs to correctly read the strings for this file, without "guessing" the codepage?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Unfortunately the VERSIONINFO structure, when compiled from a resource file, allows you to define languages that don't exist in the string block, and string blocks that have no entry in the language table. In other words, the structure isn't sanity checked. As Jonathan Potter mentions in comments, your best bet when working with an arbitrary library is to use a heuristic search for the string block that best fits your application.

In your case, however, you're using the VLC libraries which currently define their version information as follows: (trimmed so it doesn't take half a page)

BEGIN
  BLOCK "StringFileInfo"
  BEGIN
    BLOCK "040904E4"
    BEGIN
      (...)
    END
  END
  BLOCK "VarFileInfo"
  BEGIN
    VALUE "Translation", 0x409, 1200
  END
END

As you can see the language in the translation block is en-us CP1200 (UTF-16LE), but the string block is tagged en-us CP1252 (ANSI Latin 1). Oddly enough the information for the main executable is correct, and the information is nearly identical.

Remy Lebeau submitted a bug report for the issue, and I've submitted a patch.

As of 24-Jun-2016 the patch has been accepted and backported to the 2.2 maintenance branch.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...