我有一个任意的。net程序集列表。

我需要以编程方式检查每个DLL是否为x86构建(而不是x64或任何CPU)。这可能吗?


当前回答

你自己写就行了。PE架构的核心自从在Windows 95中实现以来就没有发生过重大变化。

下面是一个c#的例子:

    public static ushort GetPEArchitecture(string pFilePath)
    {
        ushort architecture = 0;
        try
        {
            using (System.IO.FileStream fStream = new System.IO.FileStream(pFilePath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
            {
                using (System.IO.BinaryReader bReader = new System.IO.BinaryReader(fStream))
                {
                    // Check the MZ signature
                    if (bReader.ReadUInt16() == 23117)
                    {
                        // Seek to e_lfanew.
                        fStream.Seek(0x3A, System.IO.SeekOrigin.Current);

                        // Seek to the start of the NT header.
                        fStream.Seek(bReader.ReadUInt32(), System.IO.SeekOrigin.Begin);

                        if (bReader.ReadUInt32() == 17744) // Check the PE\0\0 signature.
                        {
                            // Seek past the file header,
                            fStream.Seek(20, System.IO.SeekOrigin.Current);

                            // Read the magic number of the optional header.
                            architecture = bReader.ReadUInt16();
                        }
                    }
                }
            }
        }
        catch (Exception) { /* TODO: Any exception handling you want
                                     to do, personally I just take 0
                                     as a sign of failure */
        }

        // If architecture returns 0, there has been an error.
        return architecture;
    }
}

现在的常数是:

0x10B - PE32  format.
0x20B - PE32+ format.

但是用这种方法,它允许新常数的可能性。只要验证你认为合适的返回。

其他回答

澄清一下,CorFlags.exe是. net Framework SDK的一部分。我的机器上有开发工具,对我来说,确定DLL是否仅为32位的最简单方法是:

打开Visual Studio命令提示符(Windows系统:菜单开始/程序/Microsoft Visual Studio/Visual Studio工具/Visual Studio 2008命令提示符) CD到包含有关DLL的目录 像这样运行corflags: corflags MyAssembly.dll

你会得到这样的输出:

Microsoft (R) .NET Framework CorFlags Conversion Tool.  Version  3.5.21022.8
Copyright (c) Microsoft Corporation.  All rights reserved.

Version   : v2.0.50727
CLR Header: 2.5
PE        : PE32
CorFlags  : 3
ILONLY    : 1
32BIT     : 1
Signed    : 0

根据评论,上述标志的解读如下:

任意CPU: PE = PE32, 32BIT = 0 x86: PE = PE32, 32BIT = 1 64位:PE = PE32+, 32BIT = 0

查看System.Reflection.AssemblyName。assemblyFile GetAssemblyName(字符串)。

您可以从返回的AssemblyName实例中检查程序集元数据:

使用PowerShell:

[36] C:\> [reflection.assemblyname]::GetAssemblyName("${pwd}\Microsoft.GLEE.dll") | fl

Name                  : Microsoft.GLEE
Version               : 1.0.0.0
CultureInfo           :
CodeBase              : file:///C:/projects/powershell/BuildAnalyzer/...
EscapedCodeBase       : file:///C:/projects/powershell/BuildAnalyzer/...
ProcessorArchitecture : MSIL
Flags                 : PublicKey
HashAlgorithm         : SHA1
VersionCompatibility  : SameMachine
KeyPair               :
FullName              : Microsoft.GLEE, Version=1.0.0.0, Culture=neut...

在这里,ProcessorArchitecture标识目标平台。

Amd64:基于x64架构的64位处理器。 Arm: Arm处理器。 IA64:仅支持64位Intel Itanium处理器。 MSIL:对于处理器和每字比特数来说是中性的。 X86:一种32位的Intel处理器,本机的或在64位平台(WoW64)上的Windows on Windows环境中。 None:未知或未指定的处理器和每字位数的组合。

在本例中,我使用PowerShell来调用该方法。

前面提到的一个替代工具是Telerik JustDecompile(免费工具),它将在程序集名称旁边显示信息:

检查.NET程序集的目标平台的另一种方法是使用.NET Reflector检查程序集…

@ # ~ #€~ !我刚刚意识到新版本不是免费的!因此,更正一下,如果你有一个。net reflector的免费版本,你可以用它来检查目标平台。

我喜欢ILSpy工具。它不仅显示了架构,还显示了目标框架:

// linq2db, Version=3.0.0.0, Culture=neutral, PublicKeyToken=e41013125f9e410a
// Global type: <Module>
// Architecture: AnyCPU (64-bit preferred)
// Runtime: v4.0.30319
// This assembly is signed with a strong name key.
// This assembly was compiled using the /deterministic option.
// Hash algorithm: SHA1

因此,可以确定它是。net Core 2.1, .NET Framework 4.6或任何其他版本: