2008-10-22 10 views
36

मैं अपने क्लाइंट के सिस्टम के भीतर वातावरण और क्षेत्रों में तैनात .NET अनुप्रयोगों के बारे में जानकारी रिपोर्ट करने के लिए एक उपकरण लिख रहा हूं।प्रतिबिंब संचालन के लिए .NET असेंबली कैसे लोड करें और बाद में इसे अनलोड करें?

मैं इन असेंबली में असेंबली विशेषताओं के मानों को पढ़ना चाहता हूं।

यह Assembly.ReflectionOnlyLoad का उपयोग करके हासिल किया जा सकता है, हालांकि यह दृष्टिकोण असेंबली को भी लोड करता है। यहां मुद्दा यह है कि मैं दो असेंबली लोड नहीं कर सकता जिनके पास अलग-अलग पथों से समान नाम है, इसलिए स्वाभाविक रूप से मैं अलग-अलग प्रणालियों में तैनात उसी एप्लिकेशन की तुलना नहीं कर सकता।

इस बिंदु पर मुझे लगता है कि समाधान अस्थायी AppDomain एस का उपयोग कर शामिल होगा।

कोई व्यक्ति किसी अन्य AppDomain में किसी असेंबली को लोड करने का विवरण दे सकता है, इसके गुणों को पढ़ सकता है और फिर AppDomain को अनलोड कर सकता है?

इसे फ़ाइल सिस्टम के साथ-साथ यूआरएल पते पर असेंबली के लिए काम करने की जरूरत है।

उत्तर

47
MSDN documentation of System.Reflection.Assembly.ReflectionOnlyLoad (String) से

:

प्रतिबिंब-केवल संदर्भ कोई अन्य संदर्भों से अलग है। असेंबली जो संदर्भ में लोड की गई हैं, केवल द्वारा एप्लिकेशन डोमेन को अनलोड करने के द्वारा अनलोड किया जा सकता है।

तो, मुझे डर है कि असेंबली को उतारने का एकमात्र तरीका एप्लिकेशन डोमेन को उतारना है। इसे में एक नया AppDomain और लोड विधानसभाओं बनाने के लिए:

public void TempLoadAssembly() 
{ 
    AppDomain tempDomain = AppDomain.CreateDomain("TemporaryAppDomain"); 
    tempDomain.DoCallBack(LoaderCallback); 
    AppDomain.Unload(tempDomain); 
} 

private void LoaderCallback() 
{ 
    Assembly.ReflectionOnlyLoad("YourAssembly"); 
    // Do your stuff here 
} 
+0

धन्यवाद, यह एक उपयोगी पैटर्न की तरह लग रहा है। –

+1

असेंबली नहीं है। रिफॉर्मेशनऑनलीलोड (...) अभी भी मौजूदा डोमेन में असेंबली लोड करता है, न कि अस्थायी ऐपडोमेन में? – Anzurio

+3

एजेड: नहीं। AppDomain.DoCallback "निर्दिष्ट प्रतिनिधि द्वारा पहचाने गए किसी अन्य एप्लिकेशन डोमेन में कोड xecutes" (एमएसडीएन)। असेंबली के दस्तावेज।प्रतिबिंबऑनलीलोड स्पष्ट रूप से बताता है कि "असेंबली कॉलर के एप्लिकेशन डोमेन के प्रतिबिंब-केवल संदर्भ में लोड की जाती है" (फिर से, एमएसडीएन)। इसका मतलब है कि असेंबली वास्तव में अस्थायी ऐप डोमेन में लोड की जाती है। –

4

आप Unmanaged Metadata API उपयोग करने के लिए है, जो COM है और आसानी से आवरण के कुछ प्रकार के साथ नेट आवेदन से इस्तेमाल किया जा सकता कोशिश कर सकते हैं।

+0

हाय इलिया। इस लिंक के लिए धन्यवाद। मैं जल्द ही इस काम की समीक्षा करूँगा और निश्चित रूप से इस एपीआई को आजमाउंगा। मुझे आशा है कि यह वास्तव में असेंबली लोड करने से ज्यादा कुशल है। –

3

आपको एप्लिकेशन डोमेन का उपयोग करना होगा, असेंबली को उतारने का कोई और तरीका नहीं है। मूल रूप से आप इस तरह कोड का उपयोग करने के लिए है:

 

AppDomain tempDomain = AppDomain.CreateDomain("Temp Domain"); 
tempDomain.Load(assembly); 
AppDomain.Unload(tempDomain); 

9

जबकि विधानसभाओं उतारने, अगर आप सिर्फ एक फ़ाइल आप System.Diagnostics.FileVersionInfo उपयोग कर सकते हैं की संस्करण संख्या प्राप्त करने के लिए कोशिश कर रहे हैं के बारे में वास्तव में नहीं।

public string Comments { get; } 
public string CompanyName { get; } 
public int FileBuildPart { get; } 
public string FileDescription { get; } 
public int FileMajorPart { get; } 
public int FileMinorPart { get; } 
public string FileName { get; } 
public int FilePrivatePart { get; } 
public string FileVersion { get; } 
public string InternalName { get; } 
public bool IsDebug { get; } 
public bool IsPatched { get; } 
public bool IsPreRelease { get; } 
public bool IsPrivateBuild { get; } 
public bool IsSpecialBuild { get; } 
public string Language { get; } 
public string LegalCopyright { get; } 
public string LegalTrademarks { get; } 
public string OriginalFilename { get; } 
public string PrivateBuild { get; } 
public int ProductBuildPart { get; } 
public int ProductMajorPart { get; } 
public int ProductMinorPart { get; } 
public string ProductName { get; } 
public int ProductPrivatePart { get; } 
public string ProductVersion { get; } 
public string SpecialBuild { get; } 
1

आप नए AppDomain में एक उदाहरण बना सकते हैं और कि उदाहरण में अपने कोड निष्पादित कर सकते हैं:

var info = FileVersionInfo.GetVersionInfo(path); 

FileVersionInfo निम्नलिखित गुण है।

var settings = new AppDomainSetup 
{ 
    ApplicationBase = AppDomain.CurrentDomain.BaseDirectory, 
}; 
var childDomain = AppDomain.CreateDomain(Guid.NewGuid().ToString(), null, settings); 

var handle = Activator.CreateInstance(childDomain, 
      typeof(ReferenceLoader).Assembly.FullName, 
      typeof(ReferenceLoader).FullName, 
      false, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, null, CultureInfo.CurrentCulture, new object[0]); 


var loader = (ReferenceLoader)handle.Unwrap(); 

//This operation is executed in the new AppDomain 
var paths = loader.LoadReferences(assemblyPath); 


AppDomain.Unload(childDomain); 

यहाँ ReferenceLoader

public class ReferenceLoader : MarshalByRefObject 
{ 
    public string[] LoadReferences(string assemblyPath) 
    { 
     var assembly = Assembly.ReflectionOnlyLoadFrom(assemblyPath); 
     var paths = assembly.GetReferencedAssemblies().Select(x => x.FullName).ToArray(); 
     return paths; 
    } 
} 
+0

बिल्कुल सही - LINQPad में चलाने के लिए एक मामूली परिवर्तन करने के लिए इस प्रकार था: 'var सेटिंग्स = नए AppDomainSetup { \t \t ApplicationBase = Path.GetDirectoryName (this.GetType() Assembly.Location।) \t};' –

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