How can I programmatically tell in C# if an unmanaged dll is x86 or x64?
Check this out: How to find if native dll is compiled as x64 or x86?
Lazarus, thanks for link, it pointed me to the specs I needed. In case others are looking, here's a basic implementation:
public static MachineType GetDllMachineType(string dllPath)
{
//see http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx
//offset to PE header is always at 0x3C
//PE header starts with "PE\0\0" = 0x50 0x45 0x00 0x00
//followed by 2-byte machine type field (see document above for enum)
FileStream fs = new FileStream(dllPath, FileMode.Open);
BinaryReader br = new BinaryReader(fs);
fs.Seek(0x3c, SeekOrigin.Begin);
Int32 peOffset = br.ReadInt32();
fs.Seek(peOffset, SeekOrigin.Begin);
UInt32 peHead = br.ReadUInt32();
if(peHead!=0x00004550) // "PE\0\0", little-endian
throw new Exception("Can't find PE header");
MachineType machineType = (MachineType) br.ReadUInt16();
br.Close();
fs.Close();
return machineType;
}
The MachineType
enum is defined as:
public enum MachineType : ushort
{
IMAGE_FILE_MACHINE_UNKNOWN = 0x0,
IMAGE_FILE_MACHINE_AM33 = 0x1d3,
IMAGE_FILE_MACHINE_AMD64 = 0x8664,
IMAGE_FILE_MACHINE_ARM = 0x1c0,
IMAGE_FILE_MACHINE_EBC = 0xebc,
IMAGE_FILE_MACHINE_I386 = 0x14c,
IMAGE_FILE_MACHINE_IA64 = 0x200,
IMAGE_FILE_MACHINE_M32R = 0x9041,
IMAGE_FILE_MACHINE_MIPS16 = 0x266,
IMAGE_FILE_MACHINE_MIPSFPU = 0x366,
IMAGE_FILE_MACHINE_MIPSFPU16 = 0x466,
IMAGE_FILE_MACHINE_POWERPC = 0x1f0,
IMAGE_FILE_MACHINE_POWERPCFP = 0x1f1,
IMAGE_FILE_MACHINE_R4000 = 0x166,
IMAGE_FILE_MACHINE_SH3 = 0x1a2,
IMAGE_FILE_MACHINE_SH3DSP = 0x1a3,
IMAGE_FILE_MACHINE_SH4 = 0x1a6,
IMAGE_FILE_MACHINE_SH5 = 0x1a8,
IMAGE_FILE_MACHINE_THUMB = 0x1c2,
IMAGE_FILE_MACHINE_WCEMIPSV2 = 0x169,
}
I only needed three of these, but I included them all for completeness. Final 64-bit check:
// returns true if the dll is 64-bit, false if 32-bit, and null if unknown
public static bool? UnmanagedDllIs64Bit(string dllPath)
{
switch (GetDllMachineType(dllPath))
{
case MachineType.IMAGE_FILE_MACHINE_AMD64:
case MachineType.IMAGE_FILE_MACHINE_IA64:
return true;
case MachineType.IMAGE_FILE_MACHINE_I386:
return false;
default:
return null;
}
}
Even easier: check out the System.Reflection.Module class. It includes the GetPEKind method, which returns 2 enums that describe the type of code and the CPU target. No more hex!
(the rest of this very informative post was copied shamelessly from http://www.developersdex.com/vb/message.asp?p=2924&r=6413567)
Sample code:
Assembly assembly = assembly.loadfile(@"<assembly Path>");
PortableExecutableKinds kinds;
ImageFileMachine imgFileMachine;
assembly.ManifestModule.GetPEKind(out kinds, out imgFileMachine);
PortableExecutableKinds can be used to check what kind of the assembly. It has 5 values:
ILOnly: The executable contains only Microsoft intermediate language (MSIL), and is therefore neutral with respect to 32-bit or 64-bit platforms.
NotAPortableExecutableImage: The file is not in portable executable (PE) file format.
PE32Plus: The executable requires a 64-bit platform.
Required32Bit: The executable can be run on a 32-bit platform, or in the 32-bit Windows on Windows (WOW) environment on a 64-bit platform.
Unmanaged32Bit: The executable contains pure unmanaged code.
Following are the links:
Module.GetPEKind Method: http://msdn.microsoft.com/en-us/library/system.reflection.module.getpekind.a spx
PortableExecutableKinds Enumeration: http://msdn.microsoft.com/en-us/library/system.reflection.portableexecutable kinds(VS.80).aspx
ImageFileMachine Enumeration: http://msdn.microsoft.com/en-us/library/system.reflection.imagefilemachine.a spx
Hi All,
I am getting exception on the below line when i am trying to find whether the lib is x86 or x64... UInt32 peHead = br.ReadUInt32();
Is i need to do some chnages for the library files
Using a Visual Studio command prompt, dumpbin /headers dllname.dll works too. On my machine the beginning of the output stated:
FILE HEADER VALUES
8664 machine (x64)
5 number of sections
47591774 time date stamp Fri Dec 07 03:50:44 2007