Tidak dapat memuat DLL (Modul tidak dapat ditemukan HRESULT: 0x8007007E)

113

Saya memiliki perpustakaan dll dengan kode C ++ API yang tidak dikelola yang perlu saya gunakan dalam aplikasi .NET 4.0 saya. Tetapi setiap metode yang saya coba memuat dll saya, saya mendapatkan kesalahan:

Tidak dapat memuat DLL 'MyOwn.dll': Modul yang ditentukan tidak dapat ditemukan. (Pengecualian dari HRESULT: 0x8007007E)

Saya telah membaca dan mencoba beberapa solusi yang saya temukan di internet. Tidak ada yang berhasil ..

Saya telah mencoba menggunakan metode berikut:

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

Ketika saya mencoba mengikuti artikel ini dan ketika saya menjalankan contoh ini (dari kode yang diunduh) berjalan tanpa masalah (dll yang digunakan ada di folder bin / debug)

Saya telah menyalin dll saya (bersama dengan semua file yang tergantung ke folder bin saya).

Saya juga mencoba pendekatan ini tetapi mendapatkan kesalahan yang sama:

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

Ada saran?

Ingimar Andresson
sumber

Jawaban:

90

Dari yang saya ingat di Windows, urutan pencarian untuk dll adalah:

  1. Direktori Saat Ini
  2. Folder sistem, C:\windows\system32 or c:\windows\SysWOW64(untuk proses 32-bit pada kotak 64-bit).
  3. Membaca dari Pathvariabel lingkungan

Selain itu saya akan memeriksa dependensi DLL, walker dependensi yang disediakan dengan Visual Studio dapat membantu Anda di sini, juga dapat diunduh secara gratis: http://www.dependencywalker.com

display101
sumber
4
menemukan beberapa ketergantungan hilang (Oracle dan beberapa dll dari IE). Perlu menginstal Oracle karena dll saya tergantung pada itu .. kemudian saya akan tahu :) Menemukan masalah dengan DependencyWalker;)
Ingimar Andresson
Jangan khawatir, ini menghemat berjam-jam garukan kepala untuk saya, alat kecil yang hebat! :-)
display101
1
+1 untuk Keith Halligan karena menyarankan DependencyWalker. Ini memberi tahu saya bahwa tidak semua dependensi memiliki jenis CPU yang sama (x86 / x64). Saya menyalin semua file yang memiliki tipe CPU yang sama ke folder bin aplikasi saya, dan itu menyelesaikan masalah.
Rajin
6
Setiap dll yang dapat saya temukan di sistem saya memiliki DependencyWalker yang mengklaim bahwa ada kesalahan dengan jenis CPU yang berbeda - bahkan System.Web.Mvc.dll. Ada semacam alarm palsu di sini.
PandaWood
2
Dalam kasus saya, masalahnya mencoba memuat C ++ DLL yang dikompilasi untuk Debug. Itu membutuhkan runtime debug C ++, yang berarti Anda harus menginstal Visual Studio. Atau kompilasi ulang DLL untuk Rilis, dan instal runtime C ++ yang dapat didistribusikan.
RenniePet
42

Anda dapat menggunakan alat dumpbin untuk mengetahui dependensi DLL yang diperlukan:

dumpbin /DEPENDENTS my.dll

Ini akan memberi tahu Anda DLL mana yang perlu dimuat DLL Anda. Perhatikan MSVCR * .dll. Saya telah melihat kode kesalahan Anda terjadi ketika Visual C ++ Redistributable yang benar tidak diinstal.

Anda bisa mendapatkan "Paket Visual C ++ Redistributable untuk Visual Studio 2013" dari situs web Microsoft. Ini menginstal c: \ windows \ system32 \ MSVCR120.dll

Dalam nama file, 120 = 12.0 = Visual Studio 2013.

Berhati-hatilah karena Anda memiliki versi Visual Studio yang tepat (10.0 = VS 10, 11 = VS 2012, 12.0 = VS 2013 ...) arsitektur yang tepat (x64 atau x86) untuk platform target DLL Anda, dan Anda juga perlu berhati-hati. debug build. Membangun debug DLL tergantung pada MSVCR120d.dll yang merupakan versi debug pustaka, yang diinstal dengan Visual Studio tetapi tidak oleh Paket yang Dapat Didistribusikan Ulang.

Anthony Hayward
sumber
5
menambahkan VS C ++ redistributables itu untuk saya! membutuhkan v10.0 (2010). Terima kasih banyak !!!
Thiago Silva
Apakah ada cara untuk mengetahui apakah versi 64-bit atau 32-bit dari redistributable diperlukan?
BVB
1
dumpbin / ALL akan memberi tahu Anda apakah my.dll adalah x86 dari x64
Anthony Hayward
1
Bagi mereka yang masih mengalami masalah ini, jika Anda menggunakan debugbiner, versi C ++ runtime redistributable harus sama persis dengan tempat Anda membuatnya.
skyline75489
Komentar @ skyline75489 menyelamatkan hari itu bagi saya. Pustaka C ++ bekerja dengan baik di mesin saya tetapi gagal memuat di tempat lain karena VS menautkannya ke versi debug D3D.
mata
14

Ini adalah 'kludge' tetapi Anda setidaknya dapat menggunakannya untuk uji kewarasan: Cobalah melakukan hard-coding jalur ke DLL dalam kode Anda

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

Karena itu; dalam kasus saya berjalan dumpbin /DEPENDENTSseperti yang disarankan oleh @ anthony-hayward, dan menyalin lebih dari versi 32-bit DLL yang terdaftar di sana ke direktori kerja saya memecahkan masalah ini untuk saya.

Pesannya hanya sedikit menyesatkan, karena itu bukan dll "saya" yang tidak dapat dimuat - itu adalah ketergantungan

Hitam
sumber
12

DLL harus berada di folder bin.

Dalam Visual Studio, saya menambahkan dll ke proyek saya (BUKAN di Referensi, tetapi "Tambahkan file yang ada"). Kemudian setel Properti "Salin ke Direktori Output" untuk dll ke "Salin jika lebih baru".

Jeremy Thompson
sumber
11

Cobalah untuk memasukkan path lengkap dari dll. Jika tidak berhasil, coba salin dll ke folder system32.

Headpuster
sumber
3
apakah boleh memiliki semua ketergantungan di folder System32 dan dll saya di tempat lain?
Ingimar Andresson
Dependensi juga akan dicari sesuai urutan jalur pencarian windows dll seperti yang ditentukan oleh stackoverflow.com/a/9003290/4434329
4

Pastikan semua dependensi dll Anda ada di dekat dll, atau dalam format System32.

Felice Pollano
sumber
4

Ada satu hal yang sangat lucu (dan memiliki relevansi teknis) yang mungkin membuang-buang waktu Anda, jadi pikirkan untuk membagikannya di sini -

Saya membuat proyek aplikasi konsol ConsoleApplication1dan proyek perpustakaan kelasClassLibrary1 .

Semua kode yang membuat p / pemanggilan ada di dalamnya ClassLibrary1.dll. Jadi sebelum men-debug aplikasi dari visual studio, saya cukup menyalin C ++ unmanaged assembly ( myUnmanagedFunctions.dll) ke dalam \bin\debug\direktori ClassLibrary1proyek sehingga dapat dimuat saat run-time oleh CLR.

Saya terus mendapatkan

Tidak dapat memuat DLL

kesalahan selama berjam-jam. Kemudian saya menyadari bahwa semua rakitan yang tidak terkelola yang akan dimuat perlu disalin ke \bin\debugdirektori proyek start-up ConsoleApplication1yang biasanya berupa aplikasi win form, konsol atau web.

Jadi harap berhati-hati Current Directorydalam jawaban yang diterima sebenarnya berarti Current Directoryeksekusi utama dari mana proses aplikasi Anda dimulai. Tampak seperti hal yang jelas, tetapi terkadang tidak begitu.

Hal yang Dipelajari - Selalu tempatkan dll yang tidak rusak di direktori yang sama dengan eksekusi start-up untuk memastikan bahwa itu dapat ditemukan.

NSP
sumber
Ini memperbaiki hal-hal untuk saya juga. Rasanya agak aneh untuk menempatkan DLL di proyek utama daripada proyek yang benar-benar menggunakannya, meskipun ...
Sean Duggan
@SeanDuggan karena ini adalah "pustaka tautan dinamis" yang berarti digunakan (dimuat) pada waktu proses sebagai lawan dari pustaka statis yang digunakan pada waktu penautan.
m4l490n
Saya telah mencoba menambahkan dll ke dalam bin\Debugdan obj\Debugdirektori dan saya terus mendapatkan "Tidak dapat memuat DLL"
m4l490n
3

Nyalakan pencatatan fusi, lihat pertanyaan ini untuk mendapatkan banyak saran tentang bagaimana melakukannya. Men-debug masalah pemuatan aplikasi mode campuran bisa sangat merepotkan. Pencatatan fusi bisa sangat membantu.

Chris O
sumber
2

Pastikan Anda menyetel Build Platform Target ke x86 atau x64 sehingga kompatibel dengan DLL Anda - yang mungkin dikompilasi untuk platform 32 bit.

Terima kasih
sumber
2

Jika proyek DLL dan .NET berada dalam solusi yang sama dan Anda ingin mengompilasi dan menjalankan keduanya setiap saat, Anda dapat mengklik kanan properti proyek .NET, Bangun acara, lalu tambahkan sesuatu seperti berikut ini ke acara Pasca-bangun garis komando:

copy $(SolutionDir)Debug\MyOwn.dll .

Ini pada dasarnya adalah garis DOS, dan Anda dapat menyesuaikan berdasarkan di mana DLL Anda dibuat.

SharpC
sumber
2

Saya mengalami masalah yang sama saat menerapkan aplikasi saya untuk menguji PC. Masalahnya adalah PC pengembangan memiliki msvcp110d.dlldan msvcr110d.dllbukan PC uji.

Saya menambahkan modul gabungan "Visual Studio C ++ 11.0 DebugCRT (x86)" di InstalledSheild dan berhasil. Semoga ini bisa membantu orang lain.

kakopappa.dll
sumber
2

Dalam kasus saya, satu dll yang tidak dikelola tergantung pada yang lain yang hilang. Dalam hal ini kesalahan akan mengarah ke dll yang ada, bukan yang hilang yang bisa sangat membingungkan.

Persis seperti itulah yang terjadi dalam kasus saya. Semoga ini bisa membantu orang lain.

Rahatur
sumber
1

Saya pikir perpustakaan Anda yang tidak dikelola membutuhkan manifes.
Berikut adalah cara menambahkannya ke biner Anda. dan di sini alasannya.

Singkatnya, beberapa versi pustaka yang Dapat Didistribusikan Ulang dapat diinstal di kotak Anda tetapi hanya satu dari mereka yang harus memenuhi Aplikasi Anda, dan ini mungkin bukan default, jadi Anda perlu memberi tahu sistem versi yang dibutuhkan pustaka Anda, itulah alasan manifes.

Eugenio Miró
sumber
1

Pengaturan : 32-bit Windows 7

Konteks : Menginstal driver PCI-GPIB yang tidak dapat saya hubungi karena masalah yang disebutkan di atas.

Jawaban singkat : Instal ulang driver.

Jawaban Panjang : Saya juga menggunakan Dependency Walker , yang mengidentifikasi beberapa modul dependensi yang hilang. Tiba-tiba, saya pikir itu pasti penginstalan driver yang gagal. Saya tidak ingin memeriksa dan memulihkan setiap file yang hilang.

Fakta bahwa saya tidak dapat menemukan uninstaller di bawah Program dan Fitur Panel Kontrol adalah indikator lain dari instalasi yang buruk. Saya harus secara manual menghapus beberapa * .dll di \ system32 dan kunci registri untuk memungkinkan penginstalan ulang driver.

Masalah diperbaiki.

Bagian yang tidak terduga adalah tidak semua modul dependensi diselesaikan. Namun demikian, * .dll minat sekarang dapat direferensikan.

icernos.dll
sumber
1

Saya telah menemukan masalah yang sama, Dalam kasus saya, saya memiliki dua buah 32 bit. Satu dengan .NET4.5 diinstal dan yang lainnya adalah PC baru.

dll cpp 32-bit saya (Build mode build) berfungsi dengan baik dengan PC yang terinstal .NET tetapi Tidak dengan PC baru di mana saya mendapat kesalahan di bawah ini

Tidak dapat memuat DLL 'PrinterSettings.dll': Modul yang ditentukan tidak dapat ditemukan. (Pengecualian dari HRESULT: 0x8007007E)

akhirnya,

Saya baru saja membangun proyek saya dalam konfigurasi mode Debug dan kali ini dll cpp saya berfungsi dengan baik.

Abu Muhammad
sumber
0

Juga menghadapi masalah yang sama saat menggunakan file c / c ++ dll yang tidak dikelola di lingkungan c #.

1.Periksa kompatibilitas dll dengan CPU 32bit atau 64bit.

2. Memeriksa jalur yang benar dari folder DLL .bin, system32 / sysWOW64, atau jalur yang diberikan.

3. Dicentang apakah file PDB (Program Database) hilang. Video ini memberi Anda pemahaman terbaik tentang file pdb.

Saat menjalankan kode biner 32-bit C / C ++ dalam sistem 64bit, hal ini dapat terjadi karena ketidakcocokan platform. Anda dapat mengubahnya dari Build> Configuration manager.

Yuresh Karunanayake
sumber
0

Saya menghadapi masalah yang sama ketika mengimpor C ++ Dll di .Net Framework +4, saya tidak mencentang Project-> Properties-> Build-> Lebih suka 32-bit dan itu diselesaikan untuk saya.

Mamo Ghandi
sumber