我有一个任意的。net程序集列表。
我需要以编程方式检查每个DLL是否为x86构建(而不是x64或任何CPU)。这可能吗?
我有一个任意的。net程序集列表。
我需要以编程方式检查每个DLL是否为x86构建(而不是x64或任何CPU)。这可能吗?
当前回答
前面提到的一个替代工具是Telerik JustDecompile(免费工具),它将在程序集名称旁边显示信息:
其他回答
一个更通用的方法-使用文件结构来确定位和图像类型:
public static CompilationMode GetCompilationMode(this FileInfo info)
{
if (!info.Exists)
throw new ArgumentException($"{info.FullName} does not exist");
var intPtr = IntPtr.Zero;
try
{
uint unmanagedBufferSize = 4096;
intPtr = Marshal.AllocHGlobal((int)unmanagedBufferSize);
using (var stream = File.Open(info.FullName, FileMode.Open, FileAccess.Read))
{
var bytes = new byte[unmanagedBufferSize];
stream.Read(bytes, 0, bytes.Length);
Marshal.Copy(bytes, 0, intPtr, bytes.Length);
}
// Check DOS header magic number
if (Marshal.ReadInt16(intPtr) != 0x5a4d)
return CompilationMode.Invalid;
// This will get the address for the WinNT header
var ntHeaderAddressOffset = Marshal.ReadInt32(intPtr + 60);
// Check WinNT header signature
var signature = Marshal.ReadInt32(intPtr + ntHeaderAddressOffset);
if (signature != 0x4550)
return CompilationMode.Invalid;
// Determine file bitness by reading magic from IMAGE_OPTIONAL_HEADER
var magic = Marshal.ReadInt16(intPtr + ntHeaderAddressOffset + 24);
var result = CompilationMode.Invalid;
uint clrHeaderSize;
if (magic == 0x10b)
{
clrHeaderSize = (uint)Marshal.ReadInt32(intPtr + ntHeaderAddressOffset + 24 + 208 + 4);
result |= CompilationMode.Bit32;
}
else if (magic == 0x20b)
{
clrHeaderSize = (uint)Marshal.ReadInt32(intPtr + ntHeaderAddressOffset + 24 + 224 + 4);
result |= CompilationMode.Bit64;
}
else return CompilationMode.Invalid;
result |= clrHeaderSize != 0
? CompilationMode.CLR
: CompilationMode.Native;
return result;
}
finally
{
if (intPtr != IntPtr.Zero)
Marshal.FreeHGlobal(intPtr);
}
}
编译模式枚举
[Flags]
public enum CompilationMode
{
Invalid = 0,
Native = 0x1,
CLR = Native << 1,
Bit32 = CLR << 1,
Bit64 = Bit32 << 1
}
源代码和解释在GitHub。
[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);
}
}
您可以使用CorFlags命令行工具(例如,C:\Program Files\Microsoft sdk \Windows\v7.0\Bin\CorFlags.exe)来确定程序集的状态,根据其输出并将程序集作为二进制资产打开,您应该能够确定您需要在哪里查找,以确定32位标志是否设置为1 (x86)或0(任何CPU或x64,取决于PE):
Option | PE | 32BIT
----------|-------|---------
x86 | PE32 | 1
Any CPU | PE32 | 0
x64 | PE32+ | 0
博客文章x64 Development with . net有一些关于corflags的信息。
更好的是,您可以使用Module。GetPEKind来确定程序集是否为portableexecutabletypes值PE32Plus(64位)、Required32Bit(32位和WoW)或ILOnly(任何CPU)以及其他属性。
一个工具是sigcheck:
sigcheck c:\Windows\winhlp32.exe
输出:
Sigcheck v2.71 - File version and signature viewer
Copyright (C) 2004-2018 Mark Russinovich
Sysinternals - www.sysinternals.com
c:\windows\winhlp32.exe:
Verified: Signed
Signing date: 20:05 02.05.2022
Publisher: Microsoft Windows
Company: Microsoft Corporation
Description: Windows Winhlp32 Stub
Product: Microsoft® Windows® Operating System
Prod version: 10.0.19041.1
File version: 10.0.19041.1 (WinBuild.160101.0800)
MachineType: 32-bit
sigcheck -nobanner c:\Windows\HelpPane.exe
输出:
c:\windows\HelpPane.exe:
Verified: Signed
Signing date: 00:42 23.04.2022
Publisher: Microsoft Windows
Company: Microsoft Corporation
Description: Microsoft Help and Support
Product: Microsoft® Windows® Operating System
Prod version: 10.0.19041.1151
File version: 10.0.19041.1151 (WinBuild.160101.0800)
MachineType: 64-bit
我克隆了一个超级方便的工具,它为Windows资源管理器中的程序集添加了一个上下文菜单项,以显示所有可用的信息:
从release·tebjan/AssemblyInformation下载。