2013-06-20 35 views
6

Làm cách nào để tạo một miền ứng dụng, thêm các assembly vào nó, sau đó hủy miền ứng dụng đó? Đây là những gì tôi đã cố gắng:Tạo AppDomain tùy chỉnh và thêm các assembly vào nó

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!    
    } 

Tôi cũng đã cố gắng:

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

làm thế nào tôi có thể thêm một hội đồng để appdomain. Khi tôi làm điều đó tôi có thể tìm ra phương pháp thông qua phản ánh thực hiện nó và sau đó phá hủy các appdomain

Trường hợp ngoại lệ mà tôi nhận được là:

Không thể tải tập tin hoặc lắp ráp 'ConsoleApplication1, Version = 1.0.0.0, Văn hóa = trung lập, PublicKeyToken = null 'hoặc một trong các phụ thuộc của nó. Hệ thống không thể tìm thấy tệp được chỉ định.

+2

Nó là dễ dàng để tải lắp ráp để tên miền riêng của bạn - vì vậy thay vì cố gắng đẩy lắp ráp vào miền khác xem xét việc chạy một số mã trong miền khác để tải bất kỳ lắp ráp nào bạn muốn (đừng quên rằng bạn có thể cần phải tải trước phụ thuộc hoặc thiết lập đường dẫn tìm kiếm lắp ráp chính xác). –

+0

"Hoặc một trong những phụ thuộc của nó" là vấn đề thông thường. Sử dụng Fuslogvw.exe nếu bạn không có ý tưởng đó có thể là gì. Và sử dụng AppDomainSetup để thiết lập đường dẫn riêng đúng. –

Trả lời

11

Hai điểm nhanh:

  1. AppDomain.Load tải một lắp ráp trong AppDomain hiện tại và không phải trên myDomain (lạ, tôi biết).
  2. AppDomain.Load tải một hội đồng trong ngữ cảnh Load, trong đó giải quyết các hội đồng từ cơ sở ứng dụng-dir, đường dẫn-bin riêng và GAC. Có lẽ, lắp ráp bạn cố tải không nằm ở bất kỳ vị trí nào trong số này giải thích thông báo ngoại lệ.

Để biết thêm thông tin, hãy xem answer này.

Một cách để tải các hội đồng vào một AppDomain là bằng cách tạo bộ nạp có nguồn gốc từ MarshalByRef. Bạn cần một cái gì đó như thế này để tránh rò rỉ các loại (và hội đồng) để AppDomain chính của bạn. Dưới đây là một đơn giản:

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)); 
    } 
} 

Và sử dụng nó như thế:

//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

Xin chào, tôi chỉ cố gắng sử dụng đề xuất của bạn để tải trước một số assembly .net để tìm hiểu xem chúng có chứa một lớp thực hiện giao diện nhất định hay không. Nhưng ngược lại để tải lắp ráp vào miền hiện tại, hoạt động tốt, tôi không thể tải chúng vào myDomain AppDomain mới được tạo của tôi. –

Các vấn đề liên quan