342 votes

Comment puis-je déterminer si un assemblage .NET a été construit pour x86 ou x64 ?

J'ai une liste arbitraire d'assemblages .NET.

J'ai besoin de vérifier de manière programmatique si chaque DLL a été construite pour x86 (par opposition à x64 ou tout autre CPU). Cela est-il possible ?

0 votes

2 votes

Vous pourriez également vouloir vérifier celui-ci : check-if-unmanaged-dll-is-32-bit-or-64-bit .

2 votes

Dans une version ultérieure de CorFlags, correspondant à .NET 4.5, "32BIT" a été remplacé par "32BITREQ" et "32BITPREF". .

309voto

x0n Points 26002

Regardez System.Reflection.AssemblyName.GetAssemblyName(string assemblyFile)

Vous pouvez examiner les métadonnées de l'assemblage à partir de l'instance AssemblyName retournée :

Utilisation de PowerShell :

\[36\] C:\\> \[reflection.assemblyname\]::GetAssemblyName("${pwd}\\Microsoft.GLEE.dll") | fl

Name                  : Microsoft.GLEE
Version               : 1.0.0.0
CultureInfo           :
CodeBase              : file:///C:/projects/powershell/BuildAnalyzer/...
EscapedCodeBase       : file:///C:/projects/powershell/BuildAnalyzer/...
**ProcessorArchitecture : MSIL**
Flags                 : PublicKey
HashAlgorithm         : SHA1
VersionCompatibility  : SameMachine
KeyPair               :
FullName              : Microsoft.GLEE, Version=1.0.0.0, Culture=neut... 

Ici, ProcesseurArchitecture identifie la plate-forme cible.

  • Amd64 : Un processeur 64 bits basé sur l'architecture x64.
  • Bras : Un processeur ARM.
  • IA64 : Un processeur Intel Itanium 64 bits uniquement.
  • MSIL : Neutre par rapport au processeur et aux bits par mot.
  • X86 : Un processeur Intel 32 bits, en mode natif ou dans l'environnement Windows on Windows sur une plate-forme 64 bits (WOW64).
  • Aucun : Une combinaison inconnue ou non spécifiée de processeur et de bits par mot.

Dans cet exemple, j'utilise PowerShell pour appeler la méthode.

62 votes

Pardonnez ma question stupide, mais qu'est-ce qui vous dit que c'est un x86 ?

54 votes

Le champ ProcessorArchitecture est une énumération ; dans l'exemple ci-dessus, il est défini sur MSIL, ce qui signifie "Neutre en ce qui concerne le processeur et les bits par mot". Les autres valeurs comprennent X86, IA64, Amd64. Voir msdn.microsoft.com/fr/us/library/ pour plus de détails.

1 votes

J'obtiens l'erreur suivante en essayant d'utiliser PowerShell : Exception calling "GetAssemblyName" with "1" argument(s): "Could not load file or assembly '[DLLName].dll' or one of its dependencies. The system cannot find the file specified." (Oui, je l'ai épelé correctement).

227voto

cfeduke Points 13153

Vous pouvez utiliser le CorFlags CLI (par exemple, C:\Program Fichiers \Microsoft SDKs \Windows\v7.0\Bin\CorFlags.exe ) pour déterminer le statut d'un assemblage, en se basant sur sa sortie et en ouvrant un assemblage en tant que bien binaire, vous devriez être capable de déterminer où vous devez chercher pour déterminer si le drapeau 32BIT est mis à 1 ( x86 ) ou 0 ( Toute unité centrale o x64 en fonction de PE ) :

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

Le billet de blog Développement x64 avec .NET a des informations sur corflags .

Encore mieux, vous pouvez utiliser Module.GetPEKind pour déterminer si un assemblage est PortableExecutableKinds valeur PE32Plus (64 bits), Required32Bit (32 bits et WOW), ou ILOnly (n'importe quelle unité centrale) ainsi que d'autres attributs.

1 votes

Après avoir vu votre mise à jour, l'utilisation du GetPEKind semble être la bonne façon de procéder. J'ai marqué la vôtre comme étant la réponse.

0 votes

Excellent conseil concernant Module.GetPEKind, je ne le savais pas jusqu'à présent. J'ai toujours utilisé la fonction corflags outil.

9 votes

GetPEKind échoue dans un processus 64 bits lors de la vérification d'assemblages 32 bits

146voto

JoshL Points 4143

Juste pour clarifier, CorFlags.exe fait partie de l'équipe de la SDK de .NET Framework . J'ai les outils de développement sur ma machine, et le moyen le plus simple pour moi de déterminer si une DLL est uniquement en 32 bits est de :

  1. Ouvrez l'invite de commande Visual Studio (sous Windows : menu Démarrer/Programmes/Microsoft Visual Studio/Visual Studio Tools/Visual Studio 2008 Command Prompt).

  2. CD vers le répertoire contenant la DLL en question

  3. Exécutez corflags comme ceci : corflags MyAssembly.dll

Vous obtiendrez un résultat comme celui-ci :

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  : 3
ILONLY    : 1
32BIT     : 1
Signed    : 0

Selon les commentaires, les drapeaux ci-dessus doivent être lus comme suit :

  • N'importe quelle unité centrale : PE = PE32 et 32BIT = 0
  • x86 : PE = PE32 et 32BIT = 1
  • 64 bits : PE = PE32+ et 32BIT = 0

12 votes

Cela semble avoir changé entre-temps ; corflags affiche maintenant 32BITREQ y 32BITPREF plutôt qu'un seul 32BIT valeur.

1 votes

Microsoft .NET 4.5 a introduit une nouvelle option, Any CPU 32-bit Preferred. Aquí sont les détails.

0 votes

Le "Visual Studio Command Prompt" est aujourd'hui appelé " Invite de commande du développeur Visual Studio 2019 ".

22voto

Jason Points 91

Et si vous écriviez simplement le vôtre ? Le cœur de l'architecture PE n'a pas été sérieusement modifié depuis son implémentation dans Windows 95. Voici un exemple en 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;
    }
}

Maintenant les constantes actuelles sont :

0x10B - PE32  format.
0x20B - PE32+ format.

Mais avec cette méthode, il est possible de créer de nouvelles constantes, il suffit de valider le retour comme bon vous semble.

1 votes

Intéressant, merci pour le code avec l'explication. Module.GetPEKind est probablement le chemin le plus facile. Mais cela est utile pour l'apprentissage. Merci.

3 votes

Très intéressant mais quand j'ai une application compilée avec Any CPU, le résultat est 0x10B. C'est faux car mon application est exécutée dans un système x64. Y a-t-il un autre drapeau à vérifier ?

0 votes

GetPEArchitecture fonctionne pour les assemblages compilés avec .net 3.5, 4.0, 4.5 et 4.5.1 ? Quoi qu'il en soit, je pense que Module.GetPEKind échoue dans un processus 64 bits lors de la vérification d'assemblages 32 bits.

9voto

Ludwo Points 3166

Essayez d'utiliser CorFlagsReader de ce projet à CodePlex . Il ne contient aucune référence à d'autres assemblages et peut être utilisé tel quel.

1 votes

C'est la réponse la plus précise et la plus utile.

0 votes

Le lien fonctionne toujours au moment où nous écrivons ces lignes, mais comme CodePlex est sur le point d'être fermé, il serait bon de prendre les mesures appropriées avant qu'il ne soit trop tard.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X