3

我在 Windows 中有一个 SFX(自解压可执行文件)文件(使用7z, WinRar, .... 等 zip 工具创建),其中包含以下详细信息:

文件详情

我想CopyRight在 C# 中获取文本,所以我编写了以下代码:

var fileVersionInfo = FileVersionInfo.GetVersionInfo(filePath);
Console.Write(fileVersionInfo.LegalCopyright)

fileVersionInfo.LegalCopyright总是空的!有什么问题?

编辑:
我的原始代码:

var fileVersionInfo = FileVersionInfo.GetVersionInfo(filePath1);
var properties = typeof(FileVersionInfo).GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (var propertyInfo in properties)
{
    var value = propertyInfo.GetValue(fileVersionInfo);
    Console.WriteLine("{0} = {1}", propertyInfo.Name, value);
}
Console.ReadKey();

结果:

文件详情

4

3 回答 3

5

(我的声誉太低,无法发表评论,所以我在这里发布)

我刚刚测试了以下代码,它对我来说正常工作。

var fileVersionInfo = FileVersionInfo.GetVersionInfo(@"C:\Users\usr\Desktop\Game\steamIntegration\steam_api.dll");
Console.Write(fileVersionInfo.LegalCopyright);
Console.ReadLine();

也许您的权限不足以容纳该文件。将 *.manifest 添加到您的项目中,将 requestedExecutionLevel 更改为:

<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />

也许这可以解决你的问题。

于 2017-01-17T08:04:08.850 回答
1

GetVersionInfoForCodePage您观察到的行为是由于Microsoft.NET 框架类的第 411 行中私有函数的实现存在缺陷FileVersionInfo,当前版本为4.6.2并且可能更早:

// fileVersion is chosen based on best guess. Other fields can be used if appropriate. 
return (fileVersion != string.Empty);

来自参考源的引用(评论他们的)意味着该函数将放弃一个正确猜测的代码页特定版本信息,如果它的fileVersion成员是空的(块的成员,而不是标题中的那个,这会增加混乱)。

您的 exe 文件就是这种情况:

ResHacker 显示的版本信息

当我们修补框架以使用它时......

return (productVersion != string.Empty);

...它按预期工作(在控制台和 Windows 应用程序中测试):

补丁版本的输出

所以有两个选择:

  1. 编译 exe,使其 FileVersion 不会为空。希望不传输此信息不是您的压缩工具的错。
  2. 向 Microsoft 提交错误。我从他们的参考源许可证中收集到的内容,它不允许在任何产品中包含派生作品。
于 2017-01-26T12:05:30.007 回答
1

最后我可以找到一个解决方案:
1.首先安装以下包:

Microsoft.WindowsAPICodePack.Shell

它有一个依赖包,Nuget自动安装它Microsoft.WindowsAPICodePack.Core

2.现在我们可以获取文件属性如下代码

using System;
using System.Reflection;
using Microsoft.WindowsAPICodePack.Shell.PropertySystem;

namespace ConsoleApplication1
{
    internal class Program
    {
        private static void Main()
        {
            const string filePath1 = @"C:\Users\Mohammad\Downloads\Test\.....exe";
            var shellFile = Microsoft.WindowsAPICodePack.Shell.ShellObject.FromParsingName(filePath1);
            foreach (var propertyInfo in typeof(ShellProperties.PropertySystem).GetProperties(BindingFlags.Public | BindingFlags.Instance))
            {
                var shellProperty = propertyInfo.GetValue(shellFile.Properties.System, null) as IShellProperty;
                if (shellProperty?.ValueAsObject == null) continue;
                var shellPropertyValues = shellProperty.ValueAsObject as object[];
                if (shellPropertyValues != null && shellPropertyValues.Length > 0)
                {
                    foreach (var shellPropertyValue in shellPropertyValues)
                        Console.WriteLine("{0} = {1}", propertyInfo.Name, shellPropertyValue);
                }
                else
                    Console.WriteLine("{0} = {1}", propertyInfo.Name, shellProperty.ValueAsObject);
            }
            Console.ReadKey();
        }
    }
}
于 2017-01-27T05:07:41.737 回答