Impossibile caricare la DLL (non è stato possibile trovare il modulo HRESULT: 0x8007007E)


113

Ho una libreria dll con codice API C ++ non gestito che devo utilizzare nella mia applicazione .NET 4.0. Ma ogni metodo che provo a caricare il mio dll ottengo un errore:

Impossibile caricare la DLL "MyOwn.dll": non è stato possibile trovare il modulo specificato. (Eccezione da HRESULT: 0x8007007E)

Ho letto e provato diverse soluzioni che ho trovato su Internet. Niente funziona ..

Ho provato a utilizzare i seguenti metodi:

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

Quando ho provato a seguire questo articolo e quando eseguo questo esempio (dal codice scaricato) viene eseguito senza problemi (la dll utilizzata è nella cartella bin / debug)

Ho copiato la mia dll (insieme a tutti i file da cui dipende nella mia cartella bin).

Ho anche provato questo approccio ma ho ricevuto lo stesso errore:

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

Eventuali suggerimenti?

Risposte:


90

Da quello che ricordo su Windows l'ordine di ricerca di una dll è:

  1. Directory corrente
  2. Cartella di sistema, C:\windows\system32 or c:\windows\SysWOW64(per processo a 32 bit su box a 64 bit).
  3. Lettura dalla Pathvariabile d'ambiente

Inoltre controllerei le dipendenze della DLL, il walker delle dipendenze fornito con Visual Studio può aiutarti qui, può anche essere scaricato gratuitamente: http://www.dependencywalker.com


4
trovato alcune dipendenze mancanti (Oracle e alcuni dll da IE). È necessario installare Oracle poiché la mia dll dipende da quello ... poi lo saprò :) Trovato il problema con DependencyWalker;)
Ingimar Andresson

Nessun problema, mi ha risparmiato molte ore di grattarsi la testa, piccolo grande strumento! :-)
display101

1
+1 a Keith Halligan per aver suggerito DependencyWalker. Mi ha detto che non tutte le dipendenze avevano lo stesso tipo di CPU (x86 / x64). Ho copiato tutti i file che avevano lo stesso tipo di CPU nella cartella bin della mia applicazione e questo ha risolto il problema.
DiligentKarma

6
Ogni dll che riesco a trovare sul mio sistema ha DependencyWalker che afferma che c'è un errore con diversi tipi di CPU, anche System.Web.Mvc.dll. C'è una sorta di falso allarme qui.
PandaWood

2
Nel mio caso il problema stava tentando di caricare una DLL C ++ compilata per il debug. Ciò richiede il runtime di debug C ++, il che significa che devi installare Visual Studio. Oppure ricompilare la DLL per Release e installare il runtime C ++ distribuibile.
RenniePet

42

È possibile utilizzare lo strumento dumpbin per scoprire le dipendenze DLL richieste:

dumpbin /DEPENDENTS my.dll

Questo ti dirà quali DLL deve caricare la tua DLL. Cerca in particolare MSVCR * .dll. Ho visto che il tuo codice di errore si verifica quando non è installato il ridistribuibile Visual C ++ corretto.

È possibile ottenere i "Pacchetti ridistribuibili di Visual C ++ per Visual Studio 2013" dal sito Web di Microsoft. Installa c: \ windows \ system32 \ MSVCR120.dll

Nel nome del file, 120 = 12.0 = Visual Studio 2013.

Fai attenzione di avere la giusta versione di Visual Studio (10.0 = VS 10, 11 = VS 2012, 12.0 = VS 2013 ...) architettura corretta (x64 o x86) per la piattaforma di destinazione della tua DLL, e devi anche stare attento build di debug. La build di debug di una DLL dipende da MSVCR120d.dll che è una versione di debug della libreria, che viene installata con Visual Studio ma non dal pacchetto ridistribuibile.


5
l'aggiunta dei ridistribuibili VS C ++ è stato per me! necessaria v10.0 (2010). Grazie mucho !!!
Thiago Silva

Esiste un modo per sapere se sono necessarie versioni a 64 bit o 32 bit dei ridistribuibili?
BVB

1
dumpbin / ALL ti dirà se my.dll è x86 di x64
Anthony Hayward

1
Per coloro che soffrono ancora di questo problema, se si utilizza il debugbinario, la versione ridistribuibile del runtime C ++ deve essere esattamente la stessa di dove l'hai costruita.
skyline75489

Il commento di @ skyline75489 mi ha salvato la giornata. La libreria C ++ ha funzionato bene sulla mia macchina ma non è riuscita a caricarsi ovunque a causa di VS che la collega alla versione di debug di msvcr.
spia il

14

Questo è un "kludge" ma potresti almeno usarlo per testare la sanità mentale: prova a codificare il percorso della DLL nel tuo codice

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

Avendolo detto; nel mio caso, l'esecuzione dumpbin /DEPENDENTScome suggerito da @ anthony-hayward e la copia di versioni a 32 bit delle DLL elencate nella mia directory di lavoro ha risolto questo problema per me.

Il messaggio è solo un po 'fuorviante, perché non è la "mia" dll che non può essere caricata - sono le dipendenze


12

La DLL deve essere nella cartella bin.

In Visual Studio, aggiungo la dll al mio progetto (NON in Riferimenti, ma "Aggiungi file esistente"). Quindi impostare la proprietà "Copia nella directory di output" per la dll su "Copia se più recente".


11

Prova a inserire il percorso completo del file dll. Se non funziona, prova a copiare la dll nella cartella system32.


3
va bene avere tutte le dipendenze nella cartella System32 e la mia dll da qualche altra parte?
Ingimar Andresson

Dipendenze saranno anche essere ricercati come per le finestre di ricerca DLL fine percorso, come specificato da stackoverflow.com/a/9003290/4434329

4

Assicurati che tutte le dipendenze della tua dll siano presenti vicino alla dll o in System32.


4

C'è una cosa molto divertente (e ha una rilevanza tecnica) che potrebbe farti perdere ore, quindi ho pensato di condividerla qui -

Ho creato un progetto di applicazione console ConsoleApplication1e un progetto di libreria di classi ClassLibrary1.

Tutto il codice che stava creando p / invoke era presente in ClassLibrary1.dll. Quindi, prima di eseguire il debug dell'applicazione da Visual Studio, ho semplicemente copiato l'assembly non gestito C ++ ( myUnmanagedFunctions.dll) nella \bin\debug\directory del ClassLibrary1progetto in modo che possa essere caricato in fase di esecuzione dal CLR.

Ho continuato a ricevere il file

Impossibile caricare la DLL

errore per ore. Successivamente mi sono reso conto che tutti questi assembly non gestiti che devono essere caricati devono essere copiati nella \bin\debugdirectory del progetto di avvio ConsoleApplication1che di solito è una win form, una console o un'applicazione web.

Quindi si prega di essere cauti Current Directorynella risposta accettata in realtà significa Current Directorydell'eseguibile principale da cui inizia il processo di applicazione. Sembra una cosa ovvia, ma a volte potrebbe non esserlo.

Lezione appresa : posizionare sempre le DLL non gestite nella stessa directory dell'eseguibile di avvio per assicurarsi che possa essere trovato.


Questo ha risolto le cose anche per me. Sembra un po 'strano inserire le DLL nel progetto principale invece del progetto che le sta effettivamente utilizzando, però ...
Sean Duggan

@SeanDuggan è perché si tratta di una "libreria di collegamento dinamico", il che significa che viene utilizzata (caricata) in fase di esecuzione rispetto alle librerie statiche utilizzate in fase di collegamento.
m4l490n

Ho provato ad aggiungere la dll nella bin\Debuge le obj\Debugdirectory e continuo a ricevere il "Impossibile DLL di carico"
m4l490n

3

Attivare la registrazione della fusione, vedere questa domanda per molti consigli su come farlo. Il debug dei problemi di caricamento delle app in modalità mista può essere un vero dolore. La registrazione della fusione può essere di grande aiuto.


2

Assicurati di impostare Build Platform Target su x86 o x64 in modo che sia compatibile con la tua DLL, che potrebbe essere compilata per una piattaforma a 32 bit.


2

Se i progetti DLL e .NET si trovano nella stessa soluzione e si desidera compilare ed eseguire entrambi ogni volta, è possibile fare clic con il pulsante destro del mouse sulle proprietà del progetto .NET, Build events, quindi aggiungere qualcosa di simile all'evento Post-build riga di comando:

copy $(SolutionDir)Debug\MyOwn.dll .

È fondamentalmente una riga DOS e puoi modificare in base a dove viene creata la tua DLL.


2

Ho avuto lo stesso problema quando ho distribuito la mia applicazione per testare il PC. Il problema è stato lo sviluppo del PC aveva msvcp110d.dlle msvcr110d.dll, ma non il PC di prova.

Ho aggiunto il modulo di unione "Visual Studio C ++ 11.0 DebugCRT (x86)" in InstalledSheild e ha funzionato. Spero che questo possa essere utile per qualcun altro.


2

Nel mio caso una dll non gestita dipendeva da un'altra che mancava. In tal caso l'errore punterà alla dll esistente anziché a quella mancante, il che può creare confusione.

Questo è esattamente quello che era successo nel mio caso. Spero che questo aiuti qualcun altro.


1

Penso che la tua libreria non gestita abbia bisogno di un manifest.
Ecco come aggiungerlo al tuo file binario. ed ecco perché.

In sintesi, nella confezione possono essere installate diverse versioni della libreria ridistribuibile, ma solo una di esse dovrebbe soddisfare la tua app e potrebbe non essere l'impostazione predefinita, quindi devi indicare al sistema la versione di cui ha bisogno la tua libreria, ecco perché il manifest.


1

Configurazione : Windows 7 a 32 bit

Contesto : installato un driver PCI-GPIB tramite il quale non sono stato in grado di comunicare a causa del suddetto problema.

Risposta breve : reinstallare il driver.

Risposta lunga : ho anche usato Dependency Walker , che ha identificato diversi moduli di dipendenza mancanti. Immediatamente, ho pensato che doveva essere stata un'installazione del driver mal riuscita. Non volevo controllare e ripristinare ogni file mancante.

Il fatto che non sono riuscito a trovare il programma di disinstallazione in Programmi e funzionalità del pannello di controllo è un altro indicatore di una cattiva installazione. Ho dovuto eliminare manualmente un paio di * .dll in \ system32 e le chiavi di registro per consentire la reinstallazione del driver.

Problema risolto.

La parte inaspettata era che non tutti i moduli di dipendenza sono stati risolti. Tuttavia, ora è possibile fare riferimento al file * .dll di interesse.


1

Ho riscontrato lo stesso problema, nel mio caso avevo due PC a 32 bit. Uno con .NET4.5 installato e l'altro era un nuovo PC.

la mia dll cpp a 32 bit (build in modalità di rilascio) funzionava bene con il PC installato .NET ma non con il nuovo PC in cui ho ricevuto l'errore di seguito

Impossibile caricare la DLL "PrinterSettings.dll": non è stato possibile trovare il modulo specificato. (Eccezione da HRESULT: 0x8007007E)

finalmente,

Ho appena creato il mio progetto nella configurazione in modalità Debug e questa volta la mia dll cpp funzionava bene.


0

Inoltre ha affrontato lo stesso problema quando si utilizzava il file dll c / c ++ non gestito in ambiente c #.

1.Verificato la compatibilità di dll con CPU a 32 bit o 64 bit.

2.Verificato i percorsi corretti della cartella DLL .bin, system32 / sysWOW64 o il percorso specificato.

3.Verificato se mancano i file PDB (Database di programma). Questo video ti offre la migliore comprensione dei file PDB.

Quando si esegue codice binario C / C ++ a 32 bit in un sistema a 64 bit, ciò potrebbe verificarsi a causa dell'incompatibilità della piattaforma. Puoi modificarlo da Build> Configuration manager.


0

Ho riscontrato lo stesso problema durante l'importazione della DLL C ++ in .Net Framework +4, ho deselezionato Progetto-> Proprietà-> Crea-> Preferisci 32 bit e ha risolto per me.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.