我有一个任意的。net程序集列表。
我需要以编程方式检查每个DLL是否为x86构建(而不是x64或任何CPU)。这可能吗?
我有一个任意的。net程序集列表。
我需要以编程方式检查每个DLL是否为x86构建(而不是x64或任何CPU)。这可能吗?
当前回答
还有一种方法是在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>
其他回答
您可以使用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)以及其他属性。
试着在CodePlex中使用这个项目中的CorFlagsReader。它没有对其他程序集的引用,可以按原样使用。
你自己写就行了。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.
但是用这种方法,它允许新常数的可能性。只要验证你认为合适的返回。
查看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来调用该方法。
我喜欢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或任何其他版本: