c# - 控制台应用程序中的 FileVersionInfo.GetVersionInfo() 不正确

标签 c# .net console-application system.diagnostics getfileversion

我在使用 FileVersionInfo.GetVersionInfo() 时遇到了一些严重的问题,希望有人能提供帮助。

问题的基本原理是我正在遍历一个文件夹中的所有文件,每个文件都调用 GetVersionInfo()。大约有300个文件。这适用于除 2 个文件之外的所有文件。对于这些 DLL,我从 GetVersionInfo() 返回的信息完全不正确。

为了消除所有其他变量,我将此调用提取到一个简单的测试应用程序中,但它仍然遇到同样的问题。但是,如果我将测试应用程序构建为 Windows 应用程序(它最初是一个控制台应用程序),那么返回的数据是正确的。

澄清一下,当作为控制台应用程序运行时返回的不正确数据不仅仅是空信息,就像您在文件不包含版本数据时会得到的那样。它包含合理的数据,但只是错误的数据。就好像它是从另一个文件中读取它一样。我已查找包含匹配版本数据的文件,但找不到。

如果构建为控制台应用程序而不是 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));
        }
    }
}

最佳答案

这种行为看起来确实很奇怪。可能是控制台应用程序没有从与 WinForms 应用程序相同的位置加载 DLL?这意味着 GetVersionInfo 使用一些其他的 API 而不仅仅是 Win32 CreateFile(可能通过一些 DLL 解析器机制,并排或其他);请记住,在幕后,version.dll 将执行您的请求,而不是 CLR 本身。

通过 Reflector 查看 FileVersionInfo指向另一个方向:

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;
}

如您所见,一些有趣的代码页正在跳动。如果您检查的 DLL 附加了多个版本信息资源怎么办?根据调用 GetVersionInfo 的程序的文化,我猜想与代码页相关的调用可能会返回其他结果?

花点时间检查 DLL 的资源,确保版本信息只有一个语言/代码页。我希望它可能会为您指明解决方案。

关于c# - 控制台应用程序中的 FileVersionInfo.GetVersionInfo() 不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2221598/

相关文章:

C# 基于简单值的 DTO 比较(和 GetHashCode 困境)

c# - 我需要哪些 SOAP/WS-Security/WS-Addressing/etc 来发送这条消息

c# - 通过 .NET/C# 发送传真

c# - 在 .NET 中调用 COM 枚举器的正确方法是什么?

.net - 将依赖项合并到控制台应用程序中

java - 如何在控制台启动时设置数据库连接参数 jar spring-boot app

android - 从 Play 控制台删除应用程序

c# - 我是否必须取消订阅局部变量的匿名事件处理程序?

c# - 如何使用foreach将datagridview记录插入mysql数据库

c# - 如何通过代码创建新的 Microsoft Azure HybridConnection?