จะรับตำแหน่งของ DLL ที่กำลังดำเนินการอยู่ได้อย่างไร?


94

ฉันมีไฟล์กำหนดค่าที่ฉันต้องโหลดเพื่อเป็นส่วนหนึ่งของการเรียกใช้งาน dll ที่ฉันกำลังเขียน

ปัญหาที่ฉันพบคือตำแหน่งที่ฉันใส่ไฟล์ dll และ config ไม่ใช่ "ตำแหน่งปัจจุบัน" เมื่อแอปกำลังทำงาน

ตัวอย่างเช่นฉันใส่ไฟล์ dll และ xml ที่นี่:

D: \ Program Files \ Microsoft Team Foundation Server 2010 \ Application Tier \ Web Services \ bin \ Plugins

แต่ถ้าฉันพยายามอ้างอิงไฟล์ xml (ใน dll ของฉัน) เช่นนี้:

XDocument doc = XDocument.Load(@".\AggregatorItems.xml")

จากนั้น\ AggregatorItems.xmlแปลเป็น:

C: \ windows \ system32 \ inetsrv \ AggregatorItems.xml

ดังนั้นฉันต้องหาวิธี (ฉันหวังว่า) ในการรู้ว่า dll ที่กำลังดำเนินการอยู่นั้นอยู่ที่ไหน โดยทั่วไปฉันกำลังมองหาสิ่งนี้:

XDocument doc = XDocument.Load(CoolDLLClass.CurrentDirectory+@"\AggregatorItems.xml")

คำตอบ:


140

คุณกำลังมองหา System.Reflection.Assembly.GetExecutingAssembly()

string assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string xmlFileName = Path.Combine(assemblyFolder,"AggregatorItems.xml");

บันทึก:

.Locationคุณสมบัติผลตอบแทนสถานที่ตั้งของไฟล์ DLL ที่ทำงานอยู่ในปัจจุบัน

ภายใต้เงื่อนไขบางประการ DLL จะถูกคัดลอกก่อนที่จะดำเนินการและ.Locationคุณสมบัติจะส่งคืนเส้นทางของสำเนา หากคุณต้องการเส้นทางของ DLL ดั้งเดิมให้ใช้Assembly.GetExecutingAssembly().CodeBaseคุณสมบัติแทน

.CodeBaseมีคำนำหน้า ( file:\) ซึ่งคุณอาจต้องลบออก


8
อนิจจา ผลตอบแทนนั้นC:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\Temporary ASP.NET Files\\tfs\\de3c0c8e\\c1bdf790\\assembly\\dl3\\20b156cb\\22331f24_bfb9cb01\\AggregatorItems.xml
Vaccano

23
อา! แต่Assembly.GetExecutingAssembly().CodeBaseมี!
Vaccano

2
CodeBase ให้ไฟล์: \\ c: \ myassemblypath ซึ่งแปลกมาก
Matt

10
@Matt ใช้ Uri ใหม่ (Assembly.GetExecutingAssembly (). CodeBase) .LocalPath เพื่อรับชื่อจริง
Larry

2
string curAssemblyFolder = new System.Uri(System.Reflection.Assembly.GetExecutingAssembly().CodeBase).LocalPath;
Martin Connell

37

การสะท้อนกลับเป็นเพื่อนของคุณดังที่ได้กล่าวไปแล้ว แต่คุณต้องใช้วิธีการที่ถูกต้อง

Assembly.GetEntryAssembly()     //gives you the entrypoint assembly for the process.
Assembly.GetCallingAssembly()   // gives you the assembly from which the current method was called.
Assembly.GetExecutingAssembly() // gives you the assembly in which the currently executing code is defined
Assembly.GetAssembly( Type t )  // gives you the assembly in which the specified type is defined.

16

ในกรณีของฉัน (จัดการกับแอสเซมบลีของฉันที่โหลด [เป็นไฟล์] ลงใน Outlook):

typeof(OneOfMyTypes).Assembly.CodeBase

สังเกตการใช้CodeBase(not Location) บนไฟล์Assembly. คนอื่น ๆ ได้ชี้ให้เห็นวิธีการอื่นในการระบุตำแหน่งการชุมนุม



1

หากคุณกำลังทำงานกับแอปพลิเคชัน asp.net และคุณต้องการค้นหาแอสเซมบลีเมื่อใช้ดีบักเกอร์พวกเขามักจะใส่ลงในไดเร็กทอรี temp ฉันเขียนวิธีนี้เพื่อช่วยในสถานการณ์นั้น

private string[] GetAssembly(string[] assemblyNames)
{
    string [] locations = new string[assemblyNames.Length];


    for (int loop = 0; loop <= assemblyNames.Length - 1; loop++)       
    {
         locations[loop] = AppDomain.CurrentDomain.GetAssemblies().Where(a => !a.IsDynamic && a.ManifestModule.Name == assemblyNames[loop]).Select(a => a.Location).FirstOrDefault();
    }
    return locations;
}

สำหรับรายละเอียดเพิ่มเติมโปรดดูที่บล็อกโพสต์นี้http://nodogmablog.bryanhogan.net/2015/05/finding-the-location-of-a-running-assembly-in-net/

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

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

ฉันได้เขียนคำอธิบายทั้งหมดเกี่ยวกับวิธีการทำ dll ใน IIS - http://nodogmablog.bryanhogan.net/2016/09/locating-and-checking-an-executing-dll-on-a-running-web - เซิร์ฟเวอร์ /

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