"Une tentative a été faite pour charger un programme avec un format incorrect" même lorsque les plates-formes sont les mêmes

461

J'appelle des fonctions à partir d'une DLL non gérée 32 bits sur un système 64 bits. Ce que je reçois est:

BadImageFormatException: une tentative de chargement d'un programme avec un format incorrect a été effectuée. (Exception de HRESULT: 0x8007000B)

Au début, j'avais mes projets définis sur la plate-forme Any CPU, je les ai donc tous deux modifiés en x86, mais cette erreur se produit toujours. C'est vraiment le seul correctif que je connais pour cela.

Les DLL ne sont pas corrompues ou quoi que ce soit, car je peux les utiliser avec d'autres programmes (dont je n'ai pas la source). Je pensais que ce n'était peut-être pas une dépendance, mais j'ai vérifié et ils sont tous là. De plus, ne serait-ce pas jeter un DllNotFoundExceptiondans ce cas?

Que puis-je faire d'autre? Et avant de dire "Utilisez une DLL 64 bits non gérée à la place", permettez-moi de souligner qu'il n'y en a pas. ;)

David Brown
la source
1
Quels projets avez-vous modifiés pour x86? Et comment les exécutez-vous lorsque vous obtenez l'exception, via le débogueur ou manuellement? Si ce dernier, avez-vous remarqué que lorsque vous êtes passé à x86, vous avez obtenu un nouveau dossier dans votre répertoire bin \? C'est fondamentalement maintenant bin \ x86 \ Debug pour les fichiers.
Lasse V. Karlsen du
Pouvez-vous vérifier que l'exécutable s'exécute en mode 32 bits (* 32 dans le gestionnaire de processus)?
JP Alioto
@Lasse V. Karlsen: Oui, j'ai supprimé le bit x86 du chemin de sortie lorsque j'ai changé de plate-forme dans chaque projet. Mon premier projet est une DLL qui encapsule les fonctions dans la DLL non managée. Le deuxième projet est un exécutable qui utilise l'encapsuleur dans la première DLL. Les deux sont définis sur x86.
David Brown
@JP: En fait, le gestionnaire de processus ne montre pas qu'il s'exécute en tant que processus 32 bits. Pourquoi donc?
David Brown

Réponses:

532

Si vous essayez d'exécuter des applications 32 bits sur IIS 7 (et / ou un système d'exploitation 64 bits), vous obtiendrez la même erreur. Donc, depuis IIS 7, faites un clic droit sur le pool d'applications des applications et allez dans "Paramètres avancés" et changez "Activer les applications 32 bits" en "VRAI".

Redémarrez votre site Web et cela devrait fonctionner.

entrez la description de l'image ici

bluwater2001
la source
1
Oh mes jours, je cherchais à installer des composants IIS supplémentaires quand c'était la réponse ... Quelqu'un peut-il suggérer un inconvénient à avoir cette option sélectionnée?
notidaho
3
Voici une bonne discussion sur la question des performances à ce sujet: stackoverflow.com/questions/507820/…
Ben Power
J'ai un problème avec SharpSvn et cela n'aide pas. :( Sth est très mal avec cet assemblage, je vous le dis ...
user2173353
4
Cette réponse est un wtf pour moi, car la question ne mentionne pas du tout IIS!
kristianp
129

D'une manière ou d'une autre, la case à cocher Générer dans le Gestionnaire de configuration n'avait pas été cochée pour mon exécutable, donc il fonctionnait toujours avec l'ancienne génération Any CPU. Après avoir corrigé cela, Visual Studio s'est plaint qu'il ne pouvait pas déboguer l'assembly, mais cela a été corrigé avec un redémarrage.

David Brown
la source
Merci beaucoup. Cela m'a aussi. Version vérifiée dans Configuration Manager et maintenant cela fonctionne (application de bureau WPF).
danglund
1
Si vous avez fait tout ce qui précède et vérifié les paramètres de votre plate-forme, créez les paramètres de configuration, nettoyez la solution et cela ne fonctionne toujours pas - recherchez toutes les instances de la DLL et supprimez-les.
Will Calderwood
avec VS 2015, cela est toujours valable - même si je n'ai pas eu besoin de redémarrer :)
increddibelly
C'est ça! Revisitez vos paramètres Configuration Manager est la réponse.
AndyUK
74

Dans Visual Studio , cliquez avec le bouton droit sur votre projet -> Dans le volet gauche, cliquez sur l' onglet Générer ,

Propriétés du projet, onglet de construction

sous Platform Target, sélectionnez x86 (ou plus généralement l' architecture à associer à la bibliothèque à laquelle vous liez)

Propriétés du projet, plate-forme cible

J'espère que ça aidera quelqu'un! :)

Marvin Thobejane
la source
2
Cela a résolu mon problème dans VS2013, j'ai trouvé un autre correctif consistant à laisser «Plate-forme cible» comme «Tout processeur» mais cochez la case «Préférer 32 bits».
user1069816
2
Bien que vous deviez utiliser .NET 4.5 ou supérieur pour pouvoir cocher la case "Préférer 32 bits"
user1069816
1
Oui, mais j'ai converti mon projet dans 'Any CPU' en 'x64'. Mon projet 32 ​​bits fonctionne correctement, mais le même code que j'ai converti en 64 bits, ce projet ne fonctionne pas correctement en 32 bits. Pouvez-vous s'il vous plaît me donner le processus de conversion 64 bits approprié ...
Ismayil S
@IsmayilS assurez-vous que vous utilisez une version 64 bits de la bibliothèque à laquelle vous vous
connectez
53

J'ai juste eu ce problème aussi. J'ai essayé toutes les suggestions ici, mais elles n'ont pas aidé.

J'ai trouvé une autre chose à vérifier qui l'a corrigé pour moi. Dans Visual Studio, cliquez avec le bouton droit sur le projet et ouvrez "Propriétés". Cliquez sur l'onglet "Compiler" (ou "Créer") puis cliquez sur "Options de compilation avancées" en bas.

Vérifiez la liste déroulante "CPU cible". Il doit correspondre à la «plate-forme» que vous construisez. Autrement dit, si vous construisez "Any CPU" alors "Target CPU" devrait dire "Any CPU". Parcourez toutes vos plateformes en les rendant actives et vérifiez ce paramètre.

Denis
la source
2
Et pour ceux d'entre nous qui utilisent le compilateur, ma solution a été d'ajouter "/ platform: x86" aux drapeaux du compilateur.
Urchin
Cela me l'a également corrigé. J'ai dû ajuster la "cible de plate-forme" sur l'onglet "Build".
Jowen
si vous êtes sur 64 bits, cochez également le drapeau "prefer 32 bits". J'ai dû le désactiver pour moi.
N4ppeL
51

Si vous rencontrez cette erreur lorsque vous cliquez sur le bouton fléché vert pour exécuter l'application, mais que vous souhaitez toujours exécuter l'application en 64 bits. Vous pouvez le faire dans VS 2013, 2015, 2017 et 2019

Accédez à: Outils> Options> Projets et solutions> Projets Web> Utilisez la version 64 bits d'IIS Express

paibamboo
la source
3
Merci. J'en ai essayé tellement et rien n'a aidé. Tu es mon sauveur de vie. J'ai un système d'exploitation 64 bits, j'ai installé un Visual Studio 64 bits [qui fonctionne toujours en 32 bits pour une raison inconnue]. Lorsque j'ai mis ma cible de plate-forme à x64, elle générait une erreur BadImageFormatException. Avec votre correctif, cela a fonctionné. Je t'ai donné un vote positif. You rock
SKCS Kamal
Je suis content d'avoir pu aider :)
paibamboo
C'est la réponse dont j'ai besoin. Merci beaucoup!
yushulx
Merci beaucoup, cela a résolu le problème. Il fonctionne bien avec le processus Visual Studio 2017 32 bits.
samir105
1
fonctionne toujours avec VS 2019, merci
Jake Gaston
36

Si vous utilisez un processeur , vous pouvez rencontrer ce problème si l' option Préférer 32 bits est cochée:

Assurez-vous de décocher cette option dans l' onglet Build de la propriété du projet !

entrez la description de l'image ici

Drew Noakes
la source
3
Il serait utile d'indiquer où dans Visual Studio trouver cette option.
trysis
@trysis, cette option se trouve dans la page Build du volet des paramètres du projet.
Drew Noakes
1
Je disais qu'il serait utile de l'inclure. Dans l'état actuel de cette réponse, il n'y a pas de contexte pour dire à l'infortuné, peut-être nouvel utilisateur de StackOverflow, où le trouver.
trysis
Quel est le chemin pour obtenir ce formulaire? Je ne le trouve pas
Adolfo Correa
Dans Visual Studio, cliquez avec le bouton droit sur le projet et choisissez «Propriétés».
Drew Noakes du
8

Un peu hors sujet pour ce post, mais la recherche de ce message d'erreur m'a amené ici.

Si vous générez via le système d'équipe et que vous obtenez cette erreur, l'onglet de processus de définition de génération a un paramètre «MSBuild Platform». Si ce paramètre est défini sur "Auto", vous pouvez rencontrer ce problème. Le changer en "X86" peut également résoudre l'erreur.

StingyJack
la source
c'est la réponse la plus proche de ce que je vivais. J'avais une DLL qui devait être x86. Je l'ai utilisé dans un autre projet, AnyCPU par défaut. Ils ont juste besoin de correspondre. Dans ce cas, cela n'a pas fait beaucoup de différence, j'ai donc changé le nouveau projet en x86.
Greg
8

Dans mon cas, j'utilisais une DLL native en C #. Cette DLL dépendait de quelques autres DLL manquantes. Une fois ces autres DLL ajoutées, tout a fonctionné.

Tomasz Stypich
la source
4

S'appuyant sur la réponse de @paibamboo

Il a dit: Allez dans: Outils> Options> Projets et solutions> Projets Web> Utilisez la version 64 bits d'IIS Express

Mon collègue a fait cocher cette case (il l'a explicitement recherchée), mais avait le message d'erreur en question. Au bout de quelques heures, il décocha la case et la vérifia de nouveau. Et voilà: le code a maintenant fonctionné avec succès.

Il semble qu'il y ait deux endroits où l'état de cette boîte est enregistré et qui ne sont plus synchronisés. Le décocher et le revérifier le synchronise à nouveau.

Question pour les utilisateurs plus avertis: Y a-t-il eu une mise à jour ou quelque chose la semaine dernière (pour VS 2015) qui a désynchronisé les états?

MilConDoin
la source
3

Voir également cette réponse , qui a résolu le même problème pour moi.

Publié par Luis Mack le 5/12/2010 à 8:50 J'ai trouvé le même problème, uniquement pour un projet spécifique lors de la compilation sur une machine 64 bits. Un correctif qui semble fonctionner consiste à modifier manuellement un caractère dans le flux d'image CHAQUE FOIS que le contrôle utilisateur ou le formulaire est modifié dans le concepteur.

 AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w

Remplacer par

 AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w

Soit 00LjAuMC4w à 0yLjAuMC4w à la fin de la ligne (00 à 0y)

Shaul Behr
la source
1
Un bref résumé du lien serait utile @Shaul :)
Marvin Thobejane
Magnifique. Merci, le briefing ajoute du contenu à votre commentaire
Marvin Thobejane
2

Dans mon cas, j'utilise un minuscule .exe qui recharge les DLL référencées via Reflection. Je fais donc juste ces étapes qui me sauvent la journée:

À partir des propriétés du projet sur l'explorateur de solutions, dans l'onglet de construction, je choisis la cible cible depuis x86

asdf_enel_hak
la source
2

Dans mon cas, j'exécutais des tests via MSTest et j'ai découvert que je déployais à la fois une DLL 32 bits et 64 bits dans le répertoire de test. Le programme favorisait la DLL 64 bits et provoquait son échec.

TL; DR Assurez-vous de ne déployer que des DLL 32 bits pour les tests.

Mike Cluck
la source
2

Nous avons eu un problème similaire et nous avons réussi à le résoudre en définissant la cible de la plate-forme sur x86. Propriétés du projet-> build

Joe
la source
Les dll x86 sont donc différents de x64? Existe-t-il un moyen de détecter cela sur un fichier DLL référencé?
NoBugs
@NoBugs On dirait que vous le pouvez. Jetez un oeil à ce fil
Joe
1

J'ai résolu ce problème de la manière «Windows». Après avoir vérifié tous mes paramètres, nettoyé et reconstruit la solution, je ferme simplement la solution et la rouvre. Ensuite, cela a fonctionné, donc VS ne s'est probablement pas débarrassé de certaines choses pendant le nettoyage. Lorsque les solutions logiques ne fonctionnent pas, je me tourne généralement vers des solutions illogiques (ou apparemment illogiques). Windows ne me laisse pas tomber. :)

user1771386
la source
1

J'ai pu résoudre ce problème en faisant correspondre ma version de build à la version .NET sur le serveur.

J'ai double-cliqué sur le .exe juste pour voir ce qui se passerait et il m'a dit d'installer la 4.5 ...

J'ai donc rétrogradé à 4.0 et cela a fonctionné!

Assurez-vous donc que vos versions correspondent. Il a bien fonctionné sur ma boîte de développement, mais le serveur avait une version .NET plus ancienne.

Nateous
la source
1

Dans mon cas, le contenu du fichier était incorrect. La DLL a été téléchargée à partir du Web, mais le contenu de la DLL était une page HTML: D Essayez de vérifier s'il s'agit d'un fichier binaire, s'il semble correct DLL :)

Ludwo
la source
1

Nous avions le même problème dans .NET core. La solution était de télécharger le runtime .netcore 32 bits et d'avoir la cible de votre projetx86

Dans votre csprojfichier ajoutez

  <PropertyGroup>
    <PlatformTarget>x86</PlatformTarget>  
  </PropertyGroup>

  <PropertyGroup>
    <RunCommand Condition="'$(PlatformTarget)' == 'x86'">$(MSBuildProgramFiles32)\dotnet\dotnet</RunCommand>    
  </PropertyGroup>

Cela a été utilisé pour une machine Windows, vous devrez ajuster les chemins et autres pour Linux / OSX

Samir Banjanovic
la source
0

Si vous importez une DLL non managée, utilisez

CallingConvention = CallingConvention.Cdecl 

dans votre méthode d'importation de DLL.

Ramkumar Shanmugam
la source
0

1: Accédez à: Outils> Options> Projets et solutions> Projets Web> Utilisez la version 64 bits d'IIS Express 2: modifiez le paramètre ci-dessous pour le projet de service Web. entrez la description de l'image ici

Mani
la source