Code example
This is the complete code of a C#
console application that can detect dll
architectures that also includes the ones you wanted.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
MachineType type = GetDllMachineType("path/to/MyAssembly.dll");
if (type.Equals(MachineType.IMAGE_FILE_MACHINE_I386))
{
Console.WriteLine("Dll architecture: x86/32bit");
}
else if (type.Equals(MachineType.IMAGE_FILE_MACHINE_IA64))
{
Console.WriteLine("Dll architecture: x64/64bit");
}
Console.ReadKey();
}
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, FileAccess.Read);
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;
}
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,
}
// 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;
}
}
}
}
Using Corflags...
You wrote about this and, just to know, this will help you to get some information regarding your assembly (dll
) but this is not C#
! this is a tool that can be used in Visual Studio
console.
Just open Visual Studio
console and use this command:
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC>corflags C:/path/to/MyAssembly.dll
This will be the output:
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 : 24
ILONLY : 0
32BIT : 0
Signed : 1
Then, focus on PE:PE32
, this will describe your assembly architecture:
So, according to this...
AnyCPU means -> PE: PE32 -> 32BIT: 0
x86 means -> PE: PE32 -> 32BIT: 1
x64 means -> PE: PE32+ -> 32BIT: 0
The architecture of MyAssembly.dll
is 32bit
Idea...
Well, if you want to simplify all this, an idea could be to create a background process using C#
then in the arguments use the command I gave you above and print the output of PE:XX
to get the assembly architecture and according to that value tell your application what to do.
I just made some research, hope this helps :-)