从另一个AppDomain接收程序集引用时发生异常

本文关键字:异常 引用 程序集 另一个 AppDomain | 更新日期: 2023-09-27 17:50:19

我正在从一个新的AppDomain的特定"extensions"目录中加载所有dll,以从中获得一些反射相关的信息。

这就是我正在尝试的:

我在我的解决方案中创建了一个新的库AssemblyProxy,它只有这个类:

public class AssemblyProxy : MarshalByRefObject
{
    public Assembly LoadFile( string assemblyPath )
    {
      try
      {
        return Assembly.LoadFile( assemblyPath );
      }
      catch
      {
        return null;
      }
    }
}

我确保这个DLL存在于我的"扩展"目录中。然后,我使用以下代码将"extensions"目录中的所有程序集加载到新的AppDomain中。

foreach( string extensionFile in Directory.GetFiles( ExtensionsDirectory, "*.dll" ) )
{
        Type type = typeof( AssemblyProxy.AssemblyProxy );
        var value = (AssemblyProxy.AssemblyProxy) Domain.CreateInstanceAndUnwrap(
            type.Assembly.FullName,
            type.FullName );
        var extensionAssembly = value.LoadFile( extensionFile );
        types.AddRange( extensionAssembly.GetTypes() );
}

一些dll确实被成功加载,但在一些dll上抛出一个异常,如下所示:

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

编辑:在新的AppDomain中没有抛出异常。DLL成功加载到新的AppDomain中。一旦将程序集引用返回到主/调用AppDomain,就会抛出异常。是否主/调用AppDomain试图加载程序集在自己刚刚收到引用?

谢谢。

从另一个AppDomain接收程序集引用时发生异常

您不应该从新的AppDomain返回Assembly对象,因为这只会在您的主AppDomain可以访问这些程序集的情况下工作,因为程序集位于以下目录:

  • 不是AppDomain的基目录(AppDomain. basedirectory),
  • 不在AppDomain的相对搜索路径(AppDomain. privatebinpath)中指定的目录中

避免这种情况的一种方法是跟随leppie的注释和:

  1. 创建包含Assembly对象所需的最少信息的序列化类型。
  2. 将此类型添加到两个AppDomain都可以访问的新程序集中。最简单的方法是将其添加到GAC中。

另一种方法是使用Mono。Cecil代替System.Reflection。Mono。塞西尔会允许你检查组件而不需要装载它们。对于一个非常简单的例子,请看这个答案的后半部分。