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

后端 未结 4 493
星月不相逢
星月不相逢 2020-12-05 17:21

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 com

相关标签:
4条回答
  • 2020-12-05 17:53

    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
    }
    
    0 讨论(0)
  • 2020-12-05 17:58

    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.

    0 讨论(0)
  • 2020-12-05 18:03

    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.

    0 讨论(0)
  • 2020-12-05 18:17

    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();
    
    0 讨论(0)
提交回复
热议问题