2011-03-30 13 views
33

एक डीएलएल फ़ाइल को देखते हुए, मैं उस डीएलएल फ़ाइल के भीतर किसी विधि को सभी कॉल ढूंढने में सक्षम होना चाहता हूं। मैं यह कैसे कर सकता हूँ?सी # प्रतिबिंब और सभी संदर्भों को ढूंढना

अनिवार्य रूप से, मैं प्रोग्राम्सैटिक रूप से कैसे कर सकता हूं जो विजुअल स्टूडियो पहले से ही करता है?

मैं ऐसा करने के लिए .NET Reflector जैसे टूल का उपयोग नहीं करना चाहता, लेकिन प्रतिबिंब ठीक है और शायद आवश्यक है।

+2

क्या आपको विधि में केवल स्थिर कॉल का पता लगाने की आवश्यकता है? प्रतिबिंब और प्रतिबिंब एमिट के साथ कॉल करना चाहिए पता भी? –

+0

और यह काम गैर-प्रबंधित कोड के साथ होना चाहिए? सभी डीएलएल प्रतिबिंब का समर्थन नहीं करते हैं। –

+1

@ डारिन: वे केक पर आइसिंग करेंगे, लेकिन आवश्यक नहीं हैं। @ जेम्स: मुझे नहीं लगता कि मुझे गैर-प्रबंधित कोड के बारे में चिंता करने की ज़रूरत है। मैं उन डीएलएस पर ऐसा कैसे कर सकता हूं जो प्रतिबिंब का समर्थन नहीं करते हैं? – user420667

उत्तर

43

यह पता लगाने के लिए कि MyClass.Foo() विधि का उपयोग करने के लिए, आपको उन सभी असेंबली के सभी वर्गों का विश्लेषण करना होगा जिनमें MyClass शामिल असेंबली का संदर्भ है। मैंने इस कोड को कैसा दिख सकता है इस बारे में अवधारणा का एक सरल सबूत लिखा है।मेरे उदाहरण में मैं this library इस्तेमाल किया (यह सिर्फ a single .cs file है) जेबी Evain द्वारा लिखित:

मैं विश्लेषण करने के लिए एक छोटे से परीक्षण वर्ग ने लिखा है:

public class TestClass 
{ 
    public void Test() 
    { 
     Console.WriteLine("Test"); 
     Console.Write(10); 
     DateTime date = DateTime.Now; 
     Console.WriteLine(date); 
    } 
} 

और मैं सभी TestClass.Test() भीतर इस्तेमाल किया तरीकों का प्रिंट आउट के लिए इस कोड लिखा था :

System.Console.WriteLine(System.String value); 
System.Console.Write(System.Int32 value); 
System.DateTime.get_Now(); 
System.Console.WriteLine(System.Object value); 
012:

MethodBase methodBase = typeof(TestClass).GetMethod("Test"); 
var instructions = MethodBodyReader.GetInstructions(methodBase); 

foreach (Instruction instruction in instructions) 
{ 
    MethodInfo methodInfo = instruction.Operand as MethodInfo; 

    if(methodInfo != null) 
    { 
     Type type = methodInfo.DeclaringType; 
     ParameterInfo[] parameters = methodInfo.GetParameters(); 

     Console.WriteLine("{0}.{1}({2});", 
      type.FullName, 
      methodInfo.Name, 
      String.Join(", ", parameters.Select(p => p.ParameterType.FullName + " " + p.Name).ToArray()) 
     ); 
    } 
} 

यह मुझे निम्न उत्पादन दे दी है

यह उदाहरण स्पष्ट रूप से पूर्ण से दूर है, क्योंकि यह रेफरी और आउट पैरामीटर को संभाल नहीं करता है, और यह सामान्य तर्कों को संभाल नहीं करता है। मुझे यकीन है कि अन्य विवरणों के बारे में भी भूल गए हैं। यह सिर्फ दिखाता है कि यह किया जा सकता है।

+0

अच्छा। यह चुनिंदा कथन के लिए लिंक का भी उपयोग करता है। मुझे कुछ निर्भरता ग्राफ बनाने का समय। – user420667

+0

मुझे यह त्रुटि संदेश मिल रहा है: "मान अपेक्षित सीमा के भीतर नहीं आता है।" कोड के इस बिट से: 'this.body = method.GetMethodBody(); अगर (this.body == null) नया ArgumentException(); फेंक दें; और मैं सोच रहा हूं कि शरीरहीन तरीके कैसे हो सकते हैं (या और क्या हो सकता है)। कोई विचार? – ekkis

+1

@ekkis: एक अमूर्त विधि (एक अमूर्त वर्ग का) शरीरहीन है। आप 'MethodBase.IsAbstract' को चेक करके विधि जांच सकते हैं या नहीं। –

-1

स्टैक ओवरफ़्लो प्रश्न Get a list of functions for a DLL देखें।

ऊपर (धन्यवाद जॉन स्कीट) से Ripped:

एक विशेष विधानसभा के लिए, आप (प्रत्येक प्रकार के कॉल Type.GetMethods के लिए तो प्रकार प्राप्त करने के लिए, Assembly.GetTypes उपयोग कर सकते हैं), Type.GetProperties() आदि, या बस Type.GetMembers()।

हालांकि, प्लगइन कार्यक्षमता के लिए आमतौर पर प्लगइन को लागू करने के लिए एक सामान्य इंटरफ़ेस होना एक अच्छा विचार है - जो आपको उपयोग करने के लिए आवश्यक प्रतिबिंब की मात्रा को कम करता है। किसी विशेष इंटरफ़ेस के साथ एक प्रकार संगत है या नहीं, यह जांचने के लिए Type.IsAssignableFrom() का उपयोग करें।

आप प्रबंधित एक्सटेंसिबिलिटी फ्रेमवर्क को भी देखना चाहते हैं जो एक विस्तार प्रणाली को कार्यान्वित कर सकता है।

+2

मुझे नहीं पता कि यह उत्तर किसी दिए गए विधि को कॉल खोजने में कैसे मदद करता है। यह एक लक्षित असेंबली में सूची प्रकार, विधियों, गुणों आदि की सहायता करता है, लेकिन ओपी यह पता लगाने का एक तरीका ढूंढ रहा है कि एक दी गई विधि किसी अन्य विधि को कॉल कर रही है। –

+0

यह वही नहीं है जो ओपी पूछ रहा है। –

+0

यह ओपी की तलाश में नहीं है। यह विधियों को सूचीबद्ध करता है, लेकिन उनके आमंत्रण नहीं। – jason

1

मैं विजुअल स्टूडियो असेंबली को प्रतिबिंबित करने पर विचार करता हूं और देखता हूं कि आप इसे रिवर्स इंजीनियर कोड बेस में पा सकते हैं या नहीं। मेरा मानना ​​है कि वीएस वास्तव में प्रतिबिंबित करने के बजाय कोड नेविगेट कर रहा है। जैसा कि माइकल ने पोस्ट किया है, प्रतिबिंब, एक असेंबली के बिट्स को निर्धारित करने के लिए बहुत अच्छा है, लेकिन उन बिट्स के उपभोक्ताओं को नहीं। हालांकि, मैंने अपने संदेह की पुष्टि करने के लिए प्रतिबिंब की पुन: जांच नहीं की है।

2

आप एमएसडीएन पत्रिका लेख Determining .NET Assembly and Method References पर एक नज़र डाल सकते हैं।

+0

+1: ध्यान दें कि आपको आईएल रीडर के लिए कुछ खोजना होगा - रिफ्लेक्टर का एक सीधे उपलब्ध नहीं है जहां तक ​​मैं बता सकता हूं ... –

+0

अच्छा लेख। लेकिन यह विधि निर्भरताओं के लिए परावर्तक का उपयोग करने का सुझाव देता है। मुझे लगता है कि वे सभी आईएल पार्स करने के लिए उबाल लें। – user420667

3

अकेले प्रतिबिंब किसी दिए गए असेंबली में किसी विधि के सभी संदर्भों को खोजने के लिए पर्याप्त नहीं है। प्रतिबिंब आपको किसी विशेष विधि (MethodInfo.GetMethodBody.GetILAsByteArray) के शरीर के लिए बाइट सरणी देता है और आपको इसे अन्य विधियों के संदर्भों के लिए स्वयं पार्स करना होगा। कई सार्वजनिक रूप से उपलब्ध हैं "CIL पाठक" पुस्तकालय (मैंने उनका उपयोग नहीं किया है - उम्मीद है कि कोई इस पर अधिक पोस्ट करेगा)।

जोड़ना FxCop विकल्प - अपने परिदृश्य के आधार पर, आप सीआईएल को पार्स FxCop (विजुअल स्टूडियो कोड विश्लेषण) द्वारा प्रदान की तर्क का पुन: उपयोग और अपने कस्टम नियम जोड़ने अगर कोड विश्लेषण के भाग के रूप में यह चल रहा है आप के लिए ठीक है करने में सक्षम हो सकता है।

संबंधित मुद्दे