2009-02-02 25 views
32

क्या असेंबली लोड होने पर कुछ कोड चलाने के लिए कुछ कोड चलाने के लिए संभव है, लोडिंग कोड में कुछ भी विशिष्ट किए बिना? जो मैं खोज रहा हूं वह एक प्रकार के स्थिर कन्स्ट्रक्टर की तरह है।नेट: असेंबली लोड होने पर कोड चलाना

उदाहरण के लिए:

विधानसभा एक विधानसभा बी के बारे में पता नहीं है, लेकिन के बारे में ए विधानसभा एक बी के बारे में कुछ बातें जानना चाहते हैं कि बी भरी हुई है की जरूरत बी को पता है। विधानसभा बी क्रम (संदर्भित, या स्पष्ट) द्वारा लोड किया जाता है, मैं कोड (स्थिर विधि या विशेषता) का एक टुकड़ा विधानसभा ए में एक विधि

इस समस्या के मूल कारण अज्ञात है कहता है कि निष्पादित करने के लिए चाहते हैं टाइप ए का सामना करना पड़ता है जब ए में एक प्रकार का क्रमबद्ध होता है जिसमें बी से प्रकार होते हैं जो संकलन समय पर ज्ञात नहीं होते हैं क्योंकि इंटरफेस का उपयोग किया जाता है।

उत्तर

37

CLR module initializers का समर्थन करता है के बारे में पता करने के लिए बिना विधानसभा बी लोड होगा कि कर सकते हैं। उन्हें उपयोग करने के लिए आपको C++/CLI कोड या ilasm.exe हैक करना होगा।

+9

कोई हैक साथ https://github.com/Fody/ModuleInit –

+2

@RichardCollette यह अभी भी हैक कर रही है जरूरत है, लेकिन Fody सिर्फ निर्माण प्रक्रिया में हैक स्वचालित है यह करने के लिए आसान बनाने के लिए। –

6

(संपादित करें - सी # करने के लिए लागू होता है, एक सी ++ दृष्टिकोण के लिए, this answer देखें)

मूल रूप से, कोई: आप नहीं कर सकते। यह एक बड़ी हमले की सतह होगी, और इसकी अनुमति नहीं है। आप कुछ बी प्रकारों पर स्थिर कॉटर रखना चाहते हैं जो सुनिश्चित करते हैं कि इनिट कोड निष्पादित किया गया है, लेकिन यह इसके बारे में है ...

+5

क्यों यह एक हमले सतह है? –

+1

ऐसा लगता है कि यह वहाँ में कोड को छिपाने के लिए काफी आसान है कि कोई कोड जानबूझकर का आह्वान होगा - मुश्किल से नज़र, आदि अकेले चलो सवाल जिनमें से धागा इसे चलाने चाहिए ... शायद मैं इसे ठीक से vocalize नहीं कर सकते हैं, लेकिन यह मुझे मूर्खतापूर्ण लगता है। लेकिन यह मूक है क्योंकि आप इसे वैसे भी नहीं कर सकते हैं ;- –

+0

क्या आपको पता है कि इस पर कोई जानकारी है (मॉड्यूल प्रारंभकर्ता लोड पर नहीं चलते हैं, बल्कि स्थिर रचनाकारों से पहले), इसलिए यह दिलचस्प है अगर कोड कर सकता है लोड के दौरान चलाओ। http://stackoverflow.com/questions/24718917/can-a-call-to-assembly-loadbyte-raise-the-appdomain-assemblyresolve-event/24719526 - अगर आप इस बहुत करीब सवाल भी जवाब कर सकते हैं आप की जाँच करने के हैं? noredirect = 1 # comment38423553_24719526 –

3

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

+0

मैं इस विधि का उपयोग करके असेंबली बी को कैसे पहचान और लोड कर सकता हूं? –

+0

यदि आप का उपयोग करके क्रमबद्ध करते हैं, तो बाइनरीफॉर्मेटर कहें, आपके सीरियलाइज़ेशन ग्राफ़ में किसी भी प्रकार को आईएसरियलज़ेबल लागू करने के लिए उनके रचनाकारों को deserialize के दौरान बुलाया जाएगा, जिसमें आप जो भी कोड चाहते हैं उसे कॉल कर सकते हैं। के रूप में, जब आप को क्रमानुसार, इंटरफ़ेस ... –

+0

के लिए क्रमबद्धता प्रश्नों ... यह फर्क नहीं पड़ता अगर एक ही एक अंतरफलक द्वारा बी के प्रकार को संदर्भित करता है, वे ठीक तरह से क्रमानुसार होगा। –

5

आप नेट में स्थिर रचनाकारों का उपयोग कर सकते हैं, लेकिन दुर्भाग्य से वे जो भी आप चाहते हैं वह नहीं करते हैं। स्टेटिक कन्स्ट्रक्टर केवल एक प्रकार का उपयोग करने से पहले ही निष्पादित होते हैं। विवरण के लिए http://msdn.microsoft.com/en-us/library/k9x6w0hc(VS.80).aspx देखें।

आपको अपने ऐपडोमेन के असेंबली लोड ईवेंट की सदस्यता लेने से कुछ लाभ मिल सकता है। http://msdn.microsoft.com/en-us/library/system.appdomain.assemblyload.aspx देखें।

अपने ईवेंट हैंडलर में आप नई लोडेड असेंबली पर प्रतिबिंबित कर सकते हैं, और इसे जो भी कोड पसंद करते हैं उसे निष्पादित करने के लिए प्राप्त कर सकते हैं।

+0

Unfortuantly के बाद से केवल 30 अजीब विधानसभाओं में से एक यह पंजीकरण किया की जरूरत है, AssemblyLoad overkill से अधिक एक सा हो सकता है। –

0

मिश्रित असेंबली का उपयोग करके आप असेंबली लोड पर चलाने के लिए DllMain प्राप्त कर सकते हैं।

3

वहाँ 3 विकल्प एक .NET विधानसभा प्रारंभ करने में कर रहे हैं: अपने विधानसभा में

  1. आप एक स्थिर समारोह Init() या मुख्य (लिखना) प्रारंभ करने के लिए और सी # कोड से प्रतिबिंब द्वारा इस फ़ंक्शन को कॉल करें कि इस असेंबली को लोड करता है।
  2. एक प्रबंधित सी ++ असेंबली लिखें जहां आपने अपना कोड DllMain() में रखा है। सावधान रहें क्योंकि आपका कोड लोडर लॉक में निष्पादित किया जाएगा जहां कई चीजें वर्जित हैं (जैसे अन्य डीएलएल लोड करना ...)। लेकिन आप एक नया धागा शुरू कर सकते हैं जो किसी भी प्रारंभिक सामग्री को करता है। (के बारे में LoaderLock: https://msdn.microsoft.com/en-us/library/ms173266.aspx) (के बारे में DllMain: C# to C++/CLI to C DLL System.IO.FileNotFoundException)
  3. आप एक शुद्ध सी # विधानसभा संकलन और एक मॉड्यूल प्रारंभकर्ता कोड जोड़ने के लिए संकलित DLL संशोधित की तरह यहां विस्तार से बताया: http://einaregilsson.com/module-initializers-in-csharp/ इस विधि का नुकसान यह है कि जब विधानसभा प्रक्रिया में लोड हो जाती है तो प्रारंभिक कार्य तुरंत तत्काल नहीं कहा जाता है। लेकिन असेंबली में किसी और चीज से पहले इसे पहले कहा जाता है।
+0

1) तर्कसंगत रूप से _ "लोडिंग कोड में विशिष्ट कुछ भी किए बिना _ को संतुष्ट नहीं करता है?" _ – MickyD

+0

लोडिंग कोड को संशोधित करने का एकमात्र तरीका विकल्प 2 है।) – Elmue

+0

हाँ, मुझे आपका विकल्प 2 पसंद है – MickyD

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