核となる問題は次のとおりです。別の AppDomain でCOM 相互運用機能を使用する .NET アプリケーションがあります。COM スタッフは、COM スタッフが呼び出されている AppDomain ではなく、アセンブリをデフォルト ドメインにロードしているようです。
私が知りたいのは、これは予想される動作ですか、それとも、これらの COM 関連のアセンブリが間違った AppDomain に読み込まれるようにするために何か間違ったことをしているのですか? 以下の状況の詳細な説明を参照してください...
アプリケーションは 3 つのアセンブリで構成されています。 - アプリケーションのエントリ ポイントであるメイン EXE。- インターフェイス IController (IPlugin スタイル) のみを含む common.dll - IController および MarshalByRefObject を実装する Controller クラスを含む controller.dll。このクラスはすべての作業を行い、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 には、次の 2 つだけが含まれています。
public enum ControllerRunResult{FatalError, Finished, NonFatalError, NotRun}
public interface IController
{
ControllerRunResult Run();
}
そして、controller.dll には次のクラスが含まれています (COM 相互運用機能も呼び出します)。
public class Controller: IController, MarshalByRefObject
アプリケーションを最初に実行すると、Assembly.GetAssemblies() は予想どおりに表示され、common.dll は両方の AppDomains に読み込まれ、controller.dll はコントローラー ドメインにのみ読み込まれます。ただし、c.Run() を呼び出した後、COM 相互運用機能に関連するアセンブリがデフォルトの AppDomain に読み込まれ、COM 相互運用が行われている AppDomain には読み込まれていないことがわかります。
なぜこれが起こっているのでしょうか?
興味がある場合は、ここに少し背景があります。
もともと、これは 1 AppDomain アプリケーションでした。それがインターフェースするCOMのものは、長期間使用すると安定しないサーバーAPIです。COM から COMException (その原因に関する有用な診断情報がない) が発生した場合、COM 接続が再び機能する前に、アプリケーション全体を再起動する必要があります。COM アプリケーション サーバーに再接続するだけで、再びすぐに COM 例外が発生します。これに対処するために、COM 相互運用機能を別の AppDomain に移動しようとしました。これにより、謎の COMExceptions が発生したときに、それが発生した AppDomain をアンロードし、新しいものを作成して、アプリケーションを手動で再起動することなく、最初からやり直すことができます。 . とにかくそれが理論でした...