[英]C# Late Binding Unloading Dll in Runtime
我想加载.dll
在运行时到我自己的C#程序作为一个插件。如果有现有的插件DLL(InvokeHelper.dll)新的更新卸载和下载更新的.dll
(InvokeHelper.dll),并将其装入程序而不终止进程。(我的申请)。 我阅读了这些文章来完成这些任务( MSDN, Article2 )但是这段代码仍然不能用于动态卸载.dll
。
当我通过进程资源管理器查看附加的 dll 时,附加的 dll 没有卸载。它存在于进程资源管理器dll 列表中。我想如果 dll 卸载成功,我想手动重命名旧的 dll 并替换新的。
InvokeHelper.dll来源:
using System;
namespace InvokeHelper
{
public class LateBindingInvokeHelper
{
public void PrintHello()
{
using (System.IO.StreamWriter w = new System.IO.StreamWriter(@"Invoker.txt", true))
{
w.WriteLine(DateTime.Now.ToString());
w.Flush();
}
}
}
}
加载DLL函数:
private AppDomain domain = null;
private void LoadDll()
{
AppDomainSetup domInfo = new AppDomainSetup();
domInfo.ApplicationBase = System.Environment.CurrentDirectory;
Evidence adevidence = AppDomain.CurrentDomain.Evidence;
domInfo.DisallowBindingRedirects = false;
domInfo.DisallowCodeDownload = true;
domain = AppDomain.CreateDomain("MyDomain", adevidence , domInfo);
Type type = typeof(Proxy);
var value = (Proxy)domain.CreateInstanceAndUnwrap(
type.Assembly.FullName,
type.FullName);
var assembly = value.GetAssembly(@"C:\dev\ExBinder\ExBinder\bin\Debug\InvokeHelper.dll");
Type[] mytypes = assembly.GetTypes();
BindingFlags flags = (BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance);
foreach (Type t in mytypes)
{
MethodInfo[] mi = t.GetMethods(flags); // you can change this flag , commented some flags :) view only plublic or bla bla
Object obj = Activator.CreateInstance(t);
foreach (MethodInfo m in mi)
{
if (m.Name.Equals("PrintHello")) m.Invoke(obj, null); //my func name :) you can set this via config :D
}
}
}
private void button2_Click(object sender, EventArgs e)
{
LoadDll();
AppDomain.Unload(domain);
}
代理类
public class Proxy : MarshalByRefObject
{
public Assembly GetAssembly(string assemblyPath)
{
try
{
return Assembly.LoadFile(assemblyPath);
}
catch (Exception)
{
return null;
}
}
}
问题是您正在单独的 AppDomain 中加载程序集并通过代理返回该Assembly
集,因此在您的默认 AppDomain 中也加载了相同的程序集。 我已将您的调用逻辑移到代理类中并且它起作用了。
public class Proxy : MarshalByRefObject
{
public void Run()
{
var assembly = AppDomain.CurrentDomain.Load(File.ReadAllBytes(@"C:\Users\Mkrtich_Mazmanyan\Downloads\ExBinder\Exbinder\bin\Debug\InvokeHelper.dll"));
Type[] mytypes = assembly.GetTypes();
BindingFlags flags = (BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance);
foreach (Type t in mytypes)
{
MethodInfo[] mi = t.GetMethods(flags); // you can change this flag , commented some flags :) view only plublic or bla bla elshan
Object obj = Activator.CreateInstance(t);
foreach (MethodInfo m in mi)
{
if (m.Name.Equals("PrintHello")) m.Invoke(obj, null); //my func name :) you can set this via config :D
}
}
}
}
调用部分将是:
value.Run();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.