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



5 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). Это возможно?




[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);
    }
}



Еще один способ - использовать 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>



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

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

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




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




Как насчет того, что вы просто пишете себя? Ядро архитектуры 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.

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






Related