Delphi TypeLibReader

Pascal Chapuis

Cet article présente le projet Delphi « TypeLibReader ». Ce projet est un lecteur de bibliothèque de type. Quelques fonctionnalités supplémentaires sont incluses avec un minidébogueur permettant de scrupter et scripter les objets Automation.

- Titre : Delphi TypeLibReader

- Auteur : Pascal Chapuis

- Parution : 16 mai 2005

- Mise à jour : 2 janvier 2020

- Licence : Copyright ® 2005 Pascal Chapuis. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. Présentation générale

- I-A. Lecture d'une bibliothèque de type et informations présentées

- I-B. Options d'affichage et Outils divers

- II. Mise au point Automation

- II-A. coClass : CoCreateInstance et ROT

- II-B. Inspecteur

- II-C. Script

- II-D. Projet Automation

- III. Problèmes connus - points faibles

- IV. Améliorations possibles

- V. Téléchargement et description des sources du projet

- VI. Références

I - Présentation générale

Ce projet Delphi permet de visualiser le contenu d'une bibliothèque de type (Type Library).

La source de cette bibliothèque peut-être :

- un fichier par exemple shdocvw.dll, mshtml.tlb, msscript.ocx… ;

- le choix dans les registres d'une bibliothèque enregistrée :

- le choix dans la ROT (Running Object Table) d'un objet enregistré :

La lecture de la bibliothèque de type présente les informations de façon structurée. Il est possible de personnaliser l'affichage.

Le projet « TypeLibReader » permet d'inspecter ou de modifier une propriété (type OLE non scalaire) de l'interface d'une CoClass supportant l'Automation (IDispatch). Cet objet Automation est scriptable (JavaScript ou vbscript) via le composant TSMScriptExecutor de Mike Shkolnik. Le (ou les) objet(s) créé(s), l'état de l'inspecteur d'objets, le script et les options en cours peuvent être sauvegardés dans un projet Automation.

I-A - Lecture d'une bibliothèque de type et informations présentées

Les informations contenues dans la bibliothèque de type sont présentées dans quatre onglets distincts :

1. Interface ;

2. dispInterface ou Interface dispatchable ;

3. CoClass ;

4. Structures et constantes.

Dans chaque onglet sont présentées les informations suivantes :

Onglet

Informations

Exemple

« Interface »

interface (non DUAL et non AUTOMATION), son GUI, l'héritage, les flags, la doc

IXMLDocument2 ['{2B8DE2FE-8D2D-11D1-B2FC-00C04FD915A9}'] = interface(IDispatch) #FHIDDEN# #FDISPATCHABLE#

« dispInterface »

interface DUAL / AUTOMATION, son GUI, l'héritage, les flags d'interface, la doc. Les propriétés (prop. Read, prop. Write, prop Write Ref) et méthodes (avec leurs flags, doc et dispid) de l'interface

IXMLDOMImplementation ['{2933BF8F-7B36-11D2-B20E-00C04F983E60}'] = dispinterface #FDUAL# #FNONEXTENSIBLE# #FDISPATCHABLE#

« CoClass »

coClass, son GUI, l'héritage, la doc. Chacune des interfaces héritées est représentée.

DOMDocument ['{2933BF90-7B36-11D2-B20E-00C04F983E60}'] = CoClass(IXMLDOMDocument, XMLDOMDocumentEvents) « W3C-DOM XML Document »

« TypeDef, Enum, Union »

Alias : mappage et doc
Énumération : constante et doc
structure : détail du record et doc

Alias DOMNodeType = tagDOMNodeType
Enum tagDOMNodeType = Enum
Struct _xml_error = Struct

I-B - Options d'affichage et Outils divers

Les options d'affichage sont les suivantes :

- « Afficher méthodes IUnknown/IDispatch » : filtre des méthodes provenant des interfaces IUnknown ou Idispatch ;

- « Types de données Delphi » : affichage au format IDL (VT_xxx) ou type Delphi ;

- « Classement alphabétique ».

Quelques petits utilitaires sont implémentés :

- « Chercher » : recherche d'une chaine via l'API ItypeLib.FindName ;

- « Copier la sélection vers le presse-papier » : export du texte de la sélection ;

- Liste des dernières bibliothèques de type ouvertes (MRU).

II - Mise au point Automation

La fonctionnalité de mise au point (debug) ne s'applique qu'aux objets Automation (IDispatch). La coClass associée à l'objet instancié est affichée en rouge. Quand une coClass est instanciée, l'inspecteur d'objets s'affiche. L'inspecteur d'objets est composé de trois onglets :

- « Prop. Lecture » : propriété en lecture, dernière valeur lue ;

- « Prop. Écriture » : propriété en écriture, dernière valeur fixée ;

- « Script » : liste des objets disponibles, code source du script, panneau de commande, erreurs de script.

II-A - coClass : CoCreateInstance et ROT

Sur une coClass le menu contextuel « CoCreateInstance » permet d'instancier un objet. Par exemple après avoir chargé la bibliothèque de type d'Internet Explorer, il est possible d'instancier le navigateur (CoClass/InternetExplorer). L'objet ainsi créé est automatiquement ajouté à la liste des « objets disponibles » pour le script.

L'API « CoCreateInstance » utilise différentes options (CLSCTX_INPROC_SERVER, CLSCTX_INPROC_HANDLER, CLSCTX_LOCAL_SERVER) disponibles dans le menu « Options »/« Flags coCreateInstance ».

Le menu contextuel « ReleaseInstance » permet de libérer l'instance de la coClass.

Quand l'objet choisi dans la ROT supporte l'implémentation de IDispatch alors la coClass correspondante est affichée en rouge.

II-B - Inspecteur

Pour les coClass instanciées (en rouge), le menu contextuel « Évaluer »/« Modifier » permet de scrupter/modifier la valeur des propriétés (type OLE non scalaire) de l'interface par défaut (Automation).

Il y a deux types principaux de types de propriétés :

- les propriétés de types OLE (widestring, integer, IUnknown, Idispatch…) ;

- les propriétés de type utilisateur (interface).

Pour les types OLE (non scalaire), la propriété et sa valeur sont inscrites dans l'onglet « Prop. Lecture/Écriture » de l'inspecteur d'objets. Les propriétés dont l'interface est de type utilisateur sont automatiquement créées (via invoke) et le détail des membres de cette propriété est affiché pour inspection. Il est alors possible de scruter une propriété de la propriété (ceci infiniment dans la mesure où le type (interface) de cette propriété est compatible Automation).

II-C - Script

La fonctionnalité de script est implémentée via le moteur de script de Microsoft (MS ScriptControl) et le composant « TSMScriptExecutor » de Mike Shkolnik @ Scalabium.com.

Dans la liste des objets disponibles de l'onglet script est recensé le nom des coClass instanciées (en rouge). Ces différents objets peuvent être utilisés dans le script via ce nom. En option le programme propose le choix d'un langage de script : JavaScript ou vbscript.

Cette fonctionnalité de script est nécessaire pour scripter les propriétés dont le type est générique : IDispatch. Elle est aussi pratique pour automatiser les tests.

II-D - Projet Automation

Un projet Automation sauvegarde :

- le nom de la bibliothèque de type en cours ;

- la liste des objets instanciés ;

- les propriétés en lecture/écriture de ces objets ;

- différentes options (langage..).

À l'ouverture de ce fichier, la bibliothèque de type est affichée, les coClass instanciées et les différentes propriétés lues/écrites.

La sauvegarde dans un projet Automation permet de sauvegarder le contexte d'un test.

III - Problèmes connus - points faibles

1. Dans ce projet le formatage dans le langage Delphi est très partiellement traité. Le programme traite la traduction des types OLE connus. Mais le principal problème du formatage Delphi réside dans la traduction du type de passage de paramètres (in/out, var, const).

2. Propriété de propriété de type utilisateur (interface) : L'évaluation d'un membre d'une propriété de type utilisateur échoue. Cette question est posée sur le newsgroup activeX de Borland (cf. groups.google.com avec comme chaine : « INVOKE_PROPERTYGET IDispatch property succeeded but Result=nil ? »).

3. Le nom de la bibliothèque de type de l'interface par défaut de la coclass choisie dans la ROT est lu dans les registres via la méthode « TRotObj.GetTypeLibFileNameWithIntfGuid ». À l'ouverture d'un projet Automation issu d'un objet choisi dans la ROT, le nom de la bibliothèque de type ouverte est fixé via cette méthode.

4. L'interface ne vérifie pas la disponibilité d'un objet instancié. Dans le cas où celui-ci est détruit, il se produit des erreurs lors de l'inspection/script.

Une liste de « TODO : » est présente dans le projet via le menu Delphi : Voir (View) / Liste des TODO (To-Do List).

IV - Améliorations possibles

1. Création dynamique : le chargement de certaines bibliothèques de type volumineuses est très long. La raison de cette lenteur est principalement expliquée par la lecture complète de la bibliothèque de type.

Une construction dynamique est possible, car chaque nœud possède un pointeur ITypeInfo le représentant. Cette construction dynamique correspond « à un câblage » de l'événement « expand » sur les méthodes « GetMembers »… Il serait intéressant de reprendre la partie sauvegarde (dans un projet Automation) des nœuds en lecture/écriture afin de permettre la construction dynamique au chargement d'un projet, mais aussi pour le chargement initial (fichier, registres, ROT).

2. Multibibliothèque de type: l'intérêt principal d'un fonctionnement Multifenêtré/Multibibliothèque de type est de pouvoir inspecter/scripter des objets provenant de plusieurs bibliothèques de type (par exemple: shdocvw.dll et mshtml.tlb).

3. Les fonctions héritées ne sont pas hiérarchisées via l'interface héritée. Les fonctions d'une interface ne sont pas présentées d'une façon hiérarchisée (cf. Microsoft OleView).

4. EDI de Script : actuellement les fonctionnalités de formatage et d'autocomplétion ne sont pas proposées. Cette carence est justifiée par la volonté de limiter le nombre de composants nécessaires à la compilation du projet. Ainsi les composants « SynEdit » ne sont pas inclus (à l'inverse de l'exemple de Mike Shkolnik accompagnant TSMScriptExecutor).

V - Téléchargement et description des sources du projet

Téléchargement du projet : TypeLibReader 1.42 Beta Src.zip

La source du projet est composée d'un groupe de projets « Groupe de projet Débogueur et COMs.bpg » qui contient deux projets.

- Le premier projet « TypeLibReader.exe » correspond au programme principal. Ce projet est lui-même composé de deux composantes principales :

1. Le lecteur/débogueur de bibliothèque de type (uTestTypeLib.pas, uTypeLibObj.pas, uFormChoiceRot.pas…) ;

2. Un objet Automation interne (TTESTRotQueryCancel du type TAutoIntfObject dans uIQueryCancelAutoPlay.pas) qui s'enregistre dans la ROT et permet de tester le cas particulier des objets in-process non enregistrés.

- Le second projet « TestDebugAutomation.exe » correspond à un projet de serveur OLE Automation out-process (TTestDebugCA du type TAutoObjectROTDebug dans uTestDebugCA.pas) avec inscription dans la ROT.

Ces deux objets Automation (TAutoIntfObject et TAutoObject) sont disponibles pour tester et mettre au point les fonctionnalités de mise au point Automation (debug) du lecteur.

Description des différents fichiers pas du projet

1. Groupe de projet Débogueur et COMs.bpg : groupe de projets

1. TypeLibReader.exe : lecteur de bibliothèque de type

1. uTestTypeLib.pas : fiche principale du lecteur/débogueur

2. uFormChoiceRot.pas : fiche de choix d'un objet dans la ROT

3. uTypeLibObj.pas : implémentation (via API et interfaces) des différentes fonctionnalités relatives aux bibliothèques de type (lecture…) et aux objets Automation (create, invoke…)

4. uRotViewer.pas : implémentation de la lecture d'un élément dans la ROT

5. TypeLibReader_TLB.pas : import Delphi de la bibliothèque de type des interfaces de test de l'objet TTESTRotQueryCancel

6. uIQueryCancelAutoPlay.pas : définition de la classe TTESTRotQueryCancel implémentant l'interface système (XP) « IQueryCancelAutoPlay » et les interfaces de test Automation

7. uFormTlbRegistry.pas : fiche de choix d'une bibliothèque de type dans le registre

8. uConfig.pas : définition (via mappage XML) de la configuration (IXMLConfigType) du lecteur

9. uProjetConfig.pas : définition (via mappage XML) de la configuration d'un projet Automation (IXMLProjetType)

2. TestDebugAutomation.exe : objet automation out-process pour test/ROT

1. uTestDebugCA.pas : définition de la classe TTestDebugCA implémentant les interfaces de test

2. TestDebugAutomation_TLB.pas : import Delphi de la bibliothèque de type des interfaces de test de l'objet TTestDebugCA

3. uFormCOMAutomationTest.pas : fiche principale du serveur Automation out-process

4. uTAutoObjectDebug.pas : implémentation des méthodes et des interfaces définies dans TestDebugAutomation_TLB

VI - Références

1. Documentation Delphi : chapitre « OLE Programmer's Reference » (C:\Program Files\Fichiers communs\Borland Shared\MSHelp\OLE.HLP)

2. MSDN API de lecture de bibliothèque de type

3. COM Automation : Type Information, Partie (II) , Partie (III) des articles de Sean Baxter

4. Delphi et ROT un article de gekko-software.nl

5. Composant Delphi « TSMScriptExecutor » de Mike Shkolnik @ Scalabium

6. Développement Delphi chez ChapsAndChips