Outlook アドインで発生する非常に奇妙なアセンブリ参照の問題と読み込みの問題があります。詳細は次のとおりです(長い話:)):
.Net 1.1 を使用して記述およびビルドされた古い Outlook アドインがあります。アドインは、独自のアプリケーション ドメインで管理されていない shim を使用して読み込まれます。ユーザーのマシンに 1.1 が存在しなくても、.Net 2.0 で問題なく動作します。
このアドインは、Outlook 2000 に対して VS 2003 によって作成されたカスタム Outlook 相互運用機能アセンブリを使用し、その後再構築して厳密な名前を付けます (私のアドインのように)。
アドイン プロジェクトでは、このカスタム相互運用アセンブリのみを参照し、公式の MS 相互運用アセンブリへの参照はありません。
このアドインを Outlook 2007 と .Net 2.0 の環境で使用すると、公式の MS 相互運用機能アセンブリが GAC にインストールされているため、何らかの理由で、アドインがそれらを読み込んで使用することがわかります。
Connect クラスのコードには、using ディレクティブがあります。
using Outlook;
これは、カスタム相互運用アセンブリの名前空間です。
Connect ctor には、次のコード行があります (テスト目的で追加されました)。
Assembly.LoadFrom(PATHTOMYASSEMBLY + "Interop.Outlook.dll");
Type type = typeof(Outlook.ApplicationClass);
logger.Debug("Outlook.Application full type is: {0}", type.AssemblyQualifiedName);
これは以下を出力します:
Outlook.Application の完全な種類: Outlook.ApplicationClass、Interop.Outlook、Version=9.0.0.0、Culture=neutral、PublicKeyToken=4cfbdc5349cf59d8
これはまさに私が期待したものです。
問題は、OnConnection(object application, Extensibility.ext_ConnectMode connectMode, object addInInst, ref System.Array custom) が呼び出されると、ログに表示されることです (現在のドメインの AssemblyLoad イベントへのフックがあります)。アセンブリもロードされます:
private void app_domain_AssemblyLoad(object sender, AssemblyLoadEventArgs args)
{
Assembly loadedAssembly = args.LoadedAssembly;
logger.Debug("Assembly {0} is loaded from: {1}", loadedAssembly.FullName, loadedAssembly.GlobalAssemblyCache ? "GAC" : loadedAssembly.Location);
}
出力:
アセンブリ Microsoft.Office.Interop.Outlook、Version=12.0.0.0、Culture=neutral、PublicKeyToken=71e9bce111e9429c のロード元: GAC
私の OnConnection メソッドは次のように始まります。
public void OnConnection(object application, Extensibility.ext_ConnectMode connectMode, object addInInst, ref System.Array custom)
{
Type type = application.GetType();
logger.Debug("OnConnection application object's full type is: {0}", type.AssemblyQualifiedName);
Outlook.Application applicationObject = (Outlook.Application)application;
これは以下を出力します:
OnConnection アプリケーション オブジェクトの完全な型は、Microsoft.Office.Interop.Outlook.ApplicationClass、Microsoft.Office.Interop.Outlook、Version=12.0.0.0、Culture=neutral、PublicKeyToken=71e9bce111e9429c です。
次の行で Outlook.Application に問題なくキャストできることがわかるので、これは非常に奇妙です。
Reflector で確認しましたが、アセンブリは Microsoft の相互運用アセンブリをまったく参照していません。私の Interop.Outlook.dll についても同じです。
それで、誰かが何が起こっているのか知っていますか?これらの質問に対する答えは何ですか:
Microsoft アセンブリをロードするのはなぜですか?
異なるアセンブリで定義された、無関係なクラス/インターフェイス間でキャストするにはどうすればよいですか?
注: 新しいアドインを作成しました。これは非常に単純なもので、何もせず、ロードするだけです。私は問題を再現できたので、CLRがどの相互運用機能をどこからロードするかをどのように決定するかを知っている人はいますか? GAC以外に、COMオブジェクトとそれが必要とする相互運用の間にリンクがある別の場所(レジストリ???)はありますか?