Impossible de charger la DLL (le module est introuvable HRESULT: 0x8007007E)

113

J'ai une bibliothèque de dll avec un code API C ++ non managé que je dois utiliser dans mon application .NET 4.0. Mais chaque méthode que j'essaie de charger ma dll j'obtiens une erreur:

Impossible de charger la DLL «MyOwn.dll»: le module spécifié est introuvable. (Exception de HRESULT: 0x8007007E)

J'ai lu et essayé plusieurs solutions que j'ai trouvées sur Internet. Rien ne fonctionne..

J'ai essayé d'utiliser les méthodes suivantes:

[DllImport("MyOwn.dll",  CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs((UnmanagedType.I4))]
public static extern Int32 MyProIni(string DBname, string DBuser_pass,
    string WorkDirectory, ref StringBuilder ErrorMessage);

Quand j'ai essayé de suivre cet article et que j'exécute cet exemple (à partir du code téléchargé), il fonctionne sans problème (la dll utilisée se trouve dans le dossier bin / debug)

J'ai copié ma dll (avec tous les fichiers dont elle dépend dans mon dossier bin).

J'ai également essayé cette approche mais j'ai eu la même erreur:

[DllImportAttribute(MyOwnLibDllPath, EntryPoint="TMproIni")]
[return: MarshalAs(UnmanagedType.I4)]
public static extern  int MyproIni(string DBname, string DBuser_pass, 
    string WorkDirectory, ref StringBuilder ErrorMessage);

Aucune suggestion?

Ingimar Andresson
la source

Réponses:

90

D'après ce dont je me souviens sous Windows, l'ordre de recherche d'une DLL est:

  1. Répertoire actuel
  2. Dossier système, C:\windows\system32 or c:\windows\SysWOW64(pour processus 32 bits sur boîte 64 bits).
  3. Lecture à partir de la Pathvariable d'environnement

De plus, je vérifierais les dépendances de la DLL, le navigateur de dépendances fourni avec Visual Studio peut vous aider ici, il peut également être téléchargé gratuitement: http://www.dependencywalker.com

affichage101
la source
4
a trouvé des dépendances manquantes (Oracle et quelques dll d'IE). Besoin d'installer Oracle car ma dll en dépend .. alors je le saurai :) J'ai trouvé le problème avec DependencyWalker;)
Ingimar Andresson
Pas de soucis, ça m'a sauvé de nombreuses heures de grattage de tête, super petit outil! :-)
display101
1
+1 à Keith Halligan pour avoir suggéré DependencyWalker. Cela m'a dit que toutes les dépendances n'avaient pas le même type de processeur (x86 / x64). J'ai copié tous les fichiers qui avaient le même type de processeur dans le dossier bin de mon application, et cela a résolu le problème.
DiligentKarma
6
Chaque dll que je peux trouver sur mon système a DependencyWalker affirmant qu'il y a une erreur avec différents types de CPU - même System.Web.Mvc.dll. Il y a une sorte de fausse alerte ici.
PandaWood
2
Dans mon cas, le problème tentait de charger une DLL C ++ compilée pour le débogage. Cela nécessite le runtime de débogage C ++, ce qui signifie que vous devez installer Visual Studio. Ou recompilez la DLL pour Release et installez le distribuable du runtime C ++.
RenniePet
42

Vous pouvez utiliser l'outil dumpbin pour connaître les dépendances DLL requises:

dumpbin /DEPENDENTS my.dll

Cela vous indiquera quelles DLL votre DLL doit charger. Recherchez en particulier MSVCR * .dll. J'ai vu votre code d'erreur se produire lorsque le redistribuable Visual C ++ correct n'est pas installé.

Vous pouvez obtenir les «packages redistribuables Visual C ++ pour Visual Studio 2013» sur le site Web de Microsoft. Il installe c: \ windows \ system32 \ MSVCR120.dll

Dans le nom de fichier, 120 = 12.0 = Visual Studio 2013.

Assurez-vous que vous avez la bonne version de Visual Studio (10.0 = VS 10, 11 = VS 2012, 12.0 = VS 2013 ...) la bonne architecture (x64 ou x86) pour la plate-forme cible de votre DLL, et vous devez également faire attention debug builds. La version de débogage d'une DLL dépend de MSVCR120d.dll qui est une version de débogage de la bibliothèque, qui est installée avec Visual Studio mais pas par le package redistribuable.

Anthony Hayward
la source
5
l'ajout des redistribuables VS C ++ était fait pour moi! nécessaire v10.0 (2010). Merci beaucoup !!!
Thiago Silva le
Existe-t-il un moyen de savoir si des versions 64 bits ou 32 bits des redistribuables sont nécessaires?
BVB
1
dumpbin / ALL vous dira si my.dll est x86 de x64
Anthony Hayward
1
Pour ceux qui souffrent encore de ce problème, si vous utilisez debugbinaire, la version des redistribuables d'exécution C ++ doit être exactement la même que celle où vous l'avez construite.
skyline75489 du
Le commentaire de @ skyline75489 a sauvé la journée pour moi. La bibliothèque C ++ fonctionnait très bien sur ma machine mais ne se chargeait pas partout ailleurs en raison de la liaison entre VS et la version de débogage de msvcr.
espion le
14

Ceci est un 'kludge' mais vous pouvez au moins l'utiliser pour tester la cohérence: essayez de coder en dur le chemin de la DLL dans votre code

[DllImport(@"C:\\mycompany\\MyDLL.dll")]

Ayant dit cela; dans mon cas, exécuter dumpbin /DEPENDENTScomme suggéré par @ anthony-hayward, et copier des versions 32 bits des DLL listées ici dans mon répertoire de travail a résolu ce problème pour moi.

Le message est juste un peu trompeur, car ce n'est pas "ma" dll qui ne peut pas être chargée - ce sont les dépendances

Noir
la source
12

La DLL doit se trouver dans le dossier bin.

Dans Visual Studio, j'ajoute la dll à mon projet (PAS dans les références, mais "Ajouter un fichier existant"). Définissez ensuite la propriété «Copier dans le répertoire de sortie» de la dll sur «Copier si plus récent».

Jeremy Thompson
la source
11

Essayez d'entrer le chemin complet de la dll. Si cela ne fonctionne pas, essayez de copier la dll dans le dossier system32.

Headpuster
la source
3
est-il correct d'avoir toutes les dépendances dans le dossier System32 et ma dll ailleurs?
Ingimar Andresson
Les dépendances seront également recherchées selon l'ordre du chemin de recherche de la DLL Windows, comme spécifié par stackoverflow.com/a/9003290/4434329
4

Assurez-vous que toutes les dépendances de votre propre dll sont présentes à proximité de la dll ou dans System32.

Felice Pollano
la source
4

Il y a une chose très drôle (et qui a une pertinence technique) qui pourrait vous faire perdre des heures alors pensé à la partager ici -

J'ai créé un projet d'application console ConsoleApplication1et un projet de bibliothèque de classes ClassLibrary1.

Tout le code qui faisait l'invocation p / était présent dans ClassLibrary1.dll. Donc, avant de déboguer l'application depuis Visual Studio, j'ai simplement copié l'assembly non managé C ++ myUnmanagedFunctions.dlldans le \bin\debug\répertoire du ClassLibrary1projet afin qu'il puisse être chargé au moment de l'exécution par le CLR.

J'ai continué à recevoir le

Impossible de charger la DLL

erreur pendant des heures. Plus tard, j'ai réalisé que tous ces assemblys non gérés qui doivent être chargés doivent être copiés dans le \bin\debugrépertoire du projet de démarrage ConsoleApplication1qui est généralement un formulaire gagnant, une console ou une application Web.

Soyez donc prudent si la Current Directoryréponse acceptée signifie en fait l' Current Directoryexécutable principal à partir duquel votre processus de candidature démarre. Cela semble évident, mais peut-être pas parfois.

Leçon apprise - Placez toujours les dll non gérées dans le même répertoire que l'exécutable de démarrage pour vous assurer qu'il peut être trouvé.

RBT
la source
Cela a arrangé les choses pour moi aussi. C'est un peu bizarre de mettre les DLL dans le projet principal au lieu du projet qui les utilise réellement, cependant ...
Sean Duggan
@SeanDuggan parce qu'il s'agit d'une "bibliothèque de liens dynamiques", ce qui signifie qu'elle est utilisée (chargée) au moment de l'exécution par opposition aux bibliothèques statiques qui sont utilisées au moment de la liaison.
m4l490n
Je l' ai essayé d' ajouter le dll dans le bin\Debuget les obj\Debugrépertoires et je continue à obtenir la « Impossible de DLL de charge »
m4l490n
3

Activez la journalisation de la fusion, consultez cette question pour obtenir de nombreux conseils sur la façon de procéder. Le débogage des problèmes de chargement d'applications en mode mixte peut être une véritable douleur royale. La journalisation par fusion peut être d'une grande aide.

Chris O
la source
2

Assurez-vous de définir la cible de la plate-forme de construction sur x86 ou x64 afin qu'elle soit compatible avec votre DLL - qui peut être compilée pour une plate-forme 32 bits.

Bien sûr
la source
2

Si la DLL et les projets .NET sont dans la même solution et que vous souhaitez compiler et exécuter les deux à chaque fois, vous pouvez cliquer avec le bouton droit sur les propriétés du projet .NET, événements de génération, puis ajouter quelque chose comme ce qui suit à l'événement de post-génération ligne de commande:

copy $(SolutionDir)Debug\MyOwn.dll .

C'est essentiellement une ligne DOS, et vous pouvez modifier en fonction de l'endroit où votre DLL est construite.

SharpC
la source
2

J'ai eu le même problème lorsque j'ai déployé mon application pour tester le PC. Le problème était que le PC de développement avait msvcp110d.dllet msvcr110d.dllpas le PC de test.

J'ai ajouté le module de fusion "Visual Studio C ++ 11.0 DebugCRT (x86)" dans InstalledSheild et cela a fonctionné. J'espère que cela sera utile pour quelqu'un d'autre.

kakopappa
la source
2

Dans mon cas, une DLL non gérée dépendait d'une autre qui manquait. Dans ce cas, l'erreur pointera vers la dll existante au lieu de celle manquante, ce qui peut être vraiment déroutant.

C'est exactement ce qui s'est passé dans mon cas. J'espère que ceci aide quelqu'un d'autre.

Rahatur
la source
1

Je pense que votre bibliothèque non gérée a besoin d'un manifeste.
Voici comment l'ajouter à votre binaire. et voici pourquoi.

En résumé, plusieurs versions de bibliothèques redistribuables peuvent être installées dans votre boîte, mais une seule d'entre elles devrait satisfaire votre application, et ce n'est peut-être pas la valeur par défaut, vous devez donc indiquer au système la version dont votre bibliothèque a besoin, c'est pourquoi le manifeste.

Eugenio Miró
la source
1

Configuration : Windows 7 32 bits

Contexte : J'ai installé un pilote PCI-GPIB avec lequel je n'ai pas pu communiquer en raison du problème susmentionné.

Réponse courte : réinstallez le pilote.

Réponse longue : J'ai également utilisé Dependency Walker , qui a identifié plusieurs modules de dépendance manquants. Immédiatement, j'ai pensé que cela devait être une installation de pilote bâclée. Je ne voulais pas vérifier et restaurer chaque fichier manquant.

Le fait que je n'ai pas pu trouver le programme de désinstallation sous Programmes et fonctionnalités du panneau de configuration est un autre indicateur d'une mauvaise installation. J'ai dû supprimer manuellement quelques clés * .dll dans \ system32 et de registre pour permettre la réinstallation du pilote.

Problème résolu.

La partie inattendue était que tous les modules de dépendance n'étaient pas résolus. Néanmoins, le * .dll d'intérêt peut maintenant être référencé.

Icernos
la source
1

J'ai rencontré le même problème, dans mon cas, j'avais deux PC 32 bits. L'un avec .NET4.5 installé et l'autre était un PC neuf.

ma dll cpp 32 bits (version en mode de sortie) fonctionnait bien avec le PC installé .NET mais pas avec le nouveau PC où j'ai eu l'erreur ci-dessous

Impossible de charger la DLL «PrinterSettings.dll»: le module spécifié est introuvable. (Exception de HRESULT: 0x8007007E)

enfin,

Je viens de construire mon projet dans la configuration du mode débogage et cette fois, ma dll cpp fonctionnait bien.

Abu Muhammad
la source
0

Également confronté au même problème lors de l'utilisation d'un fichier dll c / c ++ non géré dans un environnement c #.

1.Vérifié la compatibilité de la DLL avec le processeur 32 bits ou 64 bits.

2.Vérifié les chemins corrects du dossier DLL .bin, system32 / sysWOW64 ou le chemin donné.

3.Vérifié si les fichiers PDB (base de données du programme) sont manquants. Cette vidéo vous donne une meilleure compréhension des fichiers pdb .

Lors de l'exécution de code binaire C / C ++ 32 bits dans un système 64 bits, cela peut survenir en raison d'une incompatibilité de plate-forme. Vous pouvez le modifier à partir de Build> Configuration manager.

Yuresh Karunanayake
la source
0

J'ai rencontré le même problème lors de l'importation de Dll C ++ dans .Net Framework +4, j'ai décoché Projet-> Propriétés-> Construire-> Préférer 32 bits et cela a été résolu pour moi.

Mamo Ghandi
la source