2009-10-25 3 views
8

COM est connu pour rendre la rétrocompatibilité possible lors de la libération de nouveaux composants ou applications. Cela est possible car les interfaces dans COM sont stables, c'est-à-dire qu'elles ne changent pas.Comment faire évoluer une interface COM?

Je me suis efforcé de trouver une référence ou un livre qui traite d'une description de la manière d'utiliser une interface COM d'une version à une autre.

Voici mes exigences:

Nous avons une application qui peut être entraînée par l'automatisation ole. Les nouvelles versions de cette application peuvent être installées en parrallèle à des versions plus anciennes.

Les clients COM de cette application peuvent utiliser la version indépendante de PROGID, auquel cas ils travaillent avec la dernière version de l'application ou une version dépendante de PROGID, auquel cas ils travaillent avec la version spécifique de l'application.

Les modifications de l'automatisation COM ne doivent pas endommager les clients.

permet de voir un exemple:

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

Disons que je veux publier la version 2.0 de cette application qui étend certaines interfaces. Voici mon approche naïve de la version 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; 
     } 
} 

Est-ce la bonne façon de procéder?

Dois-je ajouter une classe Application10 et Application20 au Registre pour ajouter une possibilité d'instancier les différentes versions de l'application pour les clients de script?

Est-ce correct de changer la version et le GUID de la bibliothèque de types?

IDocument dans la version 2.0 a un nouvel IID. Puis-je toujours utiliser IDocument dans IApplication.ActiveDocument?

Comment dois-je enregistrer la coclasse ou l'interface dans le registre Windows dans les différentes versions?

Veuillez noter que je n'utilise pas ATL ou d'autres bibliothèques que l'API WIN32.

Si vous savez où puis-je trouver des informations à ce sujet (livres, références, etc.), veuillez en suggérer une.

J'apprécierais vraiment votre aide.

Répondre

10

Oui, vous devez modifier le class id de votre objet si plusieurs versions doivent coexister. Cependant vous pouvez maintenir un program id indépendant de la version comme "Word.Application" ou "InternetExplorer.Application" que redirects to the class id of the current version. La rétrocompatibilité est très difficile à maintenir. MSXML a apparemment abandonné la pratique de progID indépendant de la version.

Si vous décidez de conserver les anciennes interfaces (recommandé), vous devez implémenter à la fois les nouvelles et les anciennes interfaces dans votre nouvel objet.

Vous pouvez vérifier les entrées de registre de Microsoft Office. Il maintient très bien la rétrocompatibilité.

Le nom suggéré des nouvelles interfaces serait le nom d'interface avec le numéro de version, tel que IHtmlDocument6.

+0

Je voudrais vraiment apprendre des entrées de registre de Microsoft Office, mais je n'ai pas une ancienne version. Connaissez-vous des programmes freeware pour apprendre? – frast

+0

Pourquoi est-il nécessaire de changer le CLSID? L'implémentation implémentera toujours toutes les interfaces, n'est-ce pas? –

+0

@frast ou vérifiez IE. –

Questions connexes