FileVersionInfo.GetVersionInfo()不正确的控制台应用程序 [英] FileVersionInfo.GetVersionInfo() incorrect in Console Application

查看:280
本文介绍了FileVersionInfo.GetVersionInfo()不正确的控制台应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我收到使用FileVersionInfo.GetVersionInfo()一些严重的怪事,并希望有人也许能够提供帮助。

这个问题的基础是,我通过一个文件夹中的所有文件迭代调用GetVersionInfo()上的每个。有大约300个文件。此工程确定为文件的所有,但2。对于这些DLL我越来越comepletely不正确的信息回程从GetVersionInfo()。

为了消除所有其他变量,我摘录了这一呼吁变成一个简单的测试应用程序,它仍然得到了同样的问题。不过,如果我建的测试程序作为Windows应用程序(这是一个控制台应用程序开始),那么数据回来是正确的。

只是为了澄清,不正确的数据回来运行作为控制台应用程序不是简单地空信息一样,你会得到,如果该文件不包含版本数据时。它包含了合理的数据,而只是错误的数据。这是因为如果它是从一个不同的文件中读取它。我看了对包含匹配的版本数据的文件,但无法找到一个。

为什么这个简单的通话功能不同,如果建成一个控制台应用程序,而不是一个Windows应用程序?

如果任何人都可以帮助这个我将非常感激。

RGDS, 刘德华

- $ C C增加了$

 使用系统;
使用System.Diagnostics程序;

命名空间测试
{
    类节目
    {
        静态无效的主要(字串[] args)
        {
            字符串文件=C:\\ ProblemFile.dll;
            FileVersionInfo版本= FileVersionInfo.GetVersionInfo(文件);
            字符串文件名= version.FileName;
            字符串的文件版本= version.FileVersion;

            Console.WriteLine(的String.Format({0}:{1},文件名,文件版本));
        }
    }
}
 

解决方案

此行​​为似乎不可思议确实如此。难道说控制台应用程序不从的WinForms应用程序不一样的地方加载DLL?这意味着 GetVersionInfo 使用一些其他的API不仅仅是Win32的的CreateFile (也许通过一些DLL解析机制,副作用由方或其他);请记住,在幕后, VERSION.DLL 将执行你的要求,而不是CLR本身。

看着 FileVersionInfo 通过反射点另一个方向尚未:

 公共静态不安全FileVersionInfo GetVersionInfo(字符串文件名)
{
    // ...
    INT fileVersionInfoSize = UnsafeNativeMethods.GetFileVersionInfoSize(文件名,出NUM);
    FileVersionInfo信息=新FileVersionInfo(文件名);
    如果(fileVersionInfoSize!= 0)
    {
        byte []的缓冲区=新的字节[fileVersionInfoSize]
        固定(BYTE * numRef =缓冲区)
        {
            IntPtr的处理=新的IntPtr((无效*)numRef);
            如果(!UnsafeNativeMethods.GetFileVersionInfo(文件名,0,fileVersionInfoSize,新HandleRef(空,手柄)))
            {
                返回信息;
            }
            INT varEntry = GetVarEntry(手柄);
            如果(!info.GetVersionInfoFor codePAGE(手柄,ConvertTo8DigitHex(varEntry)))
            {
                INT [] numArray =新INT [] {0x40904b0,0x40904e4,0x4090000};
                的foreach(在numArray INT num4)
                {
                    如果((num4 = varEntry)及!&安培; info.GetVersionInfoFor codePAGE(手柄,ConvertTo8DigitHex(num4)))
                    {
                        返回信息;
                    }
                }
            }
        }
    }
    返回信息;
}
 

正如你可以看到有一些有趣的舞蹈是怎么回事用code页面。如果你检查了DLL文件必须重视他们几个版本的信息资源?根据程序调用到 GetVersionInfo 的文化,我想这在code页相关的调用可以返回其他结果?

花点时间来检查DLL文件的资源,并确保只有一种语言/ $下的版本信息$ C页面。它可能指向你的解决方案,我希望。

I'm getting some serious weirdness using FileVersionInfo.GetVersionInfo() and was hoping somebody might be able to help.

The basics of the issue is that I am iterating through all the files in a folder calling GetVersionInfo() on each. There are about 300 files. This works ok for all but 2 of the files. For these DLLs I am getting comepletely incorrect info back from GetVersionInfo().

In order to eliminate all other variables, I extracted this call into a simple test app and it still got the same problem. However, if I built the test app as a Windows Application (it was a Console Application initially) then the data came back correct.

Just to clarify, the incorrect data coming back when running as a Console App is not simply null info like you would get if the file didn't contain version data. It contained reasonable data, but just the wrong data. It's as if it's reading it from a different file. I've looked for a file that contains matching version data, but can't find one.

Why is this simple call functioning differently if built as a Console Application rather than a Windows Application?

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

Rgds, Andy

-- Code Added

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

解决方案

This behaviour seems weird indeed. Could it be that the Console application does not load the DLL from the same place as the WinForms application does? This would mean that GetVersionInfo uses some other API than just Win32 CreateFile (maybe going through some DLL resolver mechanism, side-by-side or whatever); remember that under the covers, version.dll will be executing your request, not the CLR itself.

Looking at FileVersionInfo through Reflector points in another direction yet:

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, some interesting dance is going on with code pages. What if the DLLs you inspected had several version information resources attached to them? Depending on the culture of the program calling into GetVersionInfo, I guess that the code page related calls could return other results?

Take the time to check the resources of the DLLs and make sure that there is only one language/code page for the version information. It might point you at the solution, I hope.

这篇关于FileVersionInfo.GetVersionInfo()不正确的控制台应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆