ฉันจะแสดงรายการส่วนประกอบที่โหลดทั้งหมดได้อย่างไร


101

ใน. Net ฉันต้องการระบุแอสเซมบลีที่โหลดทั้งหมดบน AppDomains ทั้งหมด ทำมันสำหรับโปรแกรมของฉัน AppDomain AppDomain.CurrentDomain.GetAssemblies()เป็นเรื่องง่ายพอ ฉันจำเป็นต้องเข้าถึงทุก AppDomain หรือไม่? หรือมีเครื่องมือที่ทำสิ่งนี้อยู่แล้ว?


1
โปรดทราบว่าGetAssemblies()จะไม่ทำงานเนื่องจากจะไม่เกิดซ้ำและจะพลาดการอ้างอิงแอสเซมบลีที่ซ้อนกัน ฉันได้เพิ่มรุ่น recursive ของGetAssemblies()ที่stackoverflow.com/questions/383686/...
Contango

@Contango: AppDomain.CurrentDomain.GetAssemblies()เป็นอย่างดี ไม่จำเป็นต้องดำเนินการอ้างอิงซ้ำเพราะไม่ได้แจกแจงการอ้างอิงตั้งแต่แรก
Ben Voigt

คำตอบ:


98

ใช้ Visual Studio

  1. แนบดีบักเกอร์เข้ากับกระบวนการ (เช่นเริ่มต้นด้วยการดีบักหรือดีบัก> แนบกับกระบวนการ)
  2. ขณะทำการดีบักให้แสดงหน้าต่างโมดูล (Debug> Windows> Modules)

ข้อมูลนี้ให้รายละเอียดเกี่ยวกับแต่ละแอสเซมบลีโดเมนแอปและมีตัวเลือกสองสามตัวในการโหลดสัญลักษณ์ (เช่นไฟล์ pdb ที่มีข้อมูลการดีบัก)

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

ใช้ Process Explorer

หากคุณต้องการเครื่องมือภายนอกคุณสามารถใช้Process Explorer (ฟรีแวร์เผยแพร่โดย Microsoft)

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

โดยใช้โปรแกรม

ตรวจสอบคำถามSO นี้ที่อธิบายวิธีการทำ


2
จะดีกว่าที่อธิบายไว้ที่นี่เพราะในหน้าคุณสมบัติของกระบวนการ Process Explorer จะแสดงแอสเซมบลีของ AppDomain (รวมถึง 'โดเมนที่ใช้ร่วมกัน') อย่างชัดเจน ดังนั้นจึงแสดงให้เห็นมากกว่าที่จะโหลด. dll ในกระบวนการ คงจะดีไม่น้อยหากทราบว่าพวกเขาใช้ API ใดเพื่อแสดงสิ่งนี้ (ลิงก์ "แบบเป็นโปรแกรม" จะให้แอสเซมบลีใน CurrentDomain)
Govert

22

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

foreach(System.Reflection.AssemblyName an in System.Reflection.Assembly.GetExecutingAssembly().GetReferencedAssemblies()){                      
            System.Reflection.Assembly asm = System.Reflection.Assembly.Load(an.ToString());
            foreach(Type type in asm.GetTypes()){   
                //PROPERTIES
                foreach (System.Reflection.PropertyInfo property in type.GetProperties()){
                    if (property.CanRead){
                        Response.Write("<br>" + an.ToString() + "." + type.ToString() + "." + property.Name);       
                    }
                }
                //METHODS
                var methods = type.GetMethods();
                foreach (System.Reflection.MethodInfo method in methods){               
                    Response.Write("<br><b>" + an.ToString() + "."  + type.ToString() + "." + method.Name  + "</b>");   
                    foreach (System.Reflection.ParameterInfo param in method.GetParameters())
                    {
                        Response.Write("<br><i>Param=" + param.Name.ToString());
                        Response.Write("<br>  Type=" + param.ParameterType.ToString());
                        Response.Write("<br>  Position=" + param.Position.ToString());
                        Response.Write("<br>  Optional=" + param.IsOptional.ToString() + "</i>");
                    }
                }
            }
        }

btw ... ฉันแยกมันออกจากโพสต์เริ่มต้น แต่ฉันกรองคำตอบบางส่วนออกไปforeach(Type type in asm.GetTypes()){ if ((type.ToString().IndexOf("ACLASSIMLOOKINGFOR")>=0) || (type.ToString().IndexOf("BCLASSIMLOOKINGFOR")>=0)){...
s15199d

2
นี่ไม่ตอบคำถามเลย
Govert

แทนที่จะใช้ GetExecutingAssembly () ฉันใช้ GetEntryAssembly () เพื่อให้แน่ใจว่าฉันได้รับรายการแอสเซมบลีที่ดีกว่าที่โปรแกรมของฉันใช้ ถ้า ExecutingAssembly เป็น DLL ฉันจะพลาดบางส่วนไป
Harry Glinos

6
ลองใช้: Assembly [] แอสเซมบลี = AppDomain.CurrentDomain.GetAssemblies ();
DanW
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.