[.net] COM interop 어셈블리로드 시퀀스



Answers

Question

아주 이상한 어셈블리 참조 문제 및 내 Outlook 추가 기능에서 발생하는 로딩 문제가 있습니다. 세부 사항은 다음과 같습니다 (긴 이야기 :)).

나는 오래된 Outlook addin을 가지고 있고 닷넷 1.1을 사용하여 작성하고 작성했다. 추가 기능은 자체 응용 프로그램 도메인에서 관리되지 않는 심을 사용하여로드됩니다. 1.1이 사용자 컴퓨터에 없더라도 .Net 2.0에서는 정상적으로 작동합니다.

추가 기능은 Outlook 2003에 대해 VS 2003에서 만든 사용자 지정 Outlook interop 어셈블리를 사용하고 그 후 다시 작성하여 강력한 추가 기능을 제공합니다 (내 추가 기능과 동일).

addin 프로젝트에서이 사용자 지정 interop 어셈블리 만 참조하며 공식 MS interop 어셈블리는 참조하지 않습니다.

이 addin이 Outlook 2007 및 공식 MS interop 어셈블리가 GAC에 설치된 .Net 2.0이있는 환경에서 사용되는 경우, 추가 기능이로드되어 사용되는 것을 볼 수 있습니다.

Connect 클래스의 코드에는 using 지시문이 있습니다.

using Outlook;

내 사용자 지정 interop 어셈블리의 네임 스페이스입니다.

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, 버전 = 9.0.0.0, 문화 = 중립, PublicKeyToken = 4cfbdc5349cf59d8

정확히 내가 기대했던 것입니다.

문제는 OnConnection (개체 응용 프로그램, Extensibility.ext_ConnectMode connectMode, 개체 addInInst, ref System.Array 사용자 지정) 호출 될 때, 나는 (현재 도메인의 AssemblyLoad 이벤트에 대한 후크가있는) 로그에서 MS interop 어셈블리도로드됩니다.

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, 버전 = 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으로 캐스팅 할 수 있음을 알 수 있습니다. 아무 문제없이 응용 프로그램을 사용할 수 있습니다.

리플렉터를 확인해 본 결과 어셈블리는 Microsoft의 interop 어셈블리를 참조하지 않습니다. 내 Interop.Outlook.dll과 동일합니다.

그래서, 어떤 일이 벌어지고 있는지 아는 사람이 있습니까? 이 질문에 대한 답은 무엇입니까?

  1. Microsoft 어셈블리를 전혀로드하지 않는 이유는 무엇입니까?

  2. 서로 다른 어셈블리에 정의 된 관련없는 클래스 / 인터페이스간에 어떻게 캐스팅 할 수 있습니까?

NOTE : 새로운 addin을 만들었습니다. 아주 간단한 것입니다. 문제를 재현 할 수 있기 때문에 CLR이 어떻게 interop을로드할지, 어디에서 결정 할지를 아는 사람이 누구인지 알 수 있습니다. GAC 외에 COM 개체와 interop간에 필요한 링크가있는 곳 (레지스트리 ???)이 있습니까?




Related