How to Tell if a .NET Assembly Was Compiled as x86, x64 or Any CPU

14,888

Solution 1

If you just want to find this out on a given dll, then you can use the CorFlags tool that is part of the Windows SDK:

CorFlags.exe assembly.dll

If you want to do it using code, take a look at the GetPEKind method of the Module class:

Assembly assembly = Assembly.LoadFrom("path to dll");
PortableExecutableKinds peKind;
ImageFileMachine imageFileMachine;
assembly.ManifestModule.GetPEKind(out peKind, out imageFileMachine)

You then need to examine the peKind to check its value. See the MSDN docs for PortableExecutableKinds for more info.

Solution 2

Thanks Adrian! I've rewritten the snippet in PowerShell so I could use it on the server.

#USAGE #1
# Get-Bitness (dir *.dll | select -first 1)
#USAGE #2
# Get-Bitness "C:\vs\projects\bestprojectever\bin\debug\mysweetproj.dll"
function Get-Bitness([System.IO.FileInfo]$assemblyFile)
{
    $peKinds = new-object Reflection.PortableExecutableKinds
    $imageFileMachine = new-object Reflection.ImageFileMachine
    $a = [Reflection.Assembly]::LoadFile($assemblyFile.Fullname)
    $a.ManifestModule.GetPEKind([ref]$peKinds, [ref]$imageFileMachine)

    return $peKinds
}

Solution 3

Thanks Adrian and Peter! Here's a modified version of Peter's Get-Bitness that 1) takes a list of files to examine from the pipeline, and 2) doesn't die it if looks at a non-.NET DLL (e.g. if it looks at certain C++ DLLs):

# example usage: dir *.exe,*.dll | Get-PEKind
function Get-PEKind {
    Param(
      [Parameter(Mandatory=$True,ValueFromPipeline=$True)]
      [System.IO.FileInfo]$assemblies
    )

    Process {
        foreach ($assembly in $assemblies) {
            $peKinds = new-object Reflection.PortableExecutableKinds
            $imageFileMachine = new-object Reflection.ImageFileMachine
            try
            {
                $a = [Reflection.Assembly]::LoadFile($assembly.Fullname)
                $a.ManifestModule.GetPEKind([ref]$peKinds, [ref]$imageFileMachine)
            }
            catch [System.BadImageFormatException]
            {
                $peKinds = [System.Reflection.PortableExecutableKinds]"NotAPortableExecutableImage"
            }

            $o = New-Object System.Object
            $o | Add-Member -type NoteProperty -name File -value $assembly
            $o | Add-Member -type NoteProperty -name PEKind -value $peKinds
            Write-Output $o
        }
    }
}

I'm new to PowerShell, so this may not be an example of best practices.

Alternatively, according to https://stackoverflow.com/a/4719567/64257 there may also be a handy Get-PEHeader cmdlet in the PowerShell Community Extensions.

Solution 4

C# snippet, based on the Powershell answers:

var modules = assembly.GetModules();
var kinds = new List<PortableExecutableKinds>();
var images = new List<ImageFileMachine>();
foreach (var module in modules)
{
    PortableExecutableKinds peKinds;
    ImageFileMachine imageFileMachine;
    module.GetPEKind(out peKinds, out imageFileMachine);

    kinds.Add(peKinds);
    images.Add(imageFileMachine);
}

var distinctKinds = kinds.Distinct().ToList();
var distinctImages = images.Distinct().ToList();
Share:
14,888
Tim Long
Author by

Tim Long

I am a freelance software developer and IT professional. I trade as Tigra Astronomy and Tigra Networks. As a software developer I currently specialize in producing firmware and Windows software to control astronomical instruments and devices and I have worked with a number of well-known brands that sell equipment to amateur astronomers. Some of the brands I have worked with to produce shipping commercial products include NexDome, Optec, Gemini Telescope Design, AWR Technology, Technical Innovations. I have also produced one-off solutions for several private individuals and institutions. I am a member of the steering group for The ASCOM Initiative which produces standards and interoperability software used by almost all software available to amateur astronomers, and lately some universities and government departments. This work is purely voluntary but highly rewarding, because the impact of ASCOM on amateur astronomy cannot be overestimated. ASCOM was historically Windows-only but is currently undergoing a transformation to a network-centric cross-platform technology. With my IT hat on, I support several organizations with servers, cloud services and CCTV security systems. I am active mainly with arts companies such as Music Theatre Wales and conservation charities such as Thanet Countryside Trust and Pwll Du Cave Management Group, where I am a trustee. I was awarded Microsoft MVP ('Most Valuable Professional') for Windows Small Business Server in 2007, 2008 and 2009. I prefer to develop in C# and try to be an early adopter of the latest tools and techniques, where it makes sense. CodeMentor Twitter @Tim_Long Google+ Facebook LinkedIn timlong

Updated on June 25, 2022

Comments

  • Tim Long
    Tim Long almost 2 years

    What's the easiest way to discover (without access to the source project) whether a .NET assembly DLL was compiled as 'x86', 'x64' or 'Any CPU'?

    Update: A command-line utility was sufficient to meet my immediate needs, but just for the sake of completeness, if someone wants to tell me how to do it programmatically then that would be of interest too, I'm sure.