toujours dans mes tests de compatibilité du Framework .Net 1.1 avec Vista (version 64 bits, qui plus est), je suis passé aux tests de projets de type setup. Je sais que VS2003 n'est pas supporté sous Vista, mais il faut parfois s'assurer que certains scénarios continuent de fonctionner. Et en l'occurence, le msi produit par VS ne devrait pas avoir de dépendance particulière à l'OS. Sauf que si :(

 Je ne parle pas d'une condition triviale dans le projet setup qui testerait que l'os est un XP (version 5.1) au lieu de tester toute version supérieure ou égale à 5.1 pour embarquer les versions 6 et plus dans la foulée. Pour cela, si on a encore le projet, on peut changer le test. Et dans le cas contraire, on peut essayer de jouer avec les modes de compatiblités. Mais dans mon cas de figure, rien de tout cela : lors de l'installation de mon service via le msi généré, je me suis retrouvé avec un échec systématique et un erreur 11708 dans le journal d'événement sans information exploitable. Et l'indice de fiabilité de mon poste dégringolant à toute vitesse :(

En fouillant un peu, je suis tombé sur l'article suivant : http://arnshea.spaces.live.com/blog/cns!32B8884142441255!220.entry

Il semble en fait que dans le msi généré par VS 2003, un flag d'impersonification soit mal positionné au niveau des actions personalisées, ce qui passe sans problème sous XP ou 2003, mais se fait toper par l'UAC sous Vista. A priori, ce problème concernairait aussi les msi généré par Visual Studio 2005 RTM. N'ayant plus que des versions SP1+Vista fix, je n'ai pas pu faire le test. Par contre, j'ai testé les configurations suivantes :

  1. Intégration du manifest dans l'exécutable puis génération du MSI avec VS 2003. Contrairement à ce que laisse entendre l'article, il y a moyen d'automatiser l'opération (cf ThemeMe sur http://www.msjogren.net/dotnet/eng/tools/). Mais pas moyen de passer la protection DEP sous Vista 64 bits. Je suppose donc que cela doit marcher avec un Vista 32 bits mais comme j'ai besoin de toutes les configurations, cela ne me convient pas.
  2. Génération du msi avec un VS 2005+SP1+Vista fix (j'ai un doute sur l'utilité réelle de ce fix pour ce problème spécifique, mais passons). Victoire (de courte durée), le service s'installe bien sous Vista 64, les custom actions sont lancées (elles démarrent le service), et la désinstallation marche bien. Oui mais sur un XP 32 bits sans le Framework 2.0, une agaçante popup apparaît au lancement du msi :(
  3. Idem que précédement mais en modifiant la condition pour demander une v1.1 du Framework (avec ou sans support d'une version ultérieure). Cela marche bien sur mon XP, mais plante sur mon Vista. Grrr....

Bon, je suppose que dans le dernier cas, en jouant avec Orca, on doit pouvoir faire sauter la dépendance, mais comme ce n'est pas automatisable, cela ne m'interesse pas. Autre solution, produire deux setup, un pour chaque plateforme. Les outils de télédistribution savent en général cibler des packages en fonction de variables comme l'OS, ce serait jouable. Mais cela ne me plaisait pas non plus.

 Dernière solution, utiliser Wix. Cela ne m'enchantait pas trop car cela me semblait un peu "lourd". Mais comme on va l'intégrer à la prochaine version de VS, ce pouvait être l'occasion d'y jeter enfin un coup d'oeil. Et c'était en fait un bel à priori :

  1. Je suis allé sur le site http://wix.sourceforge.net/index.html récupérer le package (la V2).
  2. Je suis parti de l'exemple SampleFirst que j'ai testé tel quel
  3. Puis je l'ai modifié pour référencer mon service, être par défaut en français (valeur 1036 pour les tag Langages) et cibler la plateforme x86 (tag Platforms='Intel' sur le noeud package).
  4. Et voila :)

Pour référencer le service, j'ai ajouté le composant suivant :

<Component Id='MainService' Guid='04C7E6DD-A2C6-40B6-9069-083DC4A4BD2F'>

<File Id='service1.exe' Name='service1.exe' LongName='service1.exe' src='service1.exe'

DiskId='1' />

<ServiceInstall Id='service1.exe' Name='Service1' DisplayName='Service1'

Type='ownProcess' Interactive='no' Start='auto' Vital='yes' ErrorControl='normal' />

<ServiceControl Id='service1.exe' Name='Service1' Start='install' Stop='both' Remove='uninstall'

Wait='yes' />

<Registry Id='Service1InstallDir' Root='HKLM' Key='Software\Company\Service1'

Name='InstallDir' Action='write' Type='string' Value='[INSTALLDIR]' />

</Component>

 avec en bonus pour mon test l'écriture d'une clé de registre. Au final :

  • Cela fonctionne bien sous XP 32 bits et Vista 64 bits.
  • Plus de message d'alerte sur une dépendance à une version du Framework.
  • Les custom actions ne servent plus à rien, le démarrage ou l'arrêt du service sont pris en charge par le msi généré par Wix.
  • Et donc, lors d'une désinstallation, plus de message d'alerte indiquant que certaines applications tournent encore et peuvent nécessiter un reboot.
  • Les binaires et clés de registre vont bien au bon endroit (dans HKLM\Software ou HKLM\Software\Wow6432Node pour les clés de registres par exemple).
  • En suivant le tutoriel et les exemples fournit sur le site de Wix, on a une solution qui marche en à peu près une heure. Ok, pour des tests complémentaires, des interfaces riches et ce genre de chose, c'est peut être plus couteux. Mais cela, ce ser pour une autre fois :)

 Bon, le besoin de déployer du .Net 1.1 sur plusieurs plate-formes ne doit pas être très courant mais si cela peut éviter quelques galères et heures perdues inutilement...