我使用FileVersionInfo.GetVersionInfo()得到了一些严重的怪异,并希望有人可以提供帮助。
问题的基础是我正在遍历每个文件夹中调用GetVersionInfo()的所有文件。大约有300个文件。这适用于除2个文件之外的所有文件。对于这些DLL,我从GetVersionInfo()获得了错误的信息。
为了消除所有其他变量,我将此调用提取到一个简单的测试应用程序中,它仍然遇到了同样的问题。但是,如果我将测试应用程序构建为Windows应用程序(最初是控制台应用程序),那么数据会恢复正确。
只是澄清一下,作为控制台应用程序运行时返回的错误数据不仅仅是null信息,就像文件不包含版本数据一样。它包含合理的数据,但只包含错误的数据。就好像是从不同的文件中读取它一样。我找了一个包含匹配版本数据的文件,但找不到。
如果构建为控制台应用程序而不是Windows应用程序,为什么这个简单的调用功能会有所不同?
如果有人可以提供帮助,我将非常感激。
RGDS, 安迪
- 已添加代码
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));
}
}
}
答案 0 :(得分:8)
这种行为确实很奇怪。可能是控制台应用程序没有像WinForms应用程序那样从同一个地方加载DLL吗?这意味着GetVersionInfo
使用的其他API不仅仅是Win32 CreateFile
(可能会通过一些DLL解析器机制,并排或其他);请记住,在version.dll
下,FileVersionInfo
将执行您的请求,而不是CLR本身。
从另一个方向看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;
}
到Reflector点:
GetVersionInfo
正如你在那里看到的,一些有趣的舞蹈正在进行代码页。如果您检查的DLL附加了多个版本信息资源怎么办?根据调用{{1}}的程序的文化,我猜代码页相关的调用可以返回其他结果吗?
花点时间检查DLL的资源,并确保版本信息只有一个语言/代码页。我希望,它可能会指出你的解决方案。
答案 1 :(得分:0)
当然,您所看到的“文件”不是。和..?如果您遍历所有文件,您将始终看到条目。 (当前目录)和..(向上dir)。 GetVersion Info可能会为这些返回任何内容。您必须按名称手动过滤这些条目。
答案 2 :(得分:0)
文件和汇编版本是两个不同的东西。
你确定你不期待对方吗?
答案 3 :(得分:0)
更新:试过这个。没用。
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));
}
}
}