2013-06-20 29 views
6

मैं एपडोमेन कैसे बना सकता हूं, इसमें असेंबली जोड़ सकता हूं, फिर उस ऐप डोमेन को नष्ट कर सकता हूं? यह मैं क्या करने की कोशिश की है:कस्टम ऐपडोमेन बनाएं और इसमें असेंबली जोड़ें

static void Main(string[] args) 
    {   
     string pathToExe = @"A:\Users\Tono\Desktop\ConsoleApplication1.exe"; 

     AppDomain myDomain = AppDomain.CreateDomain("MyDomain"); 

     Assembly a = Assembly.Load(System.IO.File.ReadAllBytes(pathToExe)); 

     myDomain.Load(a.FullName); // Crashes here!    
    } 

मैं भी कोशिश की है:

myDomain.Load(File.ReadAllBytes(pathToExe)); 

कैसे मैं appdomain के लिए एक सभा जोड़ सकते हैं। एक बार मुझे लगता है कि मैं पा सकते हैं कर निष्पादित प्रतिबिंब के माध्यम से विधि और फिर appdomain नष्ट

अपवाद है कि मैं मिलता है:

फ़ाइल या विधानसभा 'ConsoleApplication1 लोड नहीं कर सका, संस्करण = 1.0.0.0, संस्कृति = तटस्थ, PublicKeyToken = शून्य 'या इसकी निर्भरताओं में से एक। सिस्टम निर्दिष्ट फ़ाइल नहीं ढूंढ सकता है।

+2

यह स्वयं के डोमेन से विधानसभा लोड करने के लिए आसान है - तो बजाय अन्य डोमेन में विधानसभा पुश करने के लिए कुछ कोड चलाने पर विचार की कोशिश कर रहा जो भी असेंबली आप चाहते हैं उसे लोड करने के लिए अन्य डोमेन (यह न भूलें कि आपको प्री-लोड निर्भरताओं या सेटअप असेंबली खोज पथ को सही ढंग से सेट करने की आवश्यकता हो सकती है)। –

+0

"या इसकी निर्भरताओं में से एक" सामान्य समस्या है। अगर आपको पता नहीं है कि यह क्या हो सकता है तो Fuslogvw.exe का उपयोग करें। और सही निजी पथ सेट करने के लिए AppDomainSetup का उपयोग करें। –

उत्तर

11

दो त्वरित अंक:

  1. AppDomain.Load भार वर्तमान AppDomain में एक विधानसभा और पर myDomain नहीं (अजीब, मुझे पता है)।
  2. AppDomain.LoadLoad संदर्भ में एक असेंबली लोड करता है, जो ऐप्स बेस-डीआईआर, निजी-बिन-पथ और जीएसी से असेंबली को हल करता है। सबसे अधिक संभावना है कि आप जिस असेंबली को लोड करने का प्रयास करते हैं वह इन स्थानों में से किसी एक में स्थित नहीं है जो अपवाद संदेश बताती है।

अधिक जानकारी के लिए इस answer पर एक नज़र डालें।

ऐपडोमेन में असेंबली लोड करने का एक तरीका मार्शलबीरफ-व्युत्पन्न लोडर बनाकर है। आपको अपने मुख्य ऐपडोमेन में लीकिंग प्रकार (और असेंबली) से बचने के लिए इस तरह की कुछ चाहिए। यहाँ एक सरल एक है:

public class SimpleAssemblyLoader : MarshalByRefObject 
{ 
    public void Load(string path) 
    { 
     ValidatePath(path); 

     Assembly.Load(path); 
    } 

    public void LoadFrom(string path) 
    { 
     ValidatePath(path); 

     Assembly.LoadFrom(path); 
    } 

    private void ValidatePath(string path) 
    { 
     if (path == null) throw new ArgumentNullException("path"); 
     if (!System.IO.File.Exists(path)) 
      throw new ArgumentException(String.Format("path \"{0}\" does not exist", path)); 
    } 
} 

और उस तरह उपयोग:

//Create the loader (a proxy). 
var assemblyLoader = (SimpleAssemblyLoader)myDomain.CreateInstanceAndUnwrap(typeof(SimpleAssemblyLoader).Assembly.FullName, typeof(SimpleAssemblyLoader).FullName); 
//Load an assembly in the LoadFrom context. Note that the Load context will 
//not work unless you correctly set the AppDomain base-dir and private-bin-paths. 
assemblyLoader.LoadFrom(pathToExe); 

//Do whatever you want to do. 

//Finally unload the AppDomain. 
AppDomain.Unload(myDomain); 
+0

हैलो, मैंने अभी कुछ सुझावों का उपयोग करने की कोशिश की है कि कुछ .NET असेंबली प्रीलोड करें ताकि यह पता लगाया जा सके कि उनमें एक निश्चित इंटरफ़ेस क्लास कार्यान्वयन है या नहीं। लेकिन वर्तमान डोमेन में असेंबली को लोड करने के विपरीत, जो ठीक काम करता है, मैं उन्हें अपने नए बनाए गए AppDomain myDomain में लोड नहीं कर सकता। –

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