这是核心问题:我有一个.NET应用程序,在单独的AppDomain中使用COM互操作。COM部分似乎将程序集加载回默认域,而不是从调用COM部分的AppDomain中加载。
我想知道的是:这是预期行为还是我做错了什么,导致这些与COM相关的程序集在错误的AppDomain中加载?请参见下面更详细的情况描述...
该应用程序由3个程序集组成: - 主EXE,应用程序的入口点。 - common.dll,仅包含IController接口(以IPlugin风格) - controller.dll,包含实现IController和MarshalByRefObject的Controller类。此类执行所有工作并使用COM互操作与另一个应用程序交互。
主EXE的相关部分如下:
当第一次运行应用程序时,Assembly.GetAssemblies()看起来正常,common.dll被加载到两个AppDomains中,而controller.dll仅被加载到控制器域中。然而,在调用c.Run()之后,我发现与COM互操作相关的程序集已被加载到默认的AppDomain中,而不是从进行COM互操作的AppDomain中加载。
为什么会发生这种情况?
如果您感兴趣,这里是一些背景信息:
最初,这是一个单一的AppDomain应用程序。它所接口的COM内容是一个不稳定的服务器API。当来自COM内容的COMException(没有有用的诊断信息)发生时,整个应用程序必须重新启动才能再次使用COM连接。简单地重新连接到COM应用程序服务器会立即导致COM异常。为了应对这种情况,我尝试将COM互操作内容移入一个单独的AppDomain中,以便在发生神秘的COMExceptions时,可以卸载其中发生的AppDomain,创建一个新的并重新开始,所有这些都无需手动重新启动应用程序。那是理论上的想法...
我想知道的是:这是预期行为还是我做错了什么,导致这些与COM相关的程序集在错误的AppDomain中加载?请参见下面更详细的情况描述...
该应用程序由3个程序集组成: - 主EXE,应用程序的入口点。 - common.dll,仅包含IController接口(以IPlugin风格) - controller.dll,包含实现IController和MarshalByRefObject的Controller类。此类执行所有工作并使用COM互操作与另一个应用程序交互。
主EXE的相关部分如下:
AppDomain controller_domain = AppDomain.CreateDomain("Controller Domain");
IController c = (IController)controller_domain.CreateInstanceFromAndUnwrap("controller.dll", "MyNamespace.Controller");
result = c.Run();
AppDomain.Unload(controller_domain);
common.dll只包含这两个东西:
public enum ControllerRunResult{FatalError, Finished, NonFatalError, NotRun}
public interface IController
{
ControllerRunResult Run();
}
控制器.dll包含这个类(也调用COM互操作的内容):
public class Controller: IController, MarshalByRefObject
当第一次运行应用程序时,Assembly.GetAssemblies()看起来正常,common.dll被加载到两个AppDomains中,而controller.dll仅被加载到控制器域中。然而,在调用c.Run()之后,我发现与COM互操作相关的程序集已被加载到默认的AppDomain中,而不是从进行COM互操作的AppDomain中加载。
为什么会发生这种情况?
如果您感兴趣,这里是一些背景信息:
最初,这是一个单一的AppDomain应用程序。它所接口的COM内容是一个不稳定的服务器API。当来自COM内容的COMException(没有有用的诊断信息)发生时,整个应用程序必须重新启动才能再次使用COM连接。简单地重新连接到COM应用程序服务器会立即导致COM异常。为了应对这种情况,我尝试将COM互操作内容移入一个单独的AppDomain中,以便在发生神秘的COMExceptions时,可以卸载其中发生的AppDomain,创建一个新的并重新开始,所有这些都无需手动重新启动应用程序。那是理论上的想法...