2009-10-25 38 views
8

COM được biết là có khả năng tương thích ngược khi có thể phát hành các thành phần hoặc ứng dụng mới. Điều này là có thể vì các giao diện trong COM ổn định tức là chúng không thay đổi.Làm cách nào để phát triển giao diện COM?

Tôi đã cố gắng hết sức để tìm một tài liệu tham khảo hoặc cuốn sách đề cập đến việc giảm tiêu chuẩn về cách tránh giao diện COM từ phiên bản này sang phiên bản khác.

Sau đây là các yêu cầu của tôi:

Chúng tôi có một ứng dụng có thể được thúc đẩy bởi tự động hóa ole. Các phiên bản mới của ứng dụng này có thể được cài đặt song song với các phiên bản cũ hơn.

Khách hàng COM của ứng dụng này có thể sử dụng PROGID độc lập phiên bản trong trường hợp họ làm việc với phiên bản mới nhất của ứng dụng hoặc PROGID phụ thuộc phiên bản trong trường hợp họ làm việc với phiên bản ứng dụng cụ thể.

Thay đổi đối với tự động hóa COM sẽ không làm hỏng bất kỳ khách hàng nào.

Cho phép xem một ví dụ:

#include <olectl.h> 
#include <fxbase\autoif.h> 

[ 
    uuid(A1B3A66F-806F-46a2-82D9-9C278F415148), 
    lcid(-1), 
    version(1.0) 
] 

library LIB 
{ 
     importlib("stdole2.tlb"); 

     [ 
      uuid(82CDE055-790A-4505-BF3E-3282170C8FC6), 
      helpstring("Document"), 
      oleautomation, 
      dual, 
      nonextensible 
     ] 
     interface IDocument : IDispatch 
     { 
       [id(0x00000001), propget, helpcontext(0x0012c94a)] 
       HRESULT Name([out, retval] BSTR* psName); 

       [id(0x00000001), propput, helpcontext(0x0012c94a)] 
       HRESULT Name([in] BSTR psName); 
     } 

     [ 
      uuid(919B9E6E-76C0-4c23-A188-5840E5900997), 
      helpstring("Application object."), 
      oleautomation, 
      dual, 
      nonextensible 
     ] 
     interface IApplication : IDispatch 
     { 
      [id(0x00000001), propget, helpstring("Returns the active document of the application.")] 
      HRESULT ActiveDocument([out, retval] IDocument** retval); 
     } 

     [ 
      uuid(E0AA6FCA-AEF1-460b-A1F9-26250C28594B), 
      helpstring("Application 1.0 Class"), 
      appobject 
     ] 
     coclass Application 
     { 
      [default] interface IApplication; 
           interface IDispatch; 
     } 
} 

phép nói rằng tôi muốn xuất bản phiên bản 2.0 của ứng dụng này kéo dài một số giao diện. Đây là cách tiếp cận ngây thơ của tôi đối với phiên bản 2.0:

#include <olectl.h> 
#include <fxbase\autoif.h> 

[ 
    uuid(3D4688A2-91F8-4cd8-989A-845810A05557), 
    lcid(-1), 
    version(2.0) 
] 

library LIB 
{ 
     importlib("stdole2.tlb"); 

     [ 
      uuid(82CDE055-790A-4505-BF3E-3282170C8FC6), 
      helpstring("Document"), 
      oleautomation, 
      dual 
     ] 
     interface IDocument10 : IDispatch 
     { 
       [id(0x00000001), propget, helpcontext(0x0012c94a)] 
       HRESULT Name([out, retval] BSTR* psName); 

       [id(0x00000001), propput, helpcontext(0x0012c94a)] 
       HRESULT Name([in] BSTR psName); 
     } 

     [ 
      uuid(AF404510-216A-407e-99F4-0636AF071B68), 
      helpstring("Document"), 
      oleautomation, 
      dual, 
      nonextensible 
     ] 
     interface IDocument : IDocument10 
     { 
       [id(0x00000001), propget, helpcontext(0x0012c94a)] 
       HRESULT Type([out, retval] BSTR* psType); 

       [id(0x00000001), propput, helpcontext(0x0012c94a)] 
       HRESULT Type([in] BSTR psType); 
     } 

     [ 
      uuid(919B9E6E-76C0-4c23-A188-5840E5900997), 
      helpstring("Application object."), 
      oleautomation, 
      dual 
     ] 
     interface IApplication10 : IDispatch 
     { 
      [id(0x00000001), propget, helpstring("Returns the active document of the application.")] 
      HRESULT ActiveDocument([out, retval] IDocument** retval); 
     } 

     [ 
      uuid(6A851C3F-21DF-4f5e-A4D6-2EF5A9D234C6), 
      helpstring("Application object."), 
      oleautomation, 
      dual, 
      nonextensible 
     ] 
     interface IApplication : IApplication10 
     { 
      [id(0x00000002), propget, helpstring("Is the application visible.")] 
      HRESULT Visible([out, retval] BOOL* retval); 
     } 

     [ 
      uuid(AA760349-1682-4ab6-BF0C-C02E620715CF), 
      helpstring("Application 2.0 Class"), 
      appobject 
     ] 
     coclass Application 
     { 
      [default] interface IApplication; 
           interface IDispatch; 
     } 
} 

Đây có phải là cách đúng để thực hiện việc này không?

Tôi có nên thêm một lớp Application10 và Application20 vào Sổ đăng ký để thêm khả năng thể hiện các phiên bản ứng dụng khác nhau cho trình khách script không?

Có quyền thay đổi phiên bản GUID của thư viện kiểu không?

ID tài liệu trong phiên bản 2.0 có IID mới. Tôi vẫn có thể sử dụng IDocument trong IApplication.ActiveDocument?

Làm cách nào để đăng ký coclass hoặc giao diện trong Windows Registry trong các phiên bản khác nhau?

Xin lưu ý rằng tôi không sử dụng ATL hoặc các thư viện khác ngoài WIN32-API.

Nếu bạn biết nơi tôi có thể tìm thấy thông tin về điều này (sách, tài liệu tham khảo, v.v.), vui lòng đề xuất một.

Tôi thực sự đánh giá cao sự trợ giúp của bạn.

Trả lời

10

Có, bạn cần thay đổi class id đối tượng của mình nếu muốn nhiều phiên bản cùng tồn tại. Tuy nhiên, bạn có thể duy trì phiên bản program id độc lập với phiên bản như "Word.Application" hoặc "InternetExplorer.Application" mà redirects to the class id of the current version. Khả năng tương thích ngược rất khó duy trì. MSXML dường như đã từ bỏ việc thực hành progID độc lập với phiên bản.

Nếu bạn quyết định giữ giao diện cũ (được khuyến nghị), bạn cần triển khai cả giao diện mới và cũ trong đối tượng mới của mình.

Bạn có thể muốn kiểm tra các đăng ký của Microsoft Office. Nó duy trì khả năng tương thích ngược khá tốt.

Tên được đề xuất của giao diện mới sẽ là tên giao diện cộng với số phiên bản, chẳng hạn như IHtmlDocument6.

+0

Tôi thực sự muốn tìm hiểu từ các mục đăng ký Microsoft Office nhưng tôi không có phiên bản cũ. Bạn có biết các chương trình phần mềm miễn phí để học hỏi không? – frast

+0

Tại sao cần thay đổi CLSID? Việc thực hiện sẽ vẫn thực hiện tất cả các giao diện nó đã làm, phải không? –

+0

@frast hoặc kiểm tra IE. –

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