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

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


当前回答

试着在CodePlex中使用这个项目中的CorFlagsReader。它没有对其他程序集的引用,可以按原样使用。

其他回答

[TestMethod]
public void EnsureKWLLibrariesAreAll64Bit()
{
    var assemblies = Assembly.GetExecutingAssembly().GetReferencedAssemblies().Where(x => x.FullName.StartsWith("YourCommonProjectName")).ToArray();
    foreach (var assembly in assemblies)
    {
        var myAssemblyName = AssemblyName.GetAssemblyName(assembly.FullName.Split(',')[0] + ".dll");
        Assert.AreEqual(ProcessorArchitecture.MSIL, myAssemblyName.ProcessorArchitecture);
    }
}

下面是一个批处理文件,它将针对当前工作目录和所有子目录中的所有DLL文件和EXE文件运行corflags.exe,解析结果并显示每个目标体系结构。

Depending on the version of corflags.exe that is used, the line items in the output will either include 32BIT, or 32BITREQ (and 32BITPREF). Whichever of these two is included in the output is the critical line item that must be checked to differentiate between Any CPU and x86. If you are using an older version of corflags.exe (pre Windows SDK v8.0A), then only the 32BIT line item will be present in the output, as others have indicated in past answers. Otherwise 32BITREQ and 32BITPREF replace it.

这假设corflags.exe在%PATH%. exe文件中。确保这一点的最简单方法是使用开发人员命令提示符。或者,您也可以从默认位置复制它。

如果下面的批处理文件是针对一个非托管DLL或EXE文件运行的,它将错误地显示为x86,因为Corflags.exe的实际输出将是一个类似于:

CF008:指定的文件没有有效的托管头

@echo off

echo.
echo Target architecture for all exes and dlls:
echo.

REM For each exe and dll in this directory and all subdirectories...
for %%a in (.exe, .dll) do forfiles /s /m *%%a /c "cmd /c echo @relpath" > testfiles.txt

for /f %%b in (testfiles.txt) do (
    REM Dump corflags results to a text file
    corflags /nologo %%b > corflagsdeets.txt

   REM Parse the corflags results to look for key markers
   findstr /C:"PE32+">nul .\corflagsdeets.txt && (
      REM `PE32+` indicates x64
        echo %%~b = x64
    ) || (
      REM pre-v8 Windows SDK listed only "32BIT" line item,
      REM newer versions list "32BITREQ" and "32BITPREF" line items
        findstr /C:"32BITREQ  : 0">nul /C:"32BIT     : 0" .\corflagsdeets.txt && (
            REM `PE32` and NOT 32bit required indicates Any CPU
            echo %%~b = Any CPU
        ) || (
            REM `PE32` and 32bit required indicates x86
            echo %%~b = x86
        )
    )

    del corflagsdeets.txt
)

del testfiles.txt
echo.

我喜欢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或任何其他版本:

还有一种方法是在DLL上使用Visual Studio工具中的dumpbin,并寻找适当的输出:

dumpbin.exe /HEADERS <your DLL file path>
    FILE HEADER VALUE
                 14C machine (x86)
                   4 number of sections
            5885AC36 time date stamp Mon Jan 23 12:39:42 2017
                   0 file pointer to symbol table
                   0 number of symbols
                  E0 size of optional header
                2102 characteristics
                       Executable
                       32 bit word machine
                       DLL

注意:上面的输出是一个32位DLL文件

dumpbin.exe的一个更有用的选项是/EXPORTS。它将显示DLL文件公开的函数

dumpbin.exe /EXPORTS <PATH OF THE DLL FILE>

查看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来调用该方法。