article de presse - Cap Data Consulting
article de presse - Cap Data Consulting
article de presse - Cap Data Consulting
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
P ratique<br />
Écrire une application d'installation<br />
sous Windows<br />
Le mois <strong>de</strong>rnier, nous avons étudié les fichiers .INF. À partir <strong>de</strong> ces connaissances, nous allons<br />
étudier l'écriture d'un programme d'installation.<br />
Les possibilités pour effectuer une installation sous Windows sont<br />
nombreuses. À la base, nous trouvons le fichier .INF qui est un<br />
simple fichier texte. Le mois <strong>de</strong>rnier, nous avons examiné l'organisation<br />
et le contenu d'un tel fichier. Lorsque quelque chose est installé<br />
via un fichier .INF, Windows procè<strong>de</strong> avec un jeu d'APIs dites API<br />
Setup. Ce jeu d'APIs va au-<strong>de</strong>là du simple traitement d'un fichier .INF. Il<br />
donne la possibilité d'écrire <strong>de</strong>s applications d'installation, les fameux<br />
setup.exe, et, bien entendu, les applications réciproques pour procé<strong>de</strong>r<br />
aux désinstallations. Le troisième moyen d'installation est l'archive .MSI<br />
qui est traitée par l'Installateur Windows. Nous réservons les MSI pour<br />
un <strong>article</strong> à venir et nous nous concentrons sur l'écriture d'une application<br />
type setup.exe.<br />
1<br />
Notre but et les outils<br />
Sur le Cd-Rom accompagnant le magazine, vous trouverez 4 programmes<br />
d'exemple. Le premier (Rudimentaire) est une application qui <strong>de</strong>man<strong>de</strong> à<br />
Windows <strong>de</strong> traiter le fichier .INF qui l'accompagne. Le second (Simple)<br />
réalise une installation en se basant sur le contenu du fichier .INF. qui l'accompagne.<br />
Le troisième (Complet) est une application autonome, c'est-àdire<br />
qui ne nécessite pas <strong>de</strong> fichier .INF du tout. Enfin, le <strong>de</strong>rnier exemple<br />
(Uninstall) est le réciproque <strong>de</strong> Complet et réalise la désinstallation <strong>de</strong><br />
l'application installée par ce <strong>de</strong>rnier. Tous les exemples sont <strong>de</strong>s applications<br />
console écrites en C++. L'habillage <strong>de</strong>s exemples par <strong>de</strong>s fenêtres<br />
ne pose pas problème en soi et nous ne nous y intéressons pas. Les<br />
exemples ont été écrits avec Visual C++ 6.0. N'importe quel autre compilateur<br />
C++ peut être utilisé pour compiler le co<strong>de</strong>. Au pire, <strong>de</strong>vrez-vous<br />
vous procurer les fichiers setupapi.h et setupapi.lib <strong>de</strong> la Microsoft<br />
Windows SDK (téléchargement gratuit). Le lecteur notera que les projets<br />
sont configurés afin que les exécutables soient déposés à la racine <strong>de</strong><br />
chaque projet et non dans les sous-répertoires 'Debug' ou 'Release'.<br />
L'application à installer se trouve au même endroit. Nous avons procédé<br />
ainsi, car Visual Studio passe le répertoire racine du projet comme répertoire<br />
<strong>de</strong> travail <strong>de</strong> l'application qu'il lance. Nous allégeons ainsi le co<strong>de</strong><br />
et nous n'avons pas à nous préoccuper <strong>de</strong> savoir si nous travaillons en<br />
configuration 'Debug' ou 'Release', tout en pouvant tester <strong>de</strong>puis Visual<br />
Studio. L'application installée par les exemples est exactement la même<br />
que celle <strong>de</strong> l'<strong>article</strong> du mois <strong>de</strong>rnier. Nous suggérons au lecteur d'en<br />
prendre connaissance, afin <strong>de</strong> profiter au mieux du présent <strong>article</strong>.<br />
2<br />
Pour se faire la main<br />
Depuis le mois <strong>de</strong>rnier, nous savons qu'il est possible <strong>de</strong> définir un processus<br />
d'installation complet à partir d'un seul fichier .INF. Toutefois,<br />
Programmez n°85 73 avril 2006<br />
sous Windows, l'utilisateur s'attend à cliquer sur un fichier setup.exe<br />
plutôt que <strong>de</strong> sélectionner 'Installer' <strong>de</strong>puis le menu contextuel d'un<br />
fichier .INF. En fait, les applications installées uniquement à partir d'un<br />
fichier .INF sont essentiellement <strong>de</strong>s pilotes <strong>de</strong> périphériques. Notre<br />
premier exemple est donc un exécutable qui fait exactement ce que fait<br />
Windows lors <strong>de</strong> l'installation d'un fichier .INF. Il invoque la fonction<br />
InstallHinfSection <strong>de</strong> la librairie setupapi.dll. Nous savons, <strong>de</strong>puis le<br />
mois <strong>de</strong>rnier, que cette fonction sert à désinstaller une application.<br />
Mais si l'on passe la section [DefautInstall] elle procè<strong>de</strong> à l'installation<br />
tout aussi bien. Cependant, aussi simple que ce procédé puisse être,<br />
il y a un petit piège. Classiquement (cf. l'<strong>article</strong> du mois <strong>de</strong>rnier)<br />
InstallHinfSection est invoqué via l'utilitaire Windows rundll32.exe.<br />
Ce <strong>de</strong>rnier s'occupe <strong>de</strong> la question <strong>de</strong> savoir si le système s'attend à<br />
recevoir une chaîne <strong>de</strong> comman<strong>de</strong> en ANSI ou en Unico<strong>de</strong>. Lorsqu'on<br />
invoque la fonction par programmation, nous <strong>de</strong>vons résoudre cette<br />
question, ce qui implique <strong>de</strong> s'enquérir <strong>de</strong> l'i<strong>de</strong>ntité du système hôte.<br />
Bien entendu, les prototypes ANSI et Unico<strong>de</strong> cohabitent dans setupapi.dll,<br />
mais il se trouve que sous mon Windows XP, la fonction ANSI ne<br />
fait strictement rien. Nous <strong>de</strong>vons donc traduire la comman<strong>de</strong> en<br />
Unico<strong>de</strong> et invoquer explicitement InstallHinfsectionW. L'exemple ci-<strong>de</strong>ssous<br />
est donc valable pour Windows XP.<br />
// Exemple rudimentaire<br />
#inclu<strong>de</strong> <br />
#inclu<strong>de</strong> <br />
#inclu<strong>de</strong> <br />
#inclu<strong>de</strong> <br />
using namespace std;<br />
string GetCurDir()<br />
{<br />
TCHAR buffer[MAX_PATH+1];<br />
::GetCurrentDirectory(sizeof(buffer), buffer);<br />
return buffer;<br />
}<br />
int main(int argc, char* argv[])<br />
{<br />
WCHAR buffer[MAX_PATH+1];<br />
string filename;<br />
Niveau<br />
C++ facile avancé expert<br />
Sur le<br />
CD ROM