ฉันจะกำจัดปัญหา“ DLL ที่หายไป” ได้อย่างไร


15

ฉันสร้างเกมด้วย Visual C ++ 2015 และ OpenGL เมื่อฉันวิ่งมันบนเครื่องของฉันก็ไม่มีปัญหา แต่เมื่อฉันวิ่งมันบนเครื่องอื่น ๆ มันแสดงให้เห็นว่า DLLs บางอย่างหายไป ฉันต้องการทราบวิธีการตรวจสอบให้แน่ใจว่าจะไม่เกิดขึ้นในครั้งต่อไปและฉันควรพิจารณาเรื่องใดบ้างเพื่อหลีกเลี่ยงปัญหาไฟล์หายไป


8
ขั้นแรกตรวจสอบให้แน่ใจว่าคุณกำลังสร้างรุ่นที่วางจำหน่าย
user253751

3
หากคุณต้องการแน่ใจว่าไม่มีการอ้างอิงจาก VS เอง - แต่มันมาพร้อมกับข้อเสียของตัวเอง - ในการตั้งค่าการสร้างรหัสคุณสามารถเลือกที่จะไปกับ Multi Threaded / Multi Threaded Debug (สำหรับ debug builds) แทน MT DLL / มอนแทนา Debug DLL มันเพิ่มขนาดปฏิบัติการของคุณและไบนารีของคุณรวบรวมในลักษณะนี้จะไม่ได้รับประโยชน์จากการปรับปรุงที่กำลังรันไทม์ แต่นั่นขึ้นอยู่กับคุณ ด้านบวกที่ปฏิบัติการของคุณจะไม่มีการอ้างอิง "ภายนอก" ฉันจะไม่โพสต์สิ่งนี้เป็นคำตอบเพราะนี่ไม่ใช่วิธีแก้ปัญหาของคุณ แต่เป็นวิธีแก้ปัญหา
Gizmo

@Gizmo การแก้ไขปัญหายังคงเป็นคำตอบและความคิดเห็นเป็นการชั่วคราวและใช้เพื่อชี้แจงโพสต์ที่อยู่ภายใต้และอาจถูกลบ ดังนั้นหากมีประโยชน์คุณควรโพสต์เป็นคำตอบ
user1306322

หืมไม่เป็นไร ฉันจะโพสต์มันเป็นคำตอบแล้ว
Gizmo

คำตอบ:


22

คุณต้องติดตั้ง redistributables สำหรับเวอร์ชันของ Visual Studio ที่คุณใช้กับเครื่องที่ต้องการเรียกใช้งานโปรแกรมเช่นhttps://www.microsoft.com/en-us/download/details.aspx?id=48145สำหรับ VS2015 . คุณอาจต้อง redists สำหรับ DirectX หรือส่วนประกอบอื่น ๆ

โดยทั่วไปตัวติดตั้งแอปพลิเคชันจะติดตั้ง redistributables ทั้งหมดสำหรับการอ้างอิงใด ๆ คุณสามารถสร้างตัวติดตั้งด้วย InnoSetup, NSIS, WIX หรือเครื่องมืออื่น ๆ

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


เป็นไปได้ไหมที่จะใช้ VS เพื่อสร้างตัวติดตั้งแบบนี้? ฉันคิดว่าฉันเห็นสิ่งที่เรียกว่า OneClick ในการตั้งค่าโครงการหนึ่งครั้ง
user1306322

@ user1306322: อย่างแน่นอนมีการพูดถึงวิธีแก้ไขปัญหาหนึ่งในความคิดเห็นของคำถามโดย Gizmo เป็นเพียงเรื่องของ runtimes / DLLs ที่คุณเชื่อมโยง การตั้งค่าเริ่มต้นทำให้คุณเชื่อมโยงกับ CRT DLL เฉพาะรุ่น แต่สามารถเปลี่ยนแปลงได้โดยการจับคู่ในตัวเลือกตัวเชื่อมโยง เพียงเชื่อมโยงกับMSVCRT.DLL(มาพร้อมกับ Windows เอง) แทนMSVCPxxx.DLL(เฉพาะรุ่นที่มาพร้อมกับ Visual Studio รีลีส)
Sean Middleditch

หรือถ้าคุณหมายถึงการสร้างโปรแกรมติดตั้งที่สมบูรณ์นั่นคือสิ่งที่WIXเป็น มันเป็น crapfest ของ Microsoft XML ที่มีความซับซ้อนสูงโดยทั่วไป แต่ก็ใช้งานได้ นอกจากนี้ยังใช้ในการเป็น "การติดตั้งโครงการ" แต่ผมเชื่อว่าเหล่านี้จะหายไปตั้งแต่ 2013 หรือปี 2015
ฌอน Middleditch

7

ฉันใช้Dependency Walkerเพื่อติดตาม DLL ที่หายไป:

การพึ่งพา Walker ยังมีประโยชน์อย่างมากสำหรับการแก้ไขข้อผิดพลาดของระบบที่เกี่ยวข้องกับการโหลดและการใช้งานโมดูล Walker พึ่งพาตรวจพบปัญหาทั่วไปของแอปพลิเคชันเช่นโมดูลที่หายไปโมดูลที่ไม่ถูกต้องข้อผิดพลาดในการนำเข้า / ส่งออกข้อผิดพลาดในการพึ่งพาแบบวนรอบประเภทของโมดูลที่ไม่ตรงกันของโมดูลและโมดูลเริ่มต้นล้มเหลว


นอกจากนี้ยังมีตัวเลือกเวลารวบรวมใน VS เพื่อเชื่อมโยง DLL ของสแตติก :

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

1
วอล์คเกอร์พึ่งพาค่อนข้างเก่า มันไม่ได้เลียนแบบกลไกของ Windows ในการโหลด DLLs อีกต่อไป มักจะนำไปสู่ข้อความปลอมเกี่ยวกับการไม่สามารถหา DLLs
jpmc26

และการเชื่อมโยงทางสถิติอาจถูกห้ามในใบอนุญาตของการพึ่งพา
KeyWeeUsr

6

สำหรับ Visual C ++ คุณมีตัวเลือกไม่กี่วิธีในการจัดการการกระจายซ้ำ: รัน EXE จากตัวติดตั้งของคุณ (มีสิทธิ์ของผู้ดูแลระบบ) ใช้โมดูลผสาน MSM กับตัวติดตั้ง MSI ของคุณหรือแม้แต่ DLLs เคียงข้างกัน ดูMSDNสำหรับรายละเอียด

ปัญหาที่ใหญ่กว่าคือ OpenGL OpenGL เวอร์ชันเดียวที่มาพร้อมกับ Windows เป็นตัวแสดงซอฟต์แวร์ OpenGL 1.5 สิ่งอื่นใดต้องมีการติดตั้ง ICD ของบุคคลที่สาม

นี่คือหนึ่งในเหตุผลที่เกม Windows จำนวนมากใช้ DirectX แทนเนื่องจากมาพร้อมกับระบบปฏิบัติการ ดูการปรับใช้ Direct3D 11 สำหรับนักพัฒนาเกมและการตั้งค่าโดยตรงไม่ได้


1
คำแนะนำของ OpenGL นั้นล้าสมัย - ไดรเวอร์กราฟฟิกที่ทันสมัยทุกตัวมาพร้อมกับ OpenGL ICD ที่ทันสมัย
user253751

ฉันเองต้องติดตั้ง DLL ของ OpenGL บนเครื่องที่อายุน้อยกว่าหนึ่งปี
Gnemlock

@Gnemlock ทันทีที่ติดตั้ง Windows ใหม่บนคอมพิวเตอร์เครื่องเก่าปีดังกล่าวคุณอาจพูดถูก คุณยังคงพบปัญหานี้หลังจากติดตั้งแพคเกจไดรเวอร์อย่างเป็นทางการจาก NVIDIA, AMD หรือ Intel หรือไม่
Damian Yerrick

2
@Gememlock - หากคุณติดตั้ง OpenGL DLLs ด้วยตนเองคุณกำลังทำอะไรผิดปกติที่น่ากลัว หากคุณหมายถึง "ติดตั้งไดรเวอร์ของผู้จำหน่าย GPU ของคุณ" นั่นก็เป็นสิ่งที่ Immibis พูดเช่นกัน
Maximus Minimus

@ Genemlock - โอ้ดังนั้นจึงไม่เกี่ยวข้องกับโลกแห่งความเป็นจริงแล้ว ขอบคุณที่ล้างข้อมูล
Maximus Minimus

1

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

หากคุณต้องการแน่ใจว่าไม่มีการอ้างอิงจาก VS เอง - แต่มาพร้อมกับข้อเสียของตัวเอง - ในการตั้งค่าการสร้างรหัสคุณสามารถเลือกที่จะไปกับ Multi Threaded (MT) / Multi Threaded Debug (MD) (สำหรับการสร้างการดีบัก ) แทน MT DLL (MTd) / MT Debug DLL (MDd)

ป้อนคำอธิบายรูปภาพที่นี่

ข้อเสียคืออะไร?

  • มันจะเพิ่มขนาดที่สามารถใช้งานได้และไบนารี่ของคุณ (แม้ว่าถ้าคุณกำลังสร้างเกมนี่อาจจะเล็กน้อย)
  • รวบรวมในลักษณะนี้จะไม่ได้รับประโยชน์จากการปรับปรุงที่กำลังรันไทม์ (เช่นถ้า Microsoft ออก VC ++ 2015 SP2, SP3, SP4 เป็นต้น) แต่นั่นก็ขึ้นอยู่กับคุณแล้ว
  • การใช้ RAM เพิ่มเติม (ไม่สำคัญ) เนื่องจากคุณไม่ได้ใช้รหัสที่โหลด / โหลดอยู่ (DLL) อีกครั้ง
  • คุณต้องแน่ใจว่าไลบรารีทั้งหมดที่คุณเชื่อมโยงถูกคอมไพล์กับรันไทม์เดียวกันการเชื่อมโยงอื่นอาจล้มเหลวหรือข้อผิดพลาดรันไทม์ที่น่าสนใจอาจเกิดขึ้น (อาจไม่ใช่ แต่มันเกิดขึ้นกับฉันครั้งเดียวในชีวิตในโครงการแบบดั้งเดิมที่อัปเดตเป็น VS ใหม่ล่าสุด)

และอะไรคือข้อดี?

  • ปฏิบัติการของคุณจะไม่มีการพึ่งพา "ภายนอก" จาก VS ตัวเอง (ไม่มีข้อกำหนด msvc * .dll)
  • บางคนเห็นว่านี่เป็นการเพิ่มประสิทธิภาพเนื่องจากคุณกำลังกำจัดค่าใช้จ่ายในการเรียก DLL ในขณะที่นี่เป็นความจริงตามหลักทฤษฏีการปรับปรุงนั้นเล็กน้อยในทางปฏิบัติ

ตรวจสอบที่ลิงค์นี้เพื่อดูคำอธิบายที่ละเอียดยิ่งขึ้นและสำหรับข้อผิดพลาดและความล้มเหลวที่คุณอาจพบโดยใช้รันไทม์แบบคงที่

วิธีแก้ปัญหาอื่นคือการวาง DLL ที่จำเป็นทั้งหมดไว้ในที่ซึ่งไบนารีของคุณอยู่ แอปพลิเคชันของคุณจะไม่ได้รับประโยชน์จากการอัปเดต (ไปยังไลบรารีรันไทม์) แต่ก็เป็นได้

ทางออกที่แท้จริงคือการกระจายแอปพลิเคชันในโหมด release / non debug dll (MTd) และจัดหาตัวติดตั้งที่แจกจ่ายต่อได้ VC ++ ที่ถูกต้อง (และตัวติดตั้งไลบรารีอื่น ๆ ที่คุณอาจใช้เช่น OpenAL, DirectX9, PhysX) ก่อนเรียกใช้แอปพลิเคชันของคุณ (ตามคำตอบอื่น ๆ ที่ชี้ให้เห็น)

นอกจากนี้ตรวจสอบให้แน่ใจว่าผู้ใช้ทราบว่าเขา / เธออาจจำเป็นต้องอัปเดตไดรเวอร์ GPU ของตน (เนื่องจากมีหลาย runtimes สำหรับแอพพลิเคชั่นมากมายเช่น OpenGL, Vulcan)


0

ทางออกของฉันคือการคัดลอกและวาง DLL ที่ทำให้เกิดข้อผิดพลาดในโฟลเดอร์ที่ไฟล์. sln ตั้งอยู่ในสตูดิโอภาพ หลังจาก#includeส่วนฉันเขียน#pragma comment (lib, "lost DLL name with .dll")และแก้ไขมัน!

หมายเหตุ: ฉันแก้ปัญหาที่ฉันพบกับไลบรารีของบุคคลที่สาม (API vulkan) อาจจะไม่เป็นที่รู้จัก แต่ 90% จะได้ผลดี :)

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