如何从程序集中加载及卸载插件
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何从程序集中加载及卸载插件相关的知识,希望对你有一定的参考价值。
安装打开360安全卫士—软件管家—卸载里找到要卸载的软件然后点卸载就OK了。 参考技术A 控制面板里Internet属性 程序选项卡中的管理加载项。通过反射从加载的程序集中返回 Types[] 时的 FileNotFound
【中文标题】通过反射从加载的程序集中返回 Types[] 时的 FileNotFound【英文标题】:FileNotFound when return Types[] from loaded assembly via reflection 【发布时间】:2015-06-30 18:14:36 【问题描述】:我正在尝试加载插件程序集(放置在
D:\xyz\addin.dll
当我的应用程序在
D:\MyApp\MyApp.exe
这样插件文件不应该被锁定,以便在应用程序运行时可以再次复制它的新版本。 为此,我创建了新的应用程序域并加载了包含 AssembltLoader 类的通用 dll,然后调用 AssemblyLoader 加载插件并获取其中可用的所有类型。 Addin dll 的依赖项已经放在同一个文件夹中。 现在从插件 dll 获取类型工作正常,但是当我
返回程序集.GetTypes();
发生了一件非常奇怪的事情。它执行该行但在该函数退出时抛出异常“d:\xyz\addin.dll”FileNotFound
public class ObjectLoader : IDisposable
public Type[] GetAllTypesFromAssembly(string filePath)
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
setup.ShadowCopyFiles = "true";
Evidence adevidence = AppDomain.CurrentDomain.Evidence;
AssemblyLoader asemblyLoader = null;
AppDomain appDomain = AppDomain.CreateDomain(filePath, adevidence, setup);
appDomain.AssemblyResolve += new ResolveEventHandler(MyResolveEventHandler);
domains.Add(filePath, appDomain);
object[] parms = filePath ;
BindingFlags bindings = BindingFlags.CreateInstance | BindingFlags.Instance | BindingFlags.Public;
try
asemblyLoader = (AssemblyLoader)appDomain.CreateInstanceFromAndUnwrap(
setup.ApplicationBase +
"Common.dll", "Common.AssemblyLoader",
true, bindings, null, parms, null, null, null
);
catch (Exception ex)
throw ex; // new AssemblyLoadFailureException();
object types = null;
if (asemblyLoader != null)
// On following line i am facing the error which occur on following line but when GetAllTypes exits.
types = asemblyLoader.GetAllTypes();
return (Type[])types;
internal class AssemblyLoader : MarshalByRefObject, IDisposable
private Assembly assembly = null;
public object GetAllTypes()
BindingFlags flags = BindingFlags.CreateInstance | BindingFlags.Instance | BindingFlags.Public;
object types = null;
if (assembly != null)
try
// following line works fine and loads a type (it contains one class)
types = assembly.GetTypes();
catch (Exception)
types = new ObjectLoadFailureException();
else
types = new AssemblyNotLoadedException();
return types;
这里是异常详情:
System.IO.FileNotFoundException was unhandled
HResult=-2147024894
Message=Could not load file or assembly 'AddIn, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
Source=mscorlib
FileName=AddIn, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
FusionLog==== Pre-bind state information ===
LOG: DisplayName = AddIn, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
(Fully-specified)
LOG: Appbase = file:///D:/MyApp/
LOG: Initial PrivatePath = NULL
Calling assembly : (Unknown).
如果我在 D:\xyz\ 和 D:\MyApp\ 中都复制了我的 addin.dll,则没有错误。我不能在运行时环境中这样做。
【问题讨论】:
我添加了解决依赖问题的 AssemblyResolve 事件处理程序,但它会锁定文件,因为这些文件也在当前 AppDomain 中加载 【参考方案1】:您正在将 Type
对象编组到主 AppDomain。
这会导致 CLR 加载包含该 AppDomain 中的类型的程序集,从而导致此错误。
您可能根本不应该使用 AppDomain。
【讨论】:
太好了,没有 AppDomains 怎么办。请提供任何提示。 @Adeem:直接在程序集上调用GetTypes()
。以上是关于如何从程序集中加载及卸载插件的主要内容,如果未能解决你的问题,请参考以下文章
通过反射从加载的程序集中返回 Types[] 时的 FileNotFound