C# AppDomain 无法加载 DLL
Posted
技术标签:
【中文标题】C# AppDomain 无法加载 DLL【英文标题】:C# AppDomain can't load DLL 【发布时间】:2016-07-21 13:52:27 【问题描述】:我正在尝试构建一个热插拔插件系统,用户可以在其中动态加载和卸载 dll。核心应用程序必须尽可能少地重新启动,因此我将尽可能多的功能转移到外部库。根据我的研究,我需要创建第二个 AppDomain 并将 DLL 加载到其中,然后将参数等传递给它以运行它。目前,我相信我的大部分程序都在工作,但是在从 CreateInstance 调用对象上的 AppDomain.Unwrap() 函数时遇到错误。错误如下:
System.InvalidCastException: Unable to cast transparent proxy to type 'Program1.Loader'.
这是加载代码:
try
unload(dom,out loader,true);
dom=null;
AppDomainSetup dms = new AppDomainSetup();
dms.ConfigurationFile=Environment.CurrentDirectory+Path.DirectorySeparatorChar+"Program1.exe.config";
dms.ApplicationBase=Environment.CurrentDirectory+Path.DirectorySeparatorChar+"Plugins";
Evidence ev = AppDomain.CurrentDomain.Evidence;
dom=AppDomain.CreateDomain("PluginManager",ev,dms);
AssemblyName an = AssemblyName.GetAssemblyName(Environment.CurrentDirectory+"\\Plugins\\PluginManager.dll");
ObjectHandle obj = dom.CreateInstance(an.FullName,"PluginManager.PluginManager");
loader = (Loader)obj.Unwrap();
loader.LoadAssembly(@"PluginManager.dll");
if(!suppressOutput)
Console.WriteLine("Reload successful.");
catch(Exception e)
unload(dom,out loader,true);
loader=null;
Console.WriteLine("PluginManager failed loading. Enter \"reload\" to try again.\n");
Console.Write(e+"\n\n");
这一行是引发错误的地方:
loader = (Loader)obj.Unwrap();
外部 DLL 中几乎没有代码,因为这是概念验证。如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace PluginManager
public class PluginManager:MarshalByRefObject
public void run(string comm)
Console.WriteLine(comm);
编辑:这是加载器类的代码。
class Loader:MarshalByRefObject
private Assembly _assembly;
public override object InitializeLifetimeService()
return null;
public void LoadAssembly(string path)
_assembly=Assembly.Load(AssemblyName.GetAssemblyName(path));
public object ExecuteStaticMethod(string typeName,string methodName,params object[] parameters)
Type type = _assembly.GetType(typeName);
MethodInfo method = type.GetMethod(methodName,BindingFlags.Static|BindingFlags.Public);
return method.Invoke(null,parameters);
【问题讨论】:
【参考方案1】:您似乎正试图在AppDomain
中创建PluginManager
类型的对象,然后将其代理转换为Loader
类型(您的代码示例中缺少该类型)。
问题出在以下几行:
ObjectHandle obj = dom.CreateInstance(an.FullName,"PluginManager.PluginManager");
loader = (Loader)obj.Unwrap();
如果您创建 Loader
的实例而不是 PluginManager
- 或 - 强制转换为 PluginManager
而不是 Loader
,它将起作用。我的猜测是前者:
ObjectHandle obj = dom.CreateInstance(an.FullName,"LoaderNamespace.Loader");
(将LoaderNamespace
替换为真实的。)
【讨论】:
我已更新代码以包含加载程序演员表。你能用一些代码解释你的答案吗?我不确定你想让我做什么。 感谢编辑!但是Loader在主程序中。 CreateInstance 在尝试从 dll 加载时不会失败吗? 但是你不尝试加载Loader,你尝试加载PluginManager。那就是问题所在。这就是您传递给 AppDomain.CreateInstance 的内容。 是的,但 PluginManager 是我需要从 dll 加载的类。加载器在主程序中。如果我执行您建议的交换,我会收到预期的错误,指出该 DLL 中不存在类加载器。以上是关于C# AppDomain 无法加载 DLL的主要内容,如果未能解决你的问题,请参考以下文章
C# 在 appdomain 调用方法中加载 dll,而不会再次加载 dll
将 DLL 加载到具有已知唯一公共接口的单独 AppDomain 中