簡體   English   中英

將DLL加載到單獨的AppDomain中

[英]Loading DLL into separate AppDomain

我正在寫一個插件架構。 我的插件dll位於運行插件管理器的子目錄中。 我將插件加載到單獨的AppDomain中,如下所示:

string subDir;//initialized to the path of the module's directory.
AppDomainSetup setup = new AppDomainSetup();
setup.PrivateBinPath = subDir;
setup.ApplicationBase = subDir;

AppDomain newDomain= AppDomain.CreateDomain(subDir, null, setup);

byte[] file = File.ReadAllBytes(dllPath);//dll path is a dll inside subDir
newDomain.Load(file);

然而。 newDomain.Load返回當前域嘗試加載的程序集。 因為插件dll位於子目錄中,所以當前域不能也不應看到這些dll,並且當前域會引發FileLoadException“ ex = {”無法加載文件或程序集...或其依賴項之一。“

問題是,我們可以將程序集加載到單獨的AppDomain中,而無需返回已加載的程序集嗎?

我知道我可以在當前域中為AssemblyResolve事件添加一個處理程序,並返回一個null,但是我不希望這樣做。

提前致謝。

您還可以使用DoCallBack-這是我在SO上閱讀了很多有關內容后整理的內容。 這將創建一個appdomain,檢查程序集是否具有相同的簽名公鑰,加載程序集,執行靜態方法,卸載appdomain,然后刪除dll。

static void Main(string[] args)
    {
        string unknownAppPath = @"path-to-your-dll";

        Console.WriteLine("Testing");
        try
        {
            AppDomainSetup setup = new AppDomainSetup();
            setup.AppDomainInitializer = new AppDomainInitializer(TestAppDomain);
            setup.AppDomainInitializerArguments = new string[] { unknownAppPath };
            AppDomain testDomain = AppDomain.CreateDomain("test", AppDomain.CurrentDomain.Evidence, setup);
            AppDomain.Unload(testDomain);
            File.Delete(unknownAppPath);
        }
        catch (Exception x)
        {
            Console.WriteLine(x.Message);
        }
        Console.ReadKey(); 
    }

    public static void TestAppDomain(string[] args)
    {
        string unknownAppPath = args[0];
        AppDomain.CurrentDomain.DoCallBack(delegate()
        {
            //check that the new assembly is signed with the same public key
            Assembly unknownAsm = AppDomain.CurrentDomain.Load(AssemblyName.GetAssemblyName(unknownAppPath));
            //get the new assembly public key
            byte[] unknownKeyBytes = unknownAsm.GetName().GetPublicKey();
            string unknownKeyStr = BitConverter.ToString(unknownKeyBytes);
            //get the current public key
            Assembly asm = Assembly.GetExecutingAssembly();
            AssemblyName aname = asm.GetName();
            byte[] pubKey = aname.GetPublicKey();
            string hexKeyStr = BitConverter.ToString(pubKey);
            if (hexKeyStr == unknownKeyStr)
            {
                //keys match so execute a method
                Type classType = unknownAsm.GetType("namespace.classname");
                classType.InvokeMember("method-you-want-to-invoke", BindingFlags.InvokeMethod, null, null, null);
            }
        });
    }

如以下鏈接中所指出:

在不同的AppDomain中加載/卸載程序集

在新的AppDomain中加載程序集而不在父AppDomain中加載它

似乎在另一個AppDomain對象上調用Load()方法也會導致該程序集也加載到當前AppDomain中。

解決方案是改用AppDomain類的CreateInstanceFromAndUnwrap()方法。 您傳遞了程序集的路徑和要轉換為的類型。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM