Как определить, была ли сборка .NET построена для x86 или x64?


Answers

Вы можете использовать CorFlags CLI CorFlags (например, C: \ Program Files \ Microsoft SDKs \ Windows \ v7.0 \ Bin \ CorFlags.exe), чтобы определить статус сборки на основе ее вывода и открытия сборки как бинарный актив, вы должны иметь возможность определить, где вам нужно определить, установлен ли флаг 32BIT в 1 ( x86 ) или 0 ( любой процессор или x64 , в зависимости от PE ):

Option    | PE    | 32BIT
----------|-------|---------
x86       | PE32  | 1
Any CPU   | PE32  | 0
x64       | PE32+ | 0

Сообщение в блоге x64 Development с .NET содержит некоторую информацию о corflags .

Еще лучше, вы можете использовать Module.GetPEKind чтобы определить, является ли сборка значением PortableExecutableKinds PE32Plus (64-разрядная PE32Plus ), Required32Bit (32-разрядная и WOW) или ILOnly (любой процессор) вместе с другими атрибутами.

Question

У меня есть произвольный список сборников .NET.

Мне нужно программно проверить, была ли построена каждая DLL для x86 (в отличие от x64 или Any CPU). Это возможно?




DotPeek от JetBrians обеспечивает быстрый и простой способ увидеть msil (anycpu), x86, x64




cfeduke отмечает возможность вызова GetPEKind. Это потенциально интересно сделать это от PowerShell.

Здесь, например, это код для командлета, который можно использовать: https://.com/a/16181743/64257

Кроме того, в https://.com/a/4719567/64257 отмечается, что «в расширениях сообщества PowerShell также используется командлет Get-PEHeader, который можно использовать для проверки исполняемых изображений».




Еще один способ - использовать dumpbin из инструментов Visual Studio в DLL и искать соответствующий вывод

dumpbin.exe /HEADERS <your dll 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

Примечание: выше o / p для 32-разрядной dll

Еще один полезный вариант с dumpbin.exe - / EXPORTS, он покажет вам функцию, открытую dll

dumpbin.exe /EXPORTS <PATH OF THE DLL>



Как насчет того, что вы просто пишете себя? Ядро архитектуры 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))
                {
                    if (bReader.ReadUInt16() == 23117) //check the MZ signature
                    {
                        fStream.Seek(0x3A, System.IO.SeekOrigin.Current); //seek to e_lfanew.
                        fStream.Seek(bReader.ReadUInt32(), System.IO.SeekOrigin.Begin); //seek to the start of the NT header.
                        if (bReader.ReadUInt32() == 17744) //check the PE\0\0 signature.
                        {
                            fStream.Seek(20, System.IO.SeekOrigin.Current); //seek past the file header,
                            architecture = bReader.ReadUInt16(); //read the magic number of the optional header.
                        }
                    }
                }
            }
        }
        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.

Но с помощью этого метода он позволяет использовать возможности новых констант, просто подтвердите возврат, как вы сочтете нужным.




[TestMethod]
public void EnsureKWLLibrariesAreAll64Bit()
{
    var assemblies = Assembly.GetExecutingAssembly().GetReferencedAssemblies().Where(x => x.FullName.StartsWith("YourCommonProjectName")).ToArray();
    foreach (var assembly in assemblies)
    {
        var myAssemblyName = AssemblyName.GetAssemblyName(assembly.FullName.Split(',')[0] + ".dll");
        Assert.AreEqual(ProcessorArchitecture.MSIL, myAssemblyName.ProcessorArchitecture);
    }
}