2008-12-03 36 views
6

Có vấn đề tham chiếu lắp ráp rất lạ và tải vấn đề tôi gặp phải với addin Outlook của tôi. Dưới đây là chi tiết (một câu chuyện dài :)):Trình tự lắp ráp liên kết COM

Tôi có một addin Outlook cũ, được viết và xây dựng sử dụng .Net 1.1. Addin được nạp bằng cách sử dụng một shim không được quản lý trong miền ứng dụng riêng của nó. Nó hoạt động OK, với .Net 2.0, ngay cả khi 1.1 không có mặt trên máy của người dùng.

Tiện ích bổ sung sử dụng lắp ráp interop Outlook tùy chỉnh, được tạo bởi VS 2003 đối với Outlook 2000 và sau đó xây dựng lại được đặt tên mạnh (như là phần bổ trợ của tôi).

Trong dự án bổ trợ, tôi chỉ tham chiếu đến lắp ráp interop tùy chỉnh này, không tham chiếu đến cụm hội đồng interop chính thức của MS.

Khi bổ trợ này được sử dụng trong môi trường với Outlook 2007 và .Net 2.0, nơi hội đồng interop chính thức MS được cài đặt trong GAC, vì một số lý do tôi thấy rằng tải bổ sung và sử dụng chúng.

Trong đoạn mã của lớp Connect, tôi có một chỉ thị sử dụng:

using Outlook; 

mà là không gian tên của lắp ráp tùy chỉnh interop tôi.

Trong Connect ctor tôi có những dòng mã (thêm vào cho mục đích thử nghiệm):

Assembly.LoadFrom(PATHTOMYASSEMBLY + "Interop.Outlook.dll"); 
Type type = typeof(Outlook.ApplicationClass); 
logger.Debug("Outlook.Application full type is: {0}", type.AssemblyQualifiedName); 

này kết quả đầu ra:

Outlook.Application đầy đủ loại là: Outlook.ApplicationClass, Interop .Outlook, Phiên bản = 9.0.0.0, Văn hóa = trung lập, PublicKeyToken = 4cfbdc5349cf59d8

Đó là chính xác những gì tôi mong đợi.

Vấn đề là, rằng khi OnConnection (object ứng dụng, Extensibility.ext_ConnectMode connectMode, đối tượng addInInst, ref System.Array tùy chỉnh) được gọi, tôi nhìn thấy trong nhật ký (Tôi có một cái móc để AssemblyLoad sự kiện của tên miền hiện tại) mà MS interop assembly được nạp cũng như:

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); 
} 

Output:

hội Microsoft.Office.Interop.Outlook, Version = 12.0.0.0, Văn hóa = n eutral, PublicKeyToken = 71e9bce111e9429c được nạp từ: GAC

phương pháp OnConnection của tôi bắt đầu như thế này:

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; 

này kết quả đầu ra: đầy đủ loại

OnConnection ứng dụng của đối tượng là: Microsoft.Office.Interop.Outlook.ApplicationClass, Microsoft.Office.Interop.Outlook, Version = 12.0.0.0, Văn hóa = trung tính, PublicKeyToken = 71e9bce111e9429c

Điều này thực sự kỳ lạ, như bạn có thể thấy rằng trên dòng tiếp theo tôi thành công có thể đúc để Outlook.Application mà không cần bất kỳ vấn đề.

Tôi đã kiểm tra với Reflector và hội đồng của tôi KHÔNG tham khảo các hội đồng interop của Microsoft theo bất kỳ cách nào. Tương tự cho Interop.Outlook.dll của tôi.

Vì vậy, có ai đó biết điều gì đang xảy ra không? Câu trả lời cho những câu hỏi này là gì:

  1. Tại sao nó tải tất cả các bộ phận của Microsoft?

  2. Làm cách nào để có thể truyền giữa các lớp/giao diện không liên quan, được xác định trong các hội đồng khác nhau?

LƯU Ý: Tôi đã tạo một phần bổ trợ mới, rất đơn giản, không có gì, chỉ tải. Tôi có thể tái tạo các vấn đề, vì vậy thực sự, không ai biết làm thế nào CLR quyết định những gì interop để tải và từ đâu. Bên cạnh đó trong GAC, là có một nơi khác (registry ???), nơi có một liên kết giữa một đối tượng COM và interop nó đòi hỏi?

Trả lời

6

Tôi nghĩ rằng tôi đã tìm thấy câu trả lời cho vấn đề của bạn trong mồi lót Primary Interop Assemblies của Microsoft. PIA được xử lý khác nhau trong Visual Studio:

Khi người dùng cố gắng thêm tham chiếu vào thư viện kiểu có PIA đã đăng ký, Visual Studio sẽ âm thầm sử dụng PIA đã đăng ký thay vì nhập lại thư viện kiểu bằng Tlbimp. Điều này đảm bảo rằng PIA được sử dụng bất cứ khi nào có thể.

Điều này có nghĩa là khi bạn thêm tham chiếu đến IA của riêng bạn vào dự án, Visual Studio sẽ kiểm tra xem có PIA đã đăng ký cho đối tượng COM này hay không. Outlook PIAs được đăng ký dưới khóa sau:

HKEY_CLASSES_ROOT\CLSID\{0006F023-0000-0000-C000-000000000046}\InprocServer32\12.0.0.0 
    Assembly="Microsoft.Office.Interop.Outlook, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71E9BCE111E9429C" 

Từ những gì tôi hiểu unregistering PIA bằng công cụ regasm nên loại bỏ phím và tái thêm các tài liệu tham khảo để IA của riêng bạn nên cho kết quả mong đợi.

Tuy nhiên, Microsoft không khuyên bạn nên sử dụng các IA tùy chỉnh nếu có PIA. Tôi không hiểu lý do chính xác cho điều này, nhưng tôi cho rằng điều này có thể liên quan đến tối ưu hóa marshaling và có định nghĩa kiểu duy nhất.

+0

cảm ơn divo. một vấn đề với câu trả lời - như tôi đã đặt trong câu hỏi, hội đồng interop của tôi được đặt tên mạnh, vì vậy nó vẫn không giải quyết được vấn đề của tôi. –

+0

Xin lỗi, tôi đã bỏ lỡ điều đặt tên mạnh mẽ, nhưng tôi đã sửa lại câu trả lời của mình. –

+0

Ok, nhưng làm cách nào, tôi không thấy các tham chiếu đến các PIA này trong mã được biên dịch của tôi? Như tôi đã nói, tôi đã kiểm tra bằng phản xạ, và không có chút tham chiếu nào cả. –

Các vấn đề liên quan