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 ?
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 ?
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.
Dans cet exemple, j'utilise PowerShell pour appeler la méthode.
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.
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).
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.
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.
Excellent conseil concernant Module.GetPEKind, je ne le savais pas jusqu'à présent. J'ai toujours utilisé la fonction corflags
outil.
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 :
Ouvrez l'invite de commande Visual Studio (sous Windows : menu Démarrer/Programmes/Microsoft Visual Studio/Visual Studio Tools/Visual Studio 2008 Command Prompt).
CD vers le répertoire contenant la DLL en question
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 :
Cela semble avoir changé entre-temps ; corflags affiche maintenant 32BITREQ
y 32BITPREF
plutôt qu'un seul 32BIT
valeur.
Microsoft .NET 4.5 a introduit une nouvelle option, Any CPU 32-bit Preferred. Aquí sont les détails.
Le "Visual Studio Command Prompt" est aujourd'hui appelé " Invite de commande du développeur Visual Studio 2019 ".
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.
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.
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 ?
Essayez d'utiliser CorFlagsReader de ce projet à CodePlex . Il ne contient aucune référence à d'autres assemblages et peut être utilisé tel quel.
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.
0 votes
Duplication possible de Comment puis-je déterminer pour quelle plate-forme un exécutable est compilé ?
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". .
0 votes
Comment déterminer si un assemblage .NET a été conçu pour x86 ou x64 ?