[英]Loading/Unloading assembly in different AppDomain
我需要在運行時加載的程序集中執行一個方法。 現在我想在方法調用后卸載那些已加載的程序集。 我知道我需要一個新的AppDomain,所以我可以卸載庫。 但在這里,出現了問題。
要加載的程序集是我的插件框架中的插件。 他們根本沒有切入點。 我所知道的是它們包含一些實現給定接口的類型。 舊的非AppDomain代碼看起來像這樣(稍微縮短):
try
{
string path = Path.GetFullPath("C:\library.dll");
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
Assembly asm = Assembly.LoadFrom(path);
Type[] types = asm.GetExportedTypes();
foreach (Type t in types)
{
if ((t.GetInterface("IStarter") != null) && !t.IsAbstract)
{
object tempObj = Activator.CreateInstance(t);
MethodInfo info = t.GetMethod("GetParameters");
if (info != null)
{
return info.Invoke(tempObj, null) as string;
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(String.Format("Damn '{0}'.", ex.Message), "Exception", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
if (args.Name.StartsWith("MyProject.View,"))
{
string path = Path.GetFullPath("C:\view.dll"));
return Assembly.LoadFrom(path);
}
return null;
}
現在我希望它們加載到自己的AppDomain中:
try
{
string path = Path.GetFullPath("C:\library.dll");
AppDomain domain = AppDomain.CreateDomain("TempDomain");
domain.AssemblyResolve += CurrentDomain_AssemblyResolve; // 1. Exception here!!
domain.ExecuteAssembly(path); // 2. Exception here!!
domain.CreateInstanceFrom(...); // 3. I have NO clue, how the type is named.
domain.Load(...); // 4. I have NO clue, how the assembly is named.
domain.DoCallBack(...); // 5. Exception here!!
// ...
}
catch (Exception ex)
{
MessageBox.Show(String.Format("Damn '{0}'.", ex.Message), "Exception", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
如你所見,我已經提出了5個案例。
如果我設置事件處理程序,我得到一個異常,無法找到/加載程序集(它是管理控制台(mmc.exe)SnapIn。
ExecuteAssembly沒有找到入口點(好吧,沒有入口點)。
我不知道該類型是如何命名的。 如何通過接口加載?
類似於3.如何獲取程序集的名稱?
與1中的錯誤相同。
我認為問題可能是某種方式的管理控制台,或者我不知道我做錯了什么。 任何幫助表示贊賞。
更新1
我現在嘗試使用發布的代理解決方案。
AppDomain domain = AppDomain.CreateDomain("TempDomain");
InstanceProxy proxy = domain.CreateInstanceAndUnwrap(Assembly.GetAssembly(
typeof(InstanceProxy)).FullName, typeof(InstanceProxy).ToString()) as InstanceProxy;
if (proxy != null)
{
proxy.LoadAssembly(path);
}
AppDomain.Unload(domain);
public class InstanceProxy : MarshalByRefObject
{
public void LoadAssembly(string path)
{
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
Assembly asm = Assembly.LoadFrom(path);
Type[] types = asm.GetExportedTypes();
// ...see above...
}
}
這也不起作用。 在嘗試創建代理對象時,我得到一個異常:
無法加載文件或程序集“MyProject.SnapIn,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null”或其依賴項之一。 該系統找不到指定的文件。
錯誤消息中的文件是加載到mmc(SnapIn)中的文件。 知道如何修復此錯誤嗎? 不調用AppDomain.AssemblyResolve(在舊域或新域中都不會)。
更新2
我現在嘗試使用AppDomainSetup的解決方案。 現在,異常已更改為:
無法加載文件或程序集'file:/// C:/Development/MyProject/bin/SnapIn/MyProject.SnapIn.DLL'或其依賴項之一。 給定的程序集名稱或代碼庫無效。 (HRESULT異常:0x80131047)
任何想法?
嘗試這個:
namespace SeperateAppDomainTest
{
class Program
{
static void Main(string[] args)
{
LoadAssembly();
}
public static void LoadAssembly()
{
string pathToDll = Assembly.GetExecutingAssembly().CodeBase;
AppDomainSetup domainSetup = new AppDomainSetup { PrivateBinPath = pathToDll };
var newDomain = AppDomain.CreateDomain("FooBar", null, domainSetup);
ProxyClass c = (ProxyClass)(newDomain.CreateInstanceFromAndUnwrap(pathToDll, typeof(ProxyClass).FullName));
Console.WriteLine(c == null);
Console.ReadKey(true);
}
}
public class ProxyClass : MarshalByRefObject { }
請看一下之前的答案: 如何在Windows Mobile(.NET CF)上將程序集加載到不同的AppDomain中? 。 該答案創建了一個代理類,它運行到新的AppDomain上下文中,因此,您可以完全控制您的初始化。
您可以在ServiceApplicationProxy
類中創建一個Start()
方法,並使用proxy.Start()
從您的主機中正常調用它。
https://msdn.microsoft.com/en-us/library/3c4f1xde%28v=vs.110%29.aspx
指定
typeName類型:System.String
The fully qualified name of the requested type, including the namespace but not the assembly, as returned by the Type.FullName
屬性。
因此嘗試使用完全限定名稱調用,而不是使用typeof(InstanceProxy).ToString()
使用字符串/文本"<<Namespace>>.InstanceProxy"
如下
InstanceProxy proxy = domain.CreateInstanceAndUnwrap(path, "<<Namespace>>.InstanceProxy") as InstanceProxy;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.