FileVersionInfo.GetVersionInfo () is incorrect in console application

I get serious weirdness using FileVersionInfo.GetVersionInfo () and was hoping someone could help.

The basics of the problem are that I repeat all the files in the folder that calls GetVersionInfo () for each. There are about 300 files. This works fine for all but 2 files. For these DLLs, I get inferior information back from GetVersionInfo ().

To eliminate all other variables, I extracted this call into a simple test application, and it still had the same problem. However, if I built the test application as a Windows application (it was originally a console application), the data returned correctly.

To clarify, the incorrect data returned at startup as a console application is not just null data, as you could get if the file did not contain version information. It contained reasonable data, but only incorrect data. It is as if he is reading it from another file. I searched for a file containing the corresponding version information, but cannot find it.

Why does this simple call work differently if it is created as a console application and not a Windows application?

If anyone can help with this, I would be very grateful.

Rgds, Andy

- Added code

using System; using System.Diagnostics; namespace test { class Program { static void Main(string[] args) { string file = "C:\\ProblemFile.dll"; FileVersionInfo version = FileVersionInfo.GetVersionInfo(file); string fileName = version.FileName; string fileVersion = version.FileVersion; Console.WriteLine(string.Format("{0} : {1}", fileName, fileVersion)); } } } 
+4
source share
4 answers

This behavior seems strange. Can a console application not load the DLL from the same place as the WinForms application? This would mean that GetVersionInfo uses some other API than just Win32 CreateFile (perhaps through some kind of DLL resolution mechanism, side by side, or something else); remember that under the covers of version.dll your request will be executed, and not the CLR itself.

Look at FileVersionInfo via Reflector in the other direction:

 public static unsafe FileVersionInfo GetVersionInfo(string fileName) { // ... int fileVersionInfoSize = UnsafeNativeMethods.GetFileVersionInfoSize(fileName, out num); FileVersionInfo info = new FileVersionInfo(fileName); if (fileVersionInfoSize != 0) { byte[] buffer = new byte[fileVersionInfoSize]; fixed (byte* numRef = buffer) { IntPtr handle = new IntPtr((void*) numRef); if (!UnsafeNativeMethods.GetFileVersionInfo(fileName, 0, fileVersionInfoSize, new HandleRef(null, handle))) { return info; } int varEntry = GetVarEntry(handle); if (!info.GetVersionInfoForCodePage(handle, ConvertTo8DigitHex(varEntry))) { int[] numArray = new int[] { 0x40904b0, 0x40904e4, 0x4090000 }; foreach (int num4 in numArray) { if ((num4 != varEntry) && info.GetVersionInfoForCodePage(handle, ConvertTo8DigitHex(num4))) { return info; } } } } } return info; } 

As you can see there, an interesting dance continues with code pages. What if there were several version information resources associated with them in the DLL that you checked? Depending on the culture of the program call in GetVersionInfo , I think that code page calls could return other results?

Take some time to check the DLL resources and make sure that there is only one language / code page for version information. Hope this may indicate a solution.

+8
source

Of course, the β€œfiles” you see are not. and..? If you repeat all files, you will always see entries for. (current directory) and .. (up). GetVersion Info can return something for them. You will have to filter these entries manually by name.

0
source

File and build options are two different things.

Are you sure you are not expecting another?

0
source

Update: tried this. Does not work.

 using System; using System.Diagnostics; using System.Runtime.InteropServices; namespace test { class Program { [DllImport("COMCTL32")] private static extern int InitCommonControls(int nExitCode); static void Main(string[] args) { InitCommonControls(0); string file = "C:\\ProblemFile.dll"; FileVersionInfo version = FileVersionInfo.GetVersionInfo(file); string fileName = version.FileName; string fileVersion = version.FileVersion; Console.WriteLine(string.Format("{0} : {1}", fileName, fileVersion)); } } } 
0
source

Source: https://habr.com/ru/post/1300623/


All Articles