DLL kann nicht geladen werden (Modul konnte nicht gefunden werden HRESULT: 0x8007007E)

113

Ich habe eine DLL-Bibliothek mit nicht verwaltetem C ++ - API-Code, die ich in meiner .NET 4.0-Anwendung verwenden muss. Aber bei jeder Methode, mit der ich versuche, meine DLL zu laden, wird eine Fehlermeldung angezeigt:

DLL 'MyOwn.dll' kann nicht geladen werden: Das angegebene Modul wurde nicht gefunden. (Ausnahme von HRESULT: 0x8007007E)

Ich habe mehrere Lösungen gelesen und ausprobiert, die ich im Internet gefunden habe. Nichts funktioniert..

Ich habe versucht, folgende Methoden zu verwenden:

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

Wenn ich versucht habe, diesem Artikel zu folgen, und wenn ich dieses Beispiel (aus dem heruntergeladenen Code) ausführe, läuft es ohne Probleme (die verwendete DLL befindet sich im Ordner bin / debug).

Ich habe meine DLL kopiert (zusammen mit allen Dateien, von denen es abhängt, in meinen bin-Ordner).

Ich habe auch diesen Ansatz ausprobiert, aber den gleichen Fehler erhalten:

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

Irgendwelche Vorschläge?

Ingimar Andresson
quelle

Antworten:

90

Soweit ich mich unter Windows erinnere, lautet die Suchreihenfolge für eine DLL:

  1. Aktuelles Verzeichnis
  2. Systemordner C:\windows\system32 or c:\windows\SysWOW64(für 32-Bit-Prozess auf 64-Bit-Box).
  3. Lesen aus der PathUmgebungsvariablen

Außerdem würde ich die Abhängigkeiten der DLL überprüfen. Der mit Visual Studio bereitgestellte Abhängigkeits-Walker kann Ihnen hier weiterhelfen. Er kann auch kostenlos heruntergeladen werden: http://www.dependencywalker.com

display101
quelle
4
Es wurde festgestellt, dass einige Abhängigkeiten fehlen (Oracle und einige DLLs aus dem IE). Müssen Oracle installieren, da meine DLL davon abhängt .. dann werde ich wissen :) Gefunden das Problem mit DependencyWalker;)
Ingimar Andresson
Keine Sorge, es hat mir viele Stunden Kopfkratzen erspart, tolles kleines Werkzeug! :-)
display101
1
+1 an Keith Halligan für den Vorschlag von DependencyWalker. Es wurde mir gesagt, dass nicht alle Abhängigkeiten den gleichen CPU-Typ hatten (x86 / x64). Ich habe alle Dateien mit demselben CPU-Typ in den Bin-Ordner meiner Anwendung kopiert, wodurch das Problem behoben wurde.
DiligentKarma
6
Für jede DLL, die ich auf meinem System finden kann, behauptet DependencyWalker, dass bei verschiedenen CPU-Typen ein Fehler vorliegt - sogar bei System.Web.Mvc.dll. Hier gibt es eine Art Fehlalarm.
PandaWood
2
In meinem Fall bestand das Problem darin, eine für Debug kompilierte C ++ - DLL zu laden. Dies erfordert die C ++ - Debug-Laufzeit, dh Sie müssen Visual Studio installieren. Oder kompilieren Sie die DLL für Release neu und installieren Sie die verteilbare C ++ - Laufzeit.
RenniePet
42

Mit dem Dumpbin-Tool können Sie die erforderlichen DLL-Abhängigkeiten ermitteln:

dumpbin /DEPENDENTS my.dll

Hier erfahren Sie, welche DLLs Ihre DLL laden muss. Achten Sie besonders auf MSVCR * .dll. Ich habe gesehen, dass Ihr Fehlercode auftritt, wenn die richtige Visual C ++ Redistributable nicht installiert ist.

Sie können die "Visual C ++ Redistributable Packages for Visual Studio 2013" von der Microsoft-Website herunterladen. Es installiert c: \ windows \ system32 \ MSVCR120.dll

Im Dateinamen ist 120 = 12.0 = Visual Studio 2013.

Stellen Sie sicher, dass Sie die richtige Visual Studio-Version (10.0 = VS 10, 11 = VS 2012, 12.0 = VS 2013 ...) für die Zielplattform Ihrer DLL (x64 oder x86) haben, und Sie müssen auch vorsichtig sein Debug-Builds. Der Debug-Build einer DLL hängt von MSVCR120d.dll ab, einer Debug-Version der Bibliothek, die mit Visual Studio installiert wird, jedoch nicht vom Redistributable Package.

Anthony Hayward
quelle
5
Das Hinzufügen der VS C ++ Redistributables war es für mich! benötigt v10.0 (2010). Vielen Dank !!!
Thiago Silva
Gibt es eine Möglichkeit festzustellen, ob 64-Bit- oder 32-Bit-Versionen der weiterverteilbaren Dateien erforderlich sind?
BVB
1
dumpbin / ALL wird Ihnen sagen, ob my.dll x86 von x64 ist
Anthony Hayward
1
Für diejenigen, die immer noch unter diesem Problem leiden debug, muss die C ++ - Laufzeit-Redistributables-Version genau so sein, wie Sie sie erstellt haben , wenn Sie Binärdateien verwenden.
skyline75489
Der Kommentar von @ skyline75489 hat mir den Tag gerettet. Die C ++ - Bibliothek funktionierte auf meinem Computer einwandfrei, konnte jedoch nicht überall geladen werden, da VS sie mit der Debug-Version von msvcr verknüpfte.
Spion
14

Dies ist ein "Kludge", aber Sie könnten ihn zumindest zum Testen der Integrität verwenden: Versuchen Sie, den Pfad zur DLL in Ihrem Code fest zu codieren

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

Nachdem ich das gesagt habe; In meinem Fall wurde dieses Problem für mich gelöst dumpbin /DEPENDENTS, indem ich wie von @ anthony-hayward vorgeschlagen lief und über 32-Bit- Versionen der dort aufgeführten DLLs in mein Arbeitsverzeichnis kopierte .

Die Nachricht ist nur ein bisschen irreführend, da nicht "meine" DLL geladen werden kann - es sind die Abhängigkeiten

Schwarz
quelle
12

Die DLL muss sich im Ordner bin befinden.

In Visual Studio füge ich die DLL meinem Projekt hinzu (NICHT in Referenzen, sondern "Vorhandene Datei hinzufügen"). Setzen Sie dann die Eigenschaft "In Ausgabeverzeichnis kopieren" für die DLL auf "Kopieren, wenn neuer".

Jeremy Thompson
quelle
11

Versuchen Sie, den vollständigen Pfad der DLL einzugeben. Wenn es nicht funktioniert, versuchen Sie, die DLL in den Ordner system32 zu kopieren.

Headpuster
quelle
3
Ist es in Ordnung, alle Abhängigkeiten im System32-Ordner und in meiner DLL woanders zu haben?
Ingimar Andresson
Abhängigkeiten werden auch gemäß der Windows-DLL-Suchpfadreihenfolge gesucht, wie von stackoverflow.com/a/9003290/4434329
4

Stellen Sie sicher, dass alle Abhängigkeiten Ihrer eigenen DLL in der Nähe der DLL oder in vorhanden sind System32.

Felice Pollano
quelle
4

Es gibt eine sehr lustige Sache (und hat eine technische Relevanz), die Ihre Stunden verschwenden könnte. Denken Sie also daran, sie hier zu teilen -

Ich habe ein Konsolenanwendungsprojekt ConsoleApplication1und ein Klassenbibliotheksprojekt erstellt ClassLibrary1.

Der gesamte Code, der den p / invoke ausführte, war in vorhanden ClassLibrary1.dll. Bevor ich die Anwendung aus Visual Studio debuggte, kopierte ich einfach die nicht verwaltete C ++ - Assembly ( myUnmanagedFunctions.dll) in das \bin\debug\Verzeichnis des ClassLibrary1Projekts, damit sie zur Laufzeit von der CLR geladen werden kann.

Ich bekam immer das

DLL kann nicht geladen werden

Fehler für Stunden. Später wurde mir klar, dass alle nicht verwalteten Assemblys, die geladen werden sollen, in das \bin\debugVerzeichnis des Startprojekts kopiert werden müssen, bei ConsoleApplication1dem es sich normalerweise um eine Win-Form, eine Konsole oder eine Webanwendung handelt.

Seien Sie also bitte vorsichtig, dass Current Directoryin der akzeptierten Antwort tatsächlich die Current Directoryausführbare Hauptdatei angegeben ist, von der aus Ihr Bewerbungsprozess beginnt. Sieht nach einer offensichtlichen Sache aus, ist aber manchmal nicht so.

Lesson Learned - Platzieren Sie die nicht verwalteten DLLs immer im selben Verzeichnis wie die ausführbare Startdatei, um sicherzustellen, dass sie gefunden werden können.

RBT
quelle
Das hat auch für mich Abhilfe geschaffen. Es fühlt sich irgendwie komisch an, die DLLs in das Hauptprojekt zu setzen, anstatt in das Projekt, in dem sie tatsächlich verwendet werden ...
Sean Duggan,
@SeanDuggan, weil es sich um eine "dynamische Verknüpfungsbibliothek" handelt, was bedeutet, dass sie zur Laufzeit verwendet (geladen) wird, im Gegensatz zu statischen Bibliotheken, die zur Verknüpfungszeit verwendet werden.
m4l490n
Ich habe versucht, die DLL in die Verzeichnisse und bin\Debugund hinzuzufügen, obj\Debugund ich erhalte immer wieder die
Meldung
3

Aktivieren Sie die Fusionsprotokollierung. In dieser Frage finden Sie viele Ratschläge dazu. Das Debuggen von Problemen beim Laden von Apps im gemischten Modus kann ein wahrer königlicher Schmerz sein. Die Fusionsprotokollierung kann eine große Hilfe sein.

Chris O.
quelle
2

Stellen Sie sicher, dass Sie das Build Platform Target auf x86 oder x64 festlegen, damit es mit Ihrer DLL kompatibel ist, die möglicherweise für eine 32-Bit-Plattform kompiliert wurde.

Grantly
quelle
2

Wenn sich die DLL- und die .NET-Projekte in derselben Lösung befinden und Sie beide jedes Mal kompilieren und ausführen möchten, können Sie mit der rechten Maustaste auf die Eigenschaften des .NET-Projekts "Ereignisse erstellen" klicken und dem Ereignis "Nach dem Erstellen" Folgendes hinzufügen Befehlszeile:

copy $(SolutionDir)Debug\MyOwn.dll .

Es handelt sich im Grunde genommen um eine DOS-Zeile, und Sie können die Einstellungen basierend darauf vornehmen, wohin Ihre DLL erstellt wird.

SharpC
quelle
2

Ich hatte das gleiche Problem, als ich meine Anwendung zum Testen des PCs bereitstellte. Das Problem war der Entwicklungs-PC msvcp110d.dllund msvcr110d.dllnicht der Test-PC.

Ich habe das Zusammenführungsmodul "Visual Studio C ++ 11.0 DebugCRT (x86)" in InstalledSheild hinzugefügt und es hat funktioniert. Hoffe, dass dies für jemand anderen hilfreich sein wird.

Kakopappa
quelle
2

In meinem Fall war eine nicht verwaltete DLL von einer anderen abhängig, die fehlte. In diesem Fall zeigt der Fehler auf die vorhandene DLL anstatt auf die fehlende, was sehr verwirrend sein kann.

Genau das war in meinem Fall passiert. Hoffe das hilft jemand anderem.

Rahatur
quelle
1

Ich denke, Ihre nicht verwaltete Bibliothek braucht ein Manifest.
Hier erfahren Sie, wie Sie es zu Ihrer Binärdatei hinzufügen. und hier ist warum.

Zusammenfassend kann gesagt werden, dass mehrere weiterverteilbare Bibliotheksversionen in Ihrer Box installiert werden können, aber nur eine davon sollte Ihrer App entsprechen. Dies ist möglicherweise nicht die Standardeinstellung. Sie müssen dem System daher mitteilen, welche Version Ihre Bibliothek benötigt. Aus diesem Grund das Manifest.

Eugenio Miró
quelle
1

Setup : 32-Bit Windows 7

Kontext : Installierte einen PCI-GPIB-Treiber, über den ich aufgrund des oben genannten Problems nicht kommunizieren konnte.

Kurze Antwort : Installieren Sie den Treiber neu.

Lange Antwort : Ich habe auch Dependency Walker verwendet , der mehrere fehlende Abhängigkeitsmodule identifiziert hat. Sofort dachte ich, dass es eine verpfuschte Treiberinstallation gewesen sein muss. Ich wollte nicht jede fehlende Datei überprüfen und wiederherstellen.

Die Tatsache, dass ich das Deinstallationsprogramm unter Programme und Funktionen der Systemsteuerung nicht finden konnte, ist ein weiterer Hinweis auf eine fehlerhafte Installation. Ich musste einige * .dll in \ system32 und Registrierungsschlüssel manuell löschen, um eine Neuinstallation des Treibers zu ermöglichen.

Problem behoben.

Der unerwartete Teil war, dass nicht alle Abhängigkeitsmodule aufgelöst wurden. Trotzdem kann jetzt auf die * .dll von Interesse verwiesen werden.

icernos
quelle
1

Ich bin auf das gleiche Problem gestoßen. In meinem Fall hatte ich zwei 32-Bit-PCs. Einer mit .NET4.5 installiert und der andere war ein neuer PC.

Meine 32-Bit-CPP-DLL (Release-Modus-Build) funktionierte einwandfrei mit einem .NET-PC, aber nicht mit einem neuen PC, auf dem der folgende Fehler aufgetreten ist

DLL 'PrinterSettings.dll' kann nicht geladen werden: Das angegebene Modul wurde nicht gefunden. (Ausnahme von HRESULT: 0x8007007E)

endlich,

Ich habe gerade mein Projekt im Debug-Modus erstellt und diesmal funktionierte meine cpp-DLL einwandfrei.

Abu Muhammad
quelle
0

Das gleiche Problem trat auch bei der Verwendung einer nicht verwalteten c / c ++ - DLL-Datei in einer c # -Umgebung auf.

1.Überprüft die Kompatibilität der DLL mit 32-Bit- oder 64-Bit-CPU.

2.Überprüfen Sie die korrekten Pfade des DLL-Ordners .bin, system32 / sysWOW64 oder des angegebenen Pfads.

3.Überprüft, ob PDB-Dateien (Program Database) fehlen. Dieses Video Dieses gibt Ihnen einen Überblick über PDF-Dateien.

Wenn 32-Bit-C / C ++ - Binärcode in einem 64-Bit-System ausgeführt wird, kann dies auf eine Plattforminkompatibilität zurückzuführen sein. Sie können es über Build> Configuration Manager ändern.

Yuresh Karunanayake
quelle
0

Beim Importieren der C ++ - DLL in .Net Framework +4 hatte ich das gleiche Problem. Ich habe Project-> Properties-> Build-> Prefer 32-bit deaktiviert und es wurde für mich gelöst.

Mamo Gandhi
quelle