===============================================
Ce tuto est basé sur le source de Philippe Heiz
===============================================
Les fichiers .manifest permettent d'installer sans toucher au registre.
Ils permettent donc:
D'utiliser plusieurs dlls ActiveX ou ocx dans plusieurs versions sur le même PC.
D'"installer" sur des PC ou on n'a pas le droit d'installer.
D'"installer" par simple copie de fichier.
De ne pas encombrer la base de registre.
Les moins:
Fonctionne sous XP (et sûrement 2000).
Le programme peut utiliser des fichiers déjà présent dans system32, donc on prend plus d'espace disque que l'on devrait.
L'installation de msvbvm60.dll par .manifest n'est peut être pas complète, mais c'est un fichier extremement courant sous XP.
Les .manifest ne fonctionnent pas avec les .vbp.
Les .manifest sont donc une très bonne alternative au programmes d'installations que les admins vous conseillerons.
Ce sont de simples fichiers qu'il faut placer dans un répertoire ou se trouve l'exe et les dlls et ocxs.
Apparement ils sont écrits dans un langage de script orienté internet, le xml (Extensible Markup Language).
Le programme de Philippe Heiz permet de générer automatiquement ces fichiers.
Cependant, sa routine de recherche de dépendances fonctionne mal, mais peut on faire mieux ?
Mais le reste de son application est une pure merveille (J'ai mis un petit mode d'emplois dans la conclusion).
J'ai fait ce tuto pour ceux qui souhaiteraient en savoir un peu plus ou rédiger les .manifest manuellement.
Sommaire:
#1 Savoir ce qu'il faut toujours installer
#2 Savoir ce que votre application a besoin en plus
#3 Faire une copie des dlls et ocxs dans le même répertoire que l'exe
#4 Rédiger le manifest de l'exe
#5 Récupérer des informations dans la base de registre
#6 Rédiger les fichier des dlls et ocxs
#7 Conclusion
#8 Bonus
#1 Savoir ce qu'il faut toujours installer:
L'empaqueteur fourni avec VB6 donne:
asycfilt.dll
COMCAT.dll
msvbvm60.dll
oleaut32.dll
olepro32.dll
stdole2.tlb
VB6FR.dll
VB6STKIT.dll
De tout ceux là, je conseil de mettre impérativement VB6FR.dll dans le même dossier que l'exe.
Ce fichier n'a pas besoin d'installation.
Les autres sont généralement présents, et en version suffisantes (sous XP).
Leurs installations, pour ceux qui en ont besoins, est un vrai cassetête (msvbvm60.dll est une dll vraiment complexe, rgsvr32 ne marche passtdole2.tlb, qui pourtant a des clés...).
#2 Savoir ce que votre application a besoin en plus:
Tout ce que vous avez rajoutez dans "Références..." et "Composant...".
Dans Composant, on récupère des contrôles ActiveX (.ocx).
Un .ocx peut contenir plusieurs controle.
Mais ici, l'important est de noter les noms des fichiers et leurs chemins d'accès, en vue de les récupérer.
Il faut bien entendu installer tout ce qui est appelé par CreateObject.
Dans "Références..." il s'agit plutôt de dll.
Les dlls contiennent des classes.
Je ne sais pas installer un .tlb avec un Manifest.
#3 Faire une copie des dlls et ocxs dans le même répertoire que l'exe:
Avec VB6FR.dll en plus.
#4 Rédiger le manifest de l'exe:
Avant tout, il faut afficher les extensions dans l'explorateur Windows.
Ensuite, pour une application nommée "NomApp.exe" ayant besoin de
"NomDll1.dll"
"NomDll1.dll"
"NomOcx1.ocx"
"NomOcx2.ocx"
Il faut créer un fichier texte nommé "NomApp.exe.manifest" dans le dossier de l'exe, et l'éditer avec notepad.
Dedans, il faut mettre:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32" name="NomApp.exe" version="1.0.0.1" processorArchitecture="x86" />
<dependency><dependentAssembly><assemblyIdentitytype="win32" name="dep.NomDll1.dll" version="1.0.0.1"processorArchitecture="x86"/></dependentAssembly></dependency>
<dependency><dependentAssembly><assemblyIdentitytype="win32" name="dep.NomDll2.dll" version="1.0.0.1"processorArchitecture="x86"/></dependentAssembly></dependency>
<dependency><dependentAssembly><assemblyIdentitytype="win32" name="dep.NomOcx1.ocx" version="1.0.0.1"processorArchitecture="x86"/></dependentAssembly></dependency>
<dependency><dependentAssembly><assemblyIdentitytype="win32" name="dep.NomOcx2.ocx" version="1.0.0.1"processorArchitecture="x86"/></dependentAssembly></dependency>
</assembly>
Vous pouvez copier ce texte, puis remlacer:
"NomApp.exe"
"NomDll1.dll"
"NomDll2.dll"
"NomOcx1.ocx"
"NomOcx2.ocx"
par votre exe et vos dépendances.
Vous pouvez bien sûr rajouter ou supprimer des lignes commençant par "<dependency>".
Ne touchez pas à la version.
Ce premier fichier est terminé !
#5 Récupérer des informations dans la base de registre:
A présent, il vat falloir récupérer des informations sur les classes des dlls, et les contrôles des ocx.
Dans la suite, je confonds classes et contrôles: je les appels tous les deux classes.
Là encore, le source de Philippe Heiz fonctionne à merveille (Onglet "single").
L'automatisation de la rédaction peut être intérressante si vous utiliser par exemple "comctl32.ocx".
Ce fichier ne contient pas moins de 24 classes !
En manuel, donc, il faut récupérer les noms des classes et le tlbid du fichier, puis pour chaque classes:
Le CLSID
La description
Le progID
Avant tout, deux trois infos sur la stratégie Microsoft.
Microsoft est parti du principe que deux personnes pouvait compiler deux fichiers ayant le même nom.
Il est évident que cela aurait posé problème si on était resté avec des appels de type APIs sur des fichiers dans system32.
Conséquement, microsoft à décidé que lors de chaque premièrecompilation de dlls ActiveX et ocxs un numéro unique (CLSID) seraitassocié à ce fichier.
Ce numéro serait sauvegardé dans la base de registre, et serait associé au chemin d'accès du fichier.
De cette manière plusieurs application pourrait utiliser plusieursfichiers portant le même nom (Mais se trouvant à des emplacementsdifférent).
En ce qui me concerne, je trouve ce raisonement parfaitement STUPIDE,et je pense cependant être plus pro-Microsoft que la moyenne.
Vous allez comprendre mon énervement après ce petit tour dans la base de registre.
Au passage, je rappel que si vous compilés un dll ou ocx, et que voussupprimer le fichier et le source, les clés de ce fichiers serontpratiquement insupprimables de la base de registre.
(Ne pas oublier le "regsvr32 /U nomdll" avans suppression !!!!)
Le gros avantage des .manifest est qu'il permette de ne pas s'occuperde la pieuvre, ni de l'encombrer, parce qu'elle n'en a vraiment pasbesoin.
(Au dernière nouvelles, Microsoft conseil d'utiliser au maximum les ini, mais c'est un peu tard...)
Occupons nous de récupérer les infos sur "NomDll1.dll".
Je rappel qu'elle doit être installée, et correctement, sur le PC.
Autement dit, si vous avez compilez une première "NomDll1.dll" à partird'un source, supprimé sans faire gaffe la source et la dll, y aurasouci !
(Je conseil de toujours mettre le même préfixe ou suffixe dans le nomsde dll ou d'ocx, de manière à pouvoir les retrouver toutes facilementdans la base de registre.)
Lancé regedt32.exe (Sous XP, il lance regedit.exe).
Je rappel que la clé "HKEY_CLASSES_ROOT" est un alias de la clé "HKEY_LOCAL_MACHINE\SOFTWARE\Classes".
Autrement dit, si vous modifiez l'une, l'autre est modifiée aussi: se sont les deux même clés !
Si vous voulez travailler dans regedit.exe, libre à vous !
Mais je vous conseille d'exporter "HKEY_CLASSES_ROOT", pour plus de sécurité, et surtout de rapidité.
Pour l'exporter, clique droit sur la clé, "Exporter".
Ouvrer le fichier créé avec notepad (Clique droit sur le fichier, "Modifier")
Vous voilà devant un petit fichier qui fait 16.9 Mo chez moi (61.6 Mo pour la base)!
Commençons par chercher les classes de "NomDll1.dll" ("Edition", "rechercher...", "NomDll1.dll").
F3 et ctrl+F: des raccourcis très utiles.
Vous allez tomber sur des chemins d'accès, sous clé de "CLSID" ou "TypeLib".
Il ne devrait y avoir qu'un chemin sous clé de Typelib, par exemple:
[HKEY_CLASSES_ROOT\TypeLib\{872FF3B4-E1A8-466D-86CC-D7CD38BE723B}\1.0\0\win32]
@="C:\\Documents and Settings\\Bruno\\Bureau\\nomDll1.dll"
Ce qui nous intéresse, c'est {872FF3B4-E1A8-466D-86CC-D7CD38BE723B}.
Nottez le.
Vous trouverez un chemin sous clé de CLSID par classe.
[HKEY_CLASSES_ROOT\CLSID\{9A68CFA5-D557-4BB8-A957-D32AFBD8AE72}\InprocServer32]
@="C:\\Documents and Settings\\Bruno\\Bureau\\nomDll1.dll"
"ThreadingModel"="Apartment"
[HKEY_CLASSES_ROOT\CLSID\{9A68CFA5-D557-4BB8-A957-D32AFBD8AE72}\ProgID]
@="nomDll1.NomClass1"
Là j'ai copié la clé du chemin, et la suivante.
Miracle, le CLSID, c'est {9A68CFA5-D557-4BB8-A957-D32AFBD8AE72} et le ProgID, c'est: "nomDll1.NomClass1".
Récupérez aussi la clé du CLSID:
[HKEY_CLASSES_ROOT\CLSID\{9A68CFA5-D557-4BB8-A957-D32AFBD8AE72}]
@="nomDll1.NomClass1"
"AppID"="{9A68CFA5-D557-4BB8-A957-D32AFBD8AE72}"
La valeur par défaut (Le @) c'est la description : "nomDll1.NomClass1" !
La descritption est généralement plus intérressante sur les contrôles Windows ou autre.
on a donc:
Un typeLib (tlbID) par fichier.
Un CLSID, un PRogID et une description par classe.
#6 Rédiger les fichier des dlls et ocxs:
Voici le contenu de "dep.nomDll1.dll.manifest":
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32" name="dep.nomDll1.dll" version="1.0.0.1" processorArchitecture="x86" />
<file name="nomDll1.dll">
<comClass clsid="{9A68CFA5-D557-4BB8-A957-D32AFBD8AE72}"description="nomDll1.NomClass1" progid="nomDll1.NomClass1"tlbid="{872FF3B4-E1A8-466D-86CC-D7CD38BE723B}" />
<comClass clsid="{A88D02AA-F4C1-4004-99FF-171441688DB2}"description="nomDll1.NomClass2" progid="nomDll1.NomClass2"tlbid="{872FF3B4-E1A8-466D-86CC-D7CD38BE723B}" />
</file>
</assembly>
Ne pas oublier le "dep." devant le nom de fichier !
On reconnait bien le CLSID, la description, le ProgID, et le TypeLibrécupérés dans la première ligne débutant par "<comClass"
La deuxième ligne concerne la deuxième classe de la dll, le CLSID, ladescription, le ProgID sont différent, mais le TypeLib reste identique:il n'y en a qu'un par fichier.
Je rappel qu'il faut un manifest par dll et ocx + celui de l'exe.
Les manifest des dlls et ocxs sont indépendants de l'application, on n'est pas obligé de les écrire à chaque exe.
On procède de la même façon pour le ocxs.
#7 Conclusion:
regsvr32 installe des sous clé en plus de celles sous le TypeLib et CLSID.
Je dis ça pour ceux qui voudrait faire un prog d'installation.
J'espère que ce tuto vous a intérressé, bien qu'il soit très rébarbatif.
Je vous conseil plutôt d'utiliser le source de Philippe Heiz, de cette manière.
Dans l'onglet application, sélectionner vote exe.
Ne cliquez pas sur "GetDependencies", mais sur "Add from file".
Ajouter de cette manière les fichiers dont votre application à besoin.
Cliquez sur "Write isolation Package".
Rajouter le fichier VB6FR.dll et les dlls et ocx dans le dossier de l'exe.
Vous voilà avec une application qui n'a pas besoin d'installation !
#8 Bonus:
Les manifest de:
msvbvm60.dll (Peut être incomplet)
olepro32.dll (Il n'y a pas de CLSID !!!)
comctl32.ocx (Les deux autres sont des protos, mais celui-là est un vrai)
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32" name="dep.msvbvm60.dll" version="1.0.0.1" processorArchitecture="x86" />
<file name="msvbvm60.dll">
<comClass clsid="{D5DE8D20-5BB8-11D1-A1E3-00A0C90F2731}"description="VBPropertyBag"tlbid="{000204EF-0000-0000-C000-000000000046}" />
</file>
</assembly>
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32" name="dep.olepro32.dll" version="1.0.0.1" processorArchitecture="x86" />
<file name="olepro32.dll">
<comClass tlbid="{BEF6E001-A874-101A-8BBA-00AA00300CAB}" />
</file>
</assembly>
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32" name="dep.comctl32.ocx" version="1.0.0.1" processorArchitecture="x86" />
<file name="comctl32.ocx">
<comClass clsid="{0713E8A2-850A-101B-AFC0-4210102A8DA7}"description="Microsoft TreeView Control, version 5.0 (SP2)"progid="COMCTL.TreeCtrl.1"tlbid="{6B7E6392-850A-101B-AFC0-4210102A8DA7}" />
<comClass clsid="{0713E8A8-850A-101B-AFC0-4210102A8DA7}"description="TreeView General Property Page Object"tlbid="{6B7E6392-850A-101B-AFC0-4210102A8DA7}" />
<comClass clsid="{0713E8D2-850A-101B-AFC0-4210102A8DA7}"description="Microsoft ProgressBar Control, version 5.0 (SP2)"progid="COMCTL.ProgCtrl.1"tlbid="{6B7E6392-850A-101B-AFC0-4210102A8DA7}" />
<comClass clsid="{0713E8D8-850A-101B-AFC0-4210102A8DA7}"description="Progress Bar General Property Page Object"tlbid="{6B7E6392-850A-101B-AFC0-4210102A8DA7}" />
<comClass clsid="{373FF7F0-EB8B-11CD-8820-08002B2F4F5A}"description="Microsoft Slider Control, version 5.0 (SP2)"progid="COMCTL.Slider.1" tlbid="{6B7E6392-850A-101B-AFC0-4210102A8DA7}"/>
<comClass clsid="{373FF7F4-EB8B-11CD-8820-08002B2F4F5A}"description="Slider General Property Page Object"tlbid="{6B7E6392-850A-101B-AFC0-4210102A8DA7}" />
<comClass clsid="{58DA8D8A-9D6A-101B-AFC0-4210102A8DA7}"description="Microsoft ListView Control, version 5.0 (SP2)"progid="COMCTL.ListViewCtrl.1"tlbid="{6B7E6392-850A-101B-AFC0-4210102A8DA7}" />
<comClass clsid="{58DA8D8F-9D6A-101B-AFC0-4210102A8DA7}"description="Microsoft ImageList Control, version 5.0 (SP2)"progid="COMCTL.ImageListCtrl.1"tlbid="{6B7E6392-850A-101B-AFC0-4210102A8DA7}" />
<comClass clsid="{58DA8D93-9D6A-101B-AFC0-4210102A8DA7}"description="ImageList General Property Page Object"tlbid="{6B7E6392-850A-101B-AFC0-4210102A8DA7}" />
<comClass clsid="{58DA8D96-9D6A-101B-AFC0-4210102A8DA7}"description="Image Property Page Object"tlbid="{6B7E6392-850A-101B-AFC0-4210102A8DA7}" />
<comClass clsid="{5ACBB955-5C57-11CF-8993-00AA00688B10}"description="ListView General Property Page Object"tlbid="{6B7E6392-850A-101B-AFC0-4210102A8DA7}" />
<comClass clsid="{5ACBB956-5C57-11CF-8993-00AA00688B10}"description="ListView Sort Property Page Object"tlbid="{6B7E6392-850A-101B-AFC0-4210102A8DA7}" />
<comClass clsid="{5ACBB957-5C57-11CF-8993-00AA00688B10}"description="ListView Images Property Page Object"tlbid="{6B7E6392-850A-101B-AFC0-4210102A8DA7}" />
<comClass clsid="{5ACBB958-5C57-11CF-8993-00AA00688B10}"description="ListView Columns Property Page Object"tlbid="{6B7E6392-850A-101B-AFC0-4210102A8DA7}" />
<comClass clsid="{6027C2D4-FB28-11CD-8820-08002B2F4F5A}"description="Slider Appearance Property Page Object"tlbid="{6B7E6392-850A-101B-AFC0-4210102A8DA7}" />
<comClass clsid="{612A8624-0FB3-11CE-8747-524153480004}"description="Microsoft Toolbar Control, version 5.0 (SP2)"progid="COMCTL.Toolbar.1"tlbid="{6B7E6392-850A-101B-AFC0-4210102A8DA7}" />
<comClass clsid="{612A8628-0FB3-11CE-8747-524153480004}"description="Toolbar General Property Page Object"tlbid="{6B7E6392-850A-101B-AFC0-4210102A8DA7}" />
<comClass clsid="{62823C20-41A3-11CE-9E8B-0020AF039CA3}"description="Button Property Page Object"tlbid="{6B7E6392-850A-101B-AFC0-4210102A8DA7}" />
<comClass clsid="{6B7E638F-850A-101B-AFC0-4210102A8DA7}"description="Microsoft StatusBar Control, version 5.0 (SP2)"progid="COMCTL.SBarCtrl.1"tlbid="{6B7E6392-850A-101B-AFC0-4210102A8DA7}" />
<comClass clsid="{6B7E6393-850A-101B-AFC0-4210102A8DA7}"description="StatusBar General Property Page Object"tlbid="{6B7E6392-850A-101B-AFC0-4210102A8DA7}" />
<comClass clsid="{6B7E63A3-850A-101B-AFC0-4210102A8DA7}"description="Panel Property Page Object"tlbid="{6B7E6392-850A-101B-AFC0-4210102A8DA7}" />
<comClass clsid="{9ED94440-E5E8-101B-B9B5-444553540000}"description="Microsoft TabStrip Control, version 5.0 (SP2)"progid="COMCTL.TabStrip.1"tlbid="{6B7E6392-850A-101B-AFC0-4210102A8DA7}" />
<comClass clsid="{9ED94444-E5E8-101B-B9B5-444553540000}"description="TabStrip General Property Page Object"tlbid="{6B7E6392-850A-101B-AFC0-4210102A8DA7}" />
<comClass clsid="{B66834C6-2E60-11CE-8748-524153480004}"description="Tab Property Page Object"tlbid="{6B7E6392-850A-101B-AFC0-4210102A8DA7}" />
</file>
</assembly>