gpt4 book ai didi

c# - 在不同的 AppDomain 中加载/卸载程序集

转载 作者:IT王子 更新时间:2023-10-29 04:31:24 47 4
gpt4 key购买 nike

我需要在运行时加载的程序集中执行一个方法。现在我想在方法调用后卸载那些加载的程序集。我知道我需要一个新的 AppDomain 以便卸载库。但是这里,问题出现了。

要加载的程序集是我的插件框架中的插件。他们根本没有入口点。我所知道的是它们包含一些实现给定接口(interface)的类型。旧的非 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 个案例。

  1. 如果我设置事件处理程序,我会得到一个异常,即程序集(它是一个管理控制台 (mmc.exe) SnapIn。无法找到/加载。

  2. ExecuteAssembly 没有找到入口点(嗯,没有)。

  3. 我不知道该类型是如何命名的。如何通过接口(interface)加载?

  4. 类似3.如何获取程序集的名称?

  5. 与 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...
}
}

这也不行。尝试创建代理对象时,出现异常:

Could not load file or assembly 'MyProject.SnapIn, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.

错误消息中的文件已加载到 mmc(管理单元)中。知道如何解决这个错误吗? AppDomain.AssemblyResolve 未被调用(无论是在旧域还是新域)。

更新 2

我现在已经尝试了使用 AppDomainSetup 的解决方案。现在,异常已更改为:

Could not load file or assembly 'file:///C:/Development/MyProject/bin/SnapIn/MyProject.SnapIn.DLL' or one of its dependencies. The given assembly name or codebase was invalid. (Exception from 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 { }

关于c# - 在不同的 AppDomain 中加载/卸载程序集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2132649/

47 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com