ไม่สามารถโหลด DLL (ไม่พบโมดูล HRESULT: 0x8007007E)


113

ฉันมีไลบรารี dll ที่มีรหัส C ++ API ที่ไม่มีการจัดการฉันจำเป็นต้องใช้ในแอปพลิเคชัน. NET 4.0 ของฉัน แต่ทุกวิธีที่ฉันพยายามโหลด dll ของฉันฉันได้รับข้อผิดพลาด:

ไม่สามารถโหลด DLL 'MyOwn.dll': ไม่พบโมดูลที่ระบุ (ข้อยกเว้นจาก HRESULT: 0x8007007E)

ฉันได้อ่านและลองใช้โซลูชันของ Severa ที่พบบนอินเทอร์เน็ตแล้ว ไม่มีอะไรทำงาน ..

ฉันได้ลองใช้วิธีการต่อไปนี้:

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

เมื่อฉันลองทำตามบทความนี้และเมื่อฉันเรียกใช้ตัวอย่างนี้ (จากรหัสที่ดาวน์โหลดมา) มันทำงานโดยไม่มีปัญหา (dll ที่ใช้อยู่ในโฟลเดอร์ bin / debug)

ฉันได้คัดลอก dll ของฉัน (พร้อมกับไฟล์ทั้งหมดซึ่งขึ้นอยู่กับลงในโฟลเดอร์ bin ของฉัน)

ฉันลองใช้วิธีนี้ด้วย แต่ได้รับข้อผิดพลาดเดียวกัน:

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

ข้อเสนอแนะใด ๆ ?

คำตอบ:


90

จากสิ่งที่ฉันจำได้ใน Windows ลำดับการค้นหา dll คือ:

  1. ไดเรกทอรีปัจจุบัน
  2. โฟลเดอร์ระบบC:\windows\system32 or c:\windows\SysWOW64(สำหรับกระบวนการ 32 บิตบนกล่อง 64 บิต)
  3. การอ่านจากPathตัวแปรสภาพแวดล้อม

นอกจากนี้ฉันจะตรวจสอบการอ้างอิงของ DLL ตัวช่วยในการพึ่งพาที่มาพร้อมกับ Visual Studio สามารถช่วยคุณได้ที่นี่สามารถดาวน์โหลดได้ฟรี: http://www.dependencywalker.com


4
พบว่าการพึ่งพาบางส่วนหายไป (Oracle และ dll บางส่วนจาก IE) จำเป็นต้องติดตั้ง Oracle เนื่องจาก dll ของฉันขึ้นอยู่กับว่า .. แล้วฉันจะรู้ :) พบปัญหากับ DependencyWalker;)
Ingimar Andresson

ไม่ต้องกังวลมันช่วยประหยัดเวลาในการเกาหัวได้หลายชั่วโมงสำหรับฉันเครื่องมือเล็ก ๆ ที่ยอดเยี่ยม! :-)
display101

1
+1 ให้ Keith Halligan เพื่อแนะนำ DependencyWalker มันบอกฉันว่าการอ้างอิงทั้งหมดไม่ได้มีประเภท CPU เดียวกัน (x86 / x64) ฉันคัดลอกไฟล์ทั้งหมดที่มี CPU ประเภทเดียวกันไปยังโฟลเดอร์ bin ของแอปพลิเคชันของฉันและนั่นช่วยแก้ปัญหาได้
DiligentKarma

6
ทุก dll ที่ฉันพบในระบบของฉันมี DependencyWalker อ้างว่ามีข้อผิดพลาดกับ CPU ประเภทต่างๆแม้แต่ System.Web.Mvc.dll มีสัญญาณเตือนที่ผิดพลาดอยู่ที่นี่
PandaWood

2
ในกรณีของฉันปัญหาคือพยายามโหลด C ++ DLL ที่คอมไพล์สำหรับ Debug ที่ต้องการรันไทม์การดีบัก C ++ ซึ่งหมายความว่าคุณต้องติดตั้ง Visual Studio หรือคอมไพล์ DLL ใหม่สำหรับรีลีสและติดตั้งรันไทม์ C ++ ที่แจกจ่ายได้
RenniePet

42

คุณสามารถใช้เครื่องมือ dumpbin เพื่อค้นหาการอ้างอิง DLL ที่จำเป็น:

dumpbin /DEPENDENTS my.dll

สิ่งนี้จะบอกคุณว่า DLL ของคุณต้องโหลด DLL ใด ระวัง MSVCR * .dll เป็นพิเศษ ฉันเห็นรหัสข้อผิดพลาดของคุณเกิดขึ้นเมื่อไม่ได้ติดตั้ง Visual C ++ Redistributable ที่ถูกต้อง

คุณสามารถรับ "Visual C ++ Redistributable Packages for Visual Studio 2013" จากเว็บไซต์ของ Microsoft มันติดตั้ง c: \ windows \ system32 \ MSVCR120.dll

ในชื่อไฟล์ 120 = 12.0 = Visual Studio 2013

โปรดระวังว่าคุณมี Visual Studio เวอร์ชันที่ถูกต้อง (10.0 = VS 10, 11 = VS 2012, 12.0 = VS 2013 ... ) สถาปัตยกรรมที่เหมาะสม (x64 หรือ x86) สำหรับแพลตฟอร์มเป้าหมายของ DLL ของคุณและคุณต้องระวังด้วย สร้างดีบัก การสร้างดีบักของ DLL ขึ้นอยู่กับ MSVCR120d.dll ซึ่งเป็นเวอร์ชันดีบักของไลบรารีซึ่งติดตั้งด้วย Visual Studio แต่ไม่ใช่โดย Redistributable Package


5
เพิ่ม VS C ++ redistributables สำหรับฉัน! จำเป็น v10.0 (2010) ขอบคุณ mucho !!!
Thiago Silva

มีวิธีใดบ้างที่จะบอกได้ว่าจำเป็นต้องแจกจ่ายเวอร์ชัน 64 บิตหรือ 32 บิต
BVB

1
dumpbin / ALL จะบอกคุณว่า my.dll เป็น x86 จาก x64 หรือไม่
Anthony Hayward

1
สำหรับผู้ที่ยังคงประสบปัญหานี้หากคุณใช้debugไบนารีเวอร์ชันที่แจกจ่ายต่อรันไทม์ C ++ จะต้องตรงกับที่คุณสร้างขึ้น
skyline75489

ความคิดเห็นของ @ skyline75489 บันทึกวันสำหรับฉัน ไลบรารี C ++ ทำงานได้ดีบนเครื่องของฉัน แต่ไม่สามารถโหลดได้ทุกที่เนื่องจาก VS เชื่อมโยงกับ msvcr เวอร์ชันดีบัก
สืบ

14

นี่คือ 'kludge' แต่อย่างน้อยคุณก็สามารถใช้เพื่อทดสอบความถูกต้อง: ลองเข้ารหัสเส้นทางไปยัง DLL ในโค้ดของคุณ

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

ต้องบอกว่า; ในกรณีของฉันทำงานdumpbin /DEPENDENTSตามที่แนะนำโดย @ anthony-hayward และการคัดลอกเวอร์ชัน32 บิตของ DLL ที่แสดงอยู่ในไดเรกทอรีการทำงานของฉันช่วยแก้ปัญหานี้ให้ฉันได้

ข้อความดังกล่าวทำให้เข้าใจผิดเล็กน้อยเนื่องจากไม่ใช่ dll "ของฉัน" ที่ไม่สามารถโหลดได้ - เป็นการอ้างอิง


12

DLL ต้องอยู่ในโฟลเดอร์ bin

ใน Visual Studio ฉันเพิ่ม dll ในโครงการของฉัน (ไม่ใช่ในการอ้างอิง แต่เป็น "เพิ่มไฟล์ที่มีอยู่") จากนั้นตั้งค่าคุณสมบัติ "Copy to Output Directory" สำหรับ dll เป็น "Copy if newer"


11

พยายามเข้าสู่เส้นทางเต็มของ dll หากไม่ได้ผลให้ลองคัดลอก dll ลงในโฟลเดอร์ system32


3
เป็นไปได้ไหมที่จะมีการพึ่งพาทั้งหมดในโฟลเดอร์ System32 และ dll ของฉันที่อื่น
Ingimar Andresson

การอ้างอิงจะถูกค้นหาตามลำดับเส้นทางการค้นหา dll ของ windows ตามที่ระบุโดยstackoverflow.com/a/9003290/4434329


4

มีสิ่งหนึ่งที่ตลกมาก (และมีความเกี่ยวข้องทางเทคนิค) ซึ่งอาจทำให้คุณเสียเวลาหลายชั่วโมงดังนั้นจึงต้องคิดแบ่งปันที่นี่ -

ฉันสร้างโปรแกรมประยุกต์คอนโซลโครงการและโครงการห้องสมุดชั้นConsoleApplication1ClassLibrary1

รหัสทั้งหมดที่สร้าง p / invoke มีอยู่ในClassLibrary1.dll. ดังนั้นก่อนที่จะดีบักแอปพลิเคชันจากสตูดิโอวิชวลฉันเพียงแค่คัดลอกแอสเซมบลีที่ไม่มีการจัดการ C ++ ( myUnmanagedFunctions.dll) ลงใน\bin\debug\ไดเร็กทอรีของClassLibrary1โปรเจ็กต์เพื่อให้ CLR สามารถโหลดได้ในขณะรันไทม์

ฉันได้รับไฟล์

ไม่สามารถโหลด DLL

ข้อผิดพลาดเป็นเวลาหลายชั่วโมง ต่อมาฉันตระหนักว่าแอสเซมบลีที่ไม่มีการจัดการทั้งหมดที่จะโหลดนั้นจำเป็นต้องคัดลอกลงใน\bin\debugไดเร็กทอรีของโปรเจ็กต์เริ่มต้นConsoleApplication1ซึ่งโดยปกติจะเป็นแบบฟอร์มวินคอนโซลหรือเว็บแอปพลิเคชัน

ดังนั้นโปรดใช้ความระมัดระวังCurrent Directoryในคำตอบที่ยอมรับจริงหมายถึงCurrent Directoryปฏิบัติการหลักจากจุดเริ่มต้นของกระบวนการสมัคร ดูเหมือนเป็นสิ่งที่ชัดเจน แต่บางครั้งอาจไม่เป็นเช่นนั้น

บทเรียนที่เรียนรู้ - วาง dll ที่ไม่มีการจัดการไว้ในไดเร็กทอรีเดียวกันกับไฟล์ปฏิบัติการเริ่มต้นเสมอเพื่อให้แน่ใจว่าสามารถค้นหาได้


สิ่งนี้คงที่สำหรับฉันเช่นกัน รู้สึกแปลก ๆ ที่ใส่ DLL ในโปรเจ็กต์หลักแทนที่จะเป็นโปรเจ็กต์ที่ใช้จริงๆแม้ว่า ...
Sean Duggan

@SeanDuggan นั่นเป็นเพราะเป็น "ไดนามิกลิงก์ไลบรารี" ซึ่งหมายความว่ามีการใช้ (โหลด) ในขณะรันซึ่งตรงข้ามกับไลบรารีแบบคงที่ที่ใช้ในเวลาเชื่อมโยง
m4l490n

ฉันได้พยายามเพิ่ม dll เข้าไปในbin\Debugและobj\Debugไดเรกทอรีและฉันให้รับ "ไม่สามารถโหลด DLL"
m4l490n

3

เปิดการบันทึกฟิวชันดูคำถามนี้เพื่อรับคำแนะนำมากมายเกี่ยวกับวิธีการทำเช่นนั้น การแก้ปัญหาการโหลดแอปโหมดผสมอาจเป็นความเจ็บปวดที่ถูกต้อง การบันทึกฟิวชั่นสามารถช่วยได้มาก


2

ตรวจสอบให้แน่ใจว่าคุณตั้งค่า Build Platform Target เป็น x86 หรือ x64 เพื่อให้เข้ากันได้กับ DLL ของคุณซึ่งอาจถูกคอมไพล์สำหรับแพลตฟอร์ม 32 บิต


2

หากโปรเจ็กต์ DLL และ. NET อยู่ในโซลูชันเดียวกันและคุณต้องการคอมไพล์และรันทั้งสองทุกครั้งคุณสามารถคลิกขวาที่คุณสมบัติของโปรเจ็กต์. NET, สร้างเหตุการณ์จากนั้นเพิ่มสิ่งต่อไปนี้ในเหตุการณ์หลังการสร้าง บรรทัดคำสั่ง:

copy $(SolutionDir)Debug\MyOwn.dll .

โดยพื้นฐานแล้วมันเป็นสาย DOS และคุณสามารถปรับแต่งตามตำแหน่งที่สร้าง DLL ของคุณได้


2

ฉันประสบปัญหาเดียวกันเมื่อติดตั้งแอปพลิเคชันเพื่อทดสอบพีซี แต่ปัญหาก็คือการพัฒนาเครื่องคอมพิวเตอร์ได้msvcp110d.dllและmsvcr110d.dllแต่ไม่ PC ทดสอบ

ฉันได้เพิ่มโมดูลผสาน "Visual Studio C ++ 11.0 DebugCRT (x86)" ใน InstalledSheild และใช้งานได้ หวังว่านี่จะเป็นประโยชน์สำหรับคนอื่น ๆ


2

ในกรณีของฉัน dll ที่ไม่มีการจัดการอันหนึ่งขึ้นอยู่กับอันอื่นที่หายไป ในกรณีนี้ข้อผิดพลาดจะชี้ไปที่ dll ที่มีอยู่แทนที่จะเป็นข้อผิดพลาดที่หายไปซึ่งอาจทำให้สับสนได้

นั่นคือสิ่งที่เกิดขึ้นในกรณีของฉัน หวังว่านี่จะช่วยคนอื่นได้


1

ฉันคิดว่าไลบรารีที่ไม่มีการจัดการของคุณจำเป็นต้องมีรายการ
นี่คือวิธีเพิ่มในไบนารีของคุณ และนี่คือเหตุผล

โดยสรุปแล้วไลบรารีที่แจกจ่ายต่อได้หลายเวอร์ชันสามารถติดตั้งได้ในกล่องของคุณ แต่มีเพียงเวอร์ชันเดียวเท่านั้นที่ตรงกับแอปของคุณและอาจไม่ใช่ค่าเริ่มต้นดังนั้นคุณต้องแจ้งให้ระบบทราบว่าไลบรารีของคุณต้องการเวอร์ชันใดนั่นเป็นสาเหตุของไฟล์ Manifest


1

การตั้งค่า : Windows 7 32 บิต

บริบท : ติดตั้งไดรเวอร์ PCI-GPIB ที่ฉันไม่สามารถสื่อสารได้เนื่องจากปัญหาดังกล่าวข้างต้น

คำตอบสั้น ๆ : ติดตั้งไดรเวอร์ใหม่

คำตอบแบบยาว : ฉันยังใช้Dependency Walkerซึ่งระบุโมดูลการพึ่งพาที่ขาดหายไปหลายโมดูล ทันทีฉันคิดว่ามันต้องเป็นการติดตั้งไดรเวอร์ที่ไม่สมบูรณ์ ฉันไม่ต้องการตรวจสอบและกู้คืนไฟล์ที่หายไปแต่ละไฟล์

ความจริงที่ว่าฉันไม่พบโปรแกรมถอนการติดตั้งภายใต้โปรแกรมและคุณสมบัติของแผงควบคุมเป็นอีกตัวบ่งชี้การติดตั้งที่ไม่ดี ฉันต้องลบ * .dll ใน \ system32 และคีย์รีจิสทรีสองสามรายการด้วยตนเองเพื่อให้สามารถติดตั้งไดรเวอร์ใหม่ได้

แก้ไขปัญหาแล้ว

ส่วนที่ไม่คาดคิดคือโมดูลการอ้างอิงทั้งหมดไม่ได้รับการแก้ไข อย่างไรก็ตามตอนนี้สามารถอ้างอิง * .dll ของดอกเบี้ยได้


1

ฉันเจอปัญหาเดียวกันในกรณีของฉันฉันมี 32 บิตสองชิ้น เครื่องหนึ่งที่ติดตั้ง. NET4.5 และอีกเครื่องหนึ่งเป็นพีซีใหม่

cpp dll 32 บิตของฉัน (รุ่นสร้างโหมด) ทำงานได้ดีกับพีซีที่ติดตั้ง. NET แต่ไม่ใช่กับพีซีใหม่ที่ฉันได้รับข้อผิดพลาดด้านล่าง

ไม่สามารถโหลด DLL 'PrinterSettings.dll': ไม่พบโมดูลที่ระบุ (ข้อยกเว้นจาก HRESULT: 0x8007007E)

ในที่สุด

ฉันเพิ่งสร้างโปรเจ็กต์ของฉันในการกำหนดค่าโหมดดีบักและคราวนี้ cpp dll ของฉันทำงานได้ดี


0

ยังประสบปัญหาเดียวกันเมื่อใช้ไฟล์ c / c ++ dll ที่ไม่มีการจัดการในสภาพแวดล้อม c #

1. ตรวจสอบความเข้ากันได้ของ dll กับ CPU 32 บิตหรือ 64 บิต

2. ตรวจสอบเส้นทางที่ถูกต้องของโฟลเดอร์ DLL .bin, system32 / sysWOW64 หรือเส้นทางที่กำหนด

3. ตรวจสอบว่าไฟล์ PDB (ฐานข้อมูลโปรแกรม) หายไปหรือไม่วิดีโอนี้ช่วยให้คุณได้รับสิ่งที่ดีที่สุดเกี่ยวกับไฟล์ pdb

เมื่อเรียกใช้รหัสไบนารี C / C ++ 32 บิตในระบบ 64 บิตอาจเกิดขึ้นเนื่องจากความไม่ลงรอยกันของแพลตฟอร์ม คุณสามารถเปลี่ยนได้จาก Build> Configuration manager


0

ฉันประสบปัญหาเดียวกันเมื่อนำเข้า C ++ Dll ใน. Net Framework +4 ฉันยกเลิกการเลือก Project-> Properties-> Build-> ต้องการ 32 บิตและแก้ไขให้ฉันได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.