2015-02-03 4 views
9

मेरे वीबी.नेट आवेदन में, ईवेंट AppDomain.CurrentDomain.AssemblyResolve में एक हैंडलर सदस्यता लेता है। इस घटना की सदस्यता लेने वाले ResolveEventHandler को मेरे कोड से अपस्ट्रीम जोड़ा गया था (मुझे पता है कि System.AppDomain के पास Private Method इवेंट की सदस्यता है) ... क्या इस घटना से सभी हैंडलर को निकालना संभव है, ताकि मैं अपना जोड़ सकूं अपने हैंडलर और सुनिश्चित करें कि यह केवल एक है?क्या एक वीबी.नेट इवेंट हैंडलर को निकालना संभव है जिसे आपकी कक्षा नहीं जोड़ा गया है?

अनिवार्य रूप से मैं यह करने के कोशिश कर रहा हूँ:

RemoveHandler AppDomain.CurrentDomain.AssemblyResolve, AddressOf ClassX.MethodX 

लेकिन मैं इस उदाहरण में नहीं पता है कि ClassX या MethodX हैं क्योंकि मुझे नहीं अभी तक इस घटना के लिए कोई हैंडलर को शामिल किया है, और इस हैंडलर अपस्ट्रीम कोड द्वारा जोड़ा गया था। मैं यदि कोई हैंडलर सदस्यता लिया है घटना की जांच करने के विधि यहाँ वर्णित उपयोग कर रहा हूँ: https://stackoverflow.com/a/2953318/734914

संपादित करें: मैं कौन सी विधि घटना की सदस्यता दी गई, तत्काल विंडो का उपयोग करते समय डिबगिंग यह पता लगाने में सक्षम था।

? DirectCast(gettype(System.AppDomain).GetField("AssemblyResolve", BindingFlags.Instance or BindingFlags.NonPublic).GetValue(AppDomain.CurrentDomain) , ResolveEventHandler) 
{System.ResolveEventHandler} 
    _methodBase: Nothing 
    _methodPtr: 157334028 
    _methodPtrAux: 1827519884 
    _target: {System.ResolveEventHandler} 
    **Method: {System.Reflection.Assembly ResolveAssembly**(System.Object, System.ResolveEventArgs)} 
    Target: Nothing 

अब मैं, इसे हटाने के लिए, इस तरह कोशिश कर रहा हूँ, क्योंकि यह एक सार्वजनिक विधि नहीं है:

RemoveHandler AppDomain.CurrentDomain.AssemblyResolve, AddressOf GetType(Reflection.Assembly).GetMethod("ResolveAssembly") 

लेकिन यह एक संकलक त्रुटि कह देता है: "AddressOf पैरामीटर के नाम होना चाहिए तरीका"। तो मुझे यकीन है कि मूल टिप्पणी से एक गैर सार्वजनिक विधि यहाँ

+0

नहीं, ऐसा करना संभव नहीं है। –

+0

क्या यह Winforms ऐप या क्लास lib है? – Plutonix

+0

मेरा कोड क्लास लाइब्रेरी में है जो WinForms एप्लिकेशन – plukich

उत्तर

1

निर्दिष्ट करने का तरीका नहीं कर रहा हूँ:

Here's प्रतिनिधियों की घटनाओं से आप प्रतिनिधि हस्ताक्षर करने के लिए .. बहुत आसान नहीं है हटाने के बारे में एक विषय, लेकिन अंत में पोस्टर ने

"ऐसा लगता है कि यह AppDomain.CurrentDomain.AssemblyResolve घटनाओं को हटाने का समर्थन नहीं करता है इसलिए मैंने जो कोड पोस्ट किया है वह काम नहीं करेगा।"

भी नेट शिकायत है कि घटना System.AppDomain.AssemblyResolve केवल += या -= के बाएं हाथ की ओर दिखाई दे सकता है (+=/-= ऑपरेटरों # सी AddHandler/RemoveHandler कर रहे हैं) .. तो यह की तरह एक 'नहीं' की तलाश में:/

इसके अतिरिक्त, आपके संपादन के बाद, कारण आप ऐसा नहीं कर सकते निम्नलिखित:

RemoveHandler AppDomain.CurrentDomain.AssemblyResolve, AddressOf GetType(Reflection.Assembly).GetMethod("ResolveAssembly") 

क्योंकि AddressOf कीवर्ड एक ऑपरेटर कीवर्ड, एक + याके समान है हैऑपरेटर होने के नाते, AddressOf दी गई प्रक्रिया पर चल रहा है और यह एक प्रक्रिया नाम होना चाहिए जो संकलन समय पर कटौती कर सकता है। और GetMethod फ़ंक्शन MethodInfo प्रकार देता है और ज्ञात फ़ंक्शन पता नहीं।

हालांकि सभी खो नहीं गए हैं!

AddHandler और RemoveHandler कार्यों वास्तव में एक Object और Delegate के लिए कॉल (जब इस्तेमाल किया AddressOf एक Delegate में संकलित किया जाता है) में पारित होने के लिए है, तो आप आप क्या चाहते करने के लिए AddressOf की जरूरत नहीं है, तो आप एक की जरूरत ।

ऐसा करने के लिए हम CreateDelegate तरीका है जिसके एक MethodInfo वस्तु ले करता है का उपयोग कर सकते हैं। ऐसा लगता है कि जब आप निजी तरीकों का उपयोग करने की कोशिश कर रहे हैं, तो आप Reflection.BindingFlags.Instance और Reflection.BindFlags.NonPublic की BindFlags का उल्लेख करना होगा (मैं and कहना लेकिन आप उन पर एक बिटवाइज़ Or करूँगा), उदाहरण के:

GetType(Reflection.Assembly).GetMethod("ResolveAssembly", Reflection.BindingFlags.Instance Or Reflection.BindingFlags.NonPublic) 

तो बुला इस पर CreateDelegate हमें निम्नलिखित कोड

[Delegate].CreateDelegate(GetType(Reflection.Assembly), GetType(Reflection.Assembly).GetMethod("ResolveAssembly", Reflection.BindingFlags.Instance Or Reflection.BindingFlags.NonPublic)) 

दे देंगे लेकिन वह नहीं बल्कि अत्यधिक शब्द है, तो यह टूट कर सकते हैं:

Dim type As Type = GetType(Reflection.Assembly) 
Dim mi As Reflection.MethodInfo = type.GetMethod("ResolveAssembly", (Reflection.BindingFlags.Instance Or Reflection.BindingFlags.NonPublic)) 

और अब हम बस निम्नलिखित के माध्यम से AppDomain.CurrentDomain.AssemblyResolve पर RemoveHandler कॉल कर सकते हैं:

RemoveHandler AppDomain.CurrentDomain.AssemblyResolve, [Delegate].CreateDelegate(type, mi) 

AppDomain.CurrentDomain.AssemblyResolve छोड़कर उम्मीद प्रतिनिधि/घटना हस्ताक्षर मिलान करने के लिए है, तो हम उचित प्रकार के लिए हमारी बनाई प्रतिनिधि कास्ट करने के लिए की जरूरत है:

RemoveHandler AppDomain.CurrentDomain.AssemblyResolve, CType([Delegate].CreateDelegate(type, mi), System.ResolveEventHandler) 

और अब आप ईवेंट हैंडलर से प्रतिबिंब के माध्यम से एक निजी विधि को हटा सकते हैं।

चेतावनी !! जबकि यह कोड संकलित और चलाएगा, मैं इसकी वैधता या सटीकता की कोई गारंटी नहीं देता क्योंकि आप फ्रेम और स्टैक पॉइंटर्स (अनिवार्य रूप से) के साथ मिल रहे हैं, और इसलिए रन हो सकता है और यह काम हो सकता है, यह भी स्पॉन बेबी बिल्ली के बच्चे .. तो बस सावधान रहें।

आशा है कि मदद कर सकते हैं!

+0

धन्यवाद txtechhelp :) – raed

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