1. Créer des paquets WAPT¶
1.1. Créer son environnement de développement de paquets WAPT¶
1.1.1. Pré-requis¶
Attention
Il est impératif d’être en possession d’un compte Administrateur Local de la machine pour cette opération.
Nous vous conseillons de créer / éditer vos paquets dans un environnement maîtrisé, sain et jetable.
L’utilisation d’une machine virtuelle autonome (type Virtualbox ou équivalent) est vivement recommandée.
Importer le paquet tis-waptdev dans votre dépôt local et l’installer sur votre machine de développement.
1.1.2. Préconisations concernant l’environnement de test¶
La méthode préconisée pour tester correctement vos paquets est d’utiliser un échantillon de machines représentatif de votre parc. Donc plus votre parc est hétérogène, plus votre échantillon devra être large.
Cette démarche vise à confronter le paquet WAPT à une multitude de plateformes et environnements afin qu’il devienne le plus abouti possible en régime de test, avant d’être basculé en production.
Pour expliquer le fonctionnement des maturités de paquets, vous pouvez vous référer à cette vidéo.
1.1.3. Démarche de test¶
1.1.3.1. Systèmes d’exploitation et architectures¶
Desktop Operating Systems
Windows XP |
Windows 7 |
Windows 10 |
Windows 10 |
Redhat and derivatives |
Debian and derivatives |
Server Operating Systems
Windows Serveur 2008 R2 |
Windows Serveur 2012 |
Windows Serveur 2008 R2 |
Architectures
x86 |
x64 |
Deployment Environments
Machine physique et virtuelle |
Des ordinateurs portables |
On testera si possible les versions RC / Beta des OS si elles sont disponibles (exemple : Windows 10 Creators Update).
1.1.3.2. L’état des mises à jour Windows¶
Un poste Microsoft Windows sans aucune mise à jour Windows Update : l’objectif est de détecter les mises à jour indispensables au bon fonctionnement du logiciel et adapter le paquet en conséquence ;
Un poste Microsoft Windows à jour avec les toutes dernières MàJ Windows Update : l’objectif est de détecter les mise à jour en conflit avec le logiciel et d’adapter le paquet en conséquence ;
1.1.3.3. État des installations des logiciels¶
Un poste avec peu de logiciels déjà installés : l’objectif est de détecter une dépendance possible à Java ou autre framework applicatif ;
Les postes avec beaucoup de logiciels déjà installés : l’objectif est de détecter un conflit avec une application existante ;
Installer les anciennes versions du logiciel : il est possible que l’installeur ne supporte pas l’écrasement d’une installation précédente, dans ce cas il faudra prévoir la désinstallation des anciennes versions avant d’installer la nouvelle version ;
1.2. Les principes de création d’un paquet WAPT à partir d’un modèle depuis la console¶
Attention
Pour créer des paquets à partir de la console, il faut d’abord avoir installé l’environnement de développement WAPT tis-pyscripter3 ou tis-vscode. Il n’est PAS recommandé d’utiliser tis-pyscripter4.
Nous vous recommandons de télécharger le paquet tis-waptdev et de l’installer sur votre ordinateur où vous créerez les paquets WAPT.
Si vous ne savez plus comment télécharger un paquet depuis le store Tranquil IT, veuillez consulter comment télécharger un paquet dans votre dépôt privé.
Si vous ne savez plus comment installer un paquet, veuillez consulter comment installer un paquet sur un hôte.
1.2.1. Créer un paquet WAPT depuis la Console WAPT¶
Nous utilisons l’installation MSI de 7-zip téléchargée depuis le site officiel de 7-zip.
Créer le modèle de paquet depuis l’installeur.
Dans la Console WAPT, cliquer sur Outils –> Générer un modèle de paquet :
Les principes de création d’un paquet WAPT à partir d’un modèle depuis la console¶
Sélectionnez le fichier d’installation MSI téléchargé (Windows installer(.msi/.msix/.exe)) et remplissez les champs obligatoires. Vérifiez que le nom du paquet ne contient pas de numéro de version.
Boîte de dialogue demandant des informations lors de la création du packaging WAPT dans la Console WAPT¶
Deux solutions sont proposées :
Cliquez sur Editer manuellement (recommandé) pour vérifier le paquet WAPT et l’adapter aux besoins spécifiques de votre organisation.
Cliquer sur Créer et Téléverser pour lancer la création et le chargement direct du paquet sur le Serveur WAPT (non recommandé).
Avertissement
Le bouton Build and upload envoi directement le paquet dans le dépôt privé sans tester l’installation.
Cette méthode fonctionne assez bien avec les MSI car leur installation est standard.
Cependant la deuxième méthode qui consiste à tester localement le paquet d’abord puis à l’uploader est la méthode recommandée.
Note
Si vous préférez utiliser la ligne de commande, vous pouvez utiliser cette méthode.
1.2.2. Personnaliser le paquet avant de le téléverser dans votre dépôt¶
La méthode conseillée avant l”upload d’un paquet est de personnaliser son comportement en l’éditant avec PyScripter.
Lors de la création du modèle de paquet, cliquez sur Editer manuellement.

« Modifier manuellement » dans la boîte de dialogue¶
Fenêtre de message indiquant dans la Console WAPT que le packaging WAPT a été téléchargé dans le dépôt WAPT.

Message windows for information¶
L’IDE PyScripter se lance et permet d’éditer les fichiers du paquet.

PyScripter - Personnalisation du paquet avec PyScripter¶
1.2.3. Présentation de PyScripter¶
1.2.3.1. L’explorateur de projets PyScripter¶
C’est la vue initiale de l’explorateur Pyscripter lorsque vous ouvrez un paquet WAPT.

PyScripter - Navigation d’un projet dans l’explorateur de fichiers de PyScrypter¶
L’explorateur de projets PyScripter liste les différents fichiers dont vous pouvez avoir besoin, notamment le fichier control
et le fichier setup.py
.
1.2.3.2. Zone d’édition¶
Le panneau d’édition en orange dans l’image ci-dessus.
Le panneau d’édition dans PyScripter permet d’éditer le fichier setup.py
et le fichier control
.
1.2.3.3. Run Configurations¶
Dans l’image ci-dessus, la boîte la box verte affiche les configurations préinstallées.
Les options de Run dans l’explorateur de projets de PyScripter vont vous permettre de lancer des actions de votre paquet en cours d’édition.
Ses fonctions sont expliqués dans le tableau ci-dessous.
Fonction |
Description |
---|---|
install |
Permet d’installer le paquet sur le système de notre machine de test. |
remove |
Utilisé pour désinstaller le paquet du système de la machine de test. |
uninstall |
Enables you to run a custom uninstall of the test machine package. |
session-setup |
Permet d’installer le paquet via le contexte utilisateur de la machine de test. |
audit |
Permet d’auditer le paquet. |
update-package-source |
Automatiser la mise à jour d’un paquet logiciel. |
1.2.3.4. Console Python¶

PyScripter - console python de PyScripter¶
C’est la console python visible dans PyScripter, elle va vous permettre d’afficher la sortie python lorsque vous exécuterez des commandes run.
Vous pouvez également l’utiliser pour tester / déboguer des portions de votre script setup.py
.
Pour en savoir plus sur la composition d’un paquet WAPT, consultez la documentation sur la structure détaillée d’un paquet.
1.2.3.5. Tester localement l’installation du paquet WAPT¶
Vous pouvez ensuite tester le lancement d’une installation sur votre station de développement.

La Console PyScripter vous permet de vérifier si l’installation s’est bien déroulée.
1.2.3.6. Tester localement la désinstallation du paquet WAPT¶
Vous pouvez ensuite tester le lancement d’une installation sur votre station de développement.

La Console PyScripter vous permet de vérifier si l’installation s’est bien déroulée.
1.2.4. Explorer les fichiers du paquet depuis la Console WAPT¶
Pour explorer tous les fichiers d’un paquet WAPT via la Console WAPT, vous devez activer l’option Afficher les fonctionnalités de développeur. Pour ce faire :
Aller dans le menu Affichage de la Console WAPT.
Sélectionner Préférences d’affichage et cocher Afficher les fonctionnalités de développeur.
Comment explorer les fichiers du paquet ? Naviguez dans la section WAPT Packages, sélectionnez votre paquet et faites un clic droit sur Edit_package
Une fois activé, vous pouvez accéder à l’explorateur de fichiers du paquet.

Console WAPT mode développeur¶
1.3. Créer vos premiers paquets WAPT¶
1.3.1. Packager des .msi (exemple)¶
Pour cet exemple, nous prendrons tightvnc.
Vous pouvez le télécharger ici.
Maintenant, vous pouvez générer votre modèle de paquet, veuillez vous référer à la documentation pour la création de paquets à partir de la Console WAPT.
Editer le fichier control
(architecture
, impacted_process
, target_os
, description
, maintainer
…), veuillez vous référer à la structure du fichier documentation du fichier control.
Votre pyscripter s’ouvre, allez dans votre setup.py
:
# -*- coding: utf-8 -*-
from setuphelpers import *
uninstallkey = []
def install():
print('installing tis-tightvnc')
install_msi_if_needed('tightvnc-2.8.5-setup-64bit.msi')
La fonction testera également si une version du logiciel est déjà installée sur la machine avec la clé de désinstallation.
Si présence il y a, l’installation sera enclenchée uniquement si la version actuellement installée est plus ancienne.
Après installation, la fonction testera finalement la présence de la clé de désinstallation et sa version pour vérifier que tout s’est bien passé.
Options (Option par défaut) |
Description |
---|---|
|
Définit la version minimale au dessus de laquelle le logiciel se mettra à jour. |
|
Liste des programmes à tuer avant de lancer l’installation. |
|
Définit les codes de retour autres que 0 ou 3010 acceptés en retour par la fonction. |
|
Définit la durée d’attente maximale d’installation (en secondes). |
|
Définit les propriétés supplémentaires à passer en argument au MSI pour l’installation. |
|
Définit la valeur passée en paramètre pour le contrôle de version au lieu de celle retournée par la fonction installed_softwares. |
|
Supprime automatiquement une ancienne version d’un logiciel dont la clé de désinstallation est identique. |
|
Force l’installation du logiciel même si une clé de désinstallation avec une version identique est trouvée. |
La fonction install_msi_if_needed récupère la clé de désinstallation depuis le MSI, il n’est pas nécessaire de l’écrire dans le fichier setup.py
.
Vous n’avez pas non plus à remplir le champ killbefore
si la valeur indiquée dans le champ impacted_process
du fichier control
est correcte.
Note
Le setup.py
aurait pu ressembler à cela, mais la méthode est moins élégante car elle fait moins de vérifications.
# -*- coding: utf-8 -*- from setuphelpers import * uninstallkey = ["{8B9896FC-B4F2-44CD-8B6E-78A0B1851B59}"] def install(): print('installing tis-tightvnc') run('msiexec /norestart /q /i "tightvnc-2.8.5-setup-64bit.msi"')
Lancez l’installation et voyez ce qui se passe lorsque le logiciel est déjà installé.
wapt-get -ldebug install C:\waptdev\tis-tightvnc-wapt
Installing WAPT file C:\waptdev\tis-tightvnc-wapt
MSI tightvnc-2.8.5-gpl-setup-64bit.msi already installed. Skipping msiexec
Results:
=== install packages ===
C:\waptdev\tis-tightvnc-wapt | tis-tightvnc (2.8.5.0-1)
1.3.1.1. Ajouter des propriétés supplémentaires en argument¶
Pour ajouter des propriétés supplémentaires on va les stocker dans un élément dict.
# -*- coding: utf-8 -*-
from setuphelpers import *
uninstallkey = []
properties = {
'SERVER_REGISTER_AS_SERVICE': 0,
'SERVER_ADD_FIREWALL_EXCEPTION': 0,
'ADDLOCAL': 'Server,Viewer'
}
def install():
print(u'Installation en cours de TightVNC')
install_msi_if_needed('tightvnc-2.8.5-setup-64bit.msi', properties = properties )
Note
Le setup.py
aurait pu ressembler à cela, mais la méthode est moins élégante car elle fait moins de vérifications.
# -*- coding: utf-8 -*- from setuphelpers import * uninstallkey = ["{8B9896FC-B4F2-44CD-8B6E-78A0B1851B59}"] def install(): print('installing tis-tightvnc') run('msiexec /norestart /q /i "tightvnc-2.8.5-setup-64bit.msi" SERVER_REGISTER_AS_SERVICE=0 SERVER_ADD_FIREWALL_EXCEPTION=0')
1.3.1.2. Vidéo de démonstration¶
1.3.2. Packager des .exe (exemple)¶
Télécharger l’installateur .exe à partir d’une source fiable.
Télécharger l’installateur au format exe Firefox ESR x64 sur https://download.mozilla.org/?product=firefox-esr-latest-ssl&os=win64.
Rechercher la documentation associée pour les flags silencieux :
Sur le site de la Fondation Mozilla .
Autres méthodes pour récupérer le flag silencieux :
Dépôt de paquets WPKG ;
Recherche Internet avec le terme Firefox silent install.
Puis générer votre modèle de paquet, veuillez vous référer à la documentation pour la création de paquets à partir de la Console WAPT. PyScripter se charge et ouvre le projet de paquet .exe.
PyScripter - Ouverture du paquet WAPT de FirefoxESR¶
Editer le fichier
control
(architecture
,impacted_process
,target_os
,description
,maintainer
…), veuillez vous référer à la structure du fichier documentation du fichier control.Vérifier le contenu du fichier
control
. Mozilla Firefox-ESR ne répond pas aux standards et retourne un numéro de version erroné (il s’agit du numéro de version du logiciel qui créé l’installeur).Fichier
control
d’origine.package : tis-firefox-esr version : 4.42.0.0-0 architecture : all section : base priority : optional maintainer : user description : automatic package for firefox setup 52.6.0esr impacted_process :
Fichier
control
modifié.package : tis-firefox-esr version : 52.6.0-1 architecture : all section : base priority : optional maintainer : Tranquil-IT Systems description : Mozilla Firefox 52.6.0 ESR impacted_process : firefox.exe
Il est à noter qu’une sous-version -1 a été ajoutée au numéro de version du logiciel ; il s’agit de la version de packaging du paquet WAPT.
Il permet au développeur de paquets de publier plusieurs versions de paquets WAPT d’un même logiciel, ce qui est très utile pour un développement très rapide et itératif.
Utiliser install_exe_if_needed
La fonction est sensiblement la même que celle utilisée pour les installeurs .msi, avec quelques différences :
La fonction nécessite l’ajout des flags silencieux en paramètre.
La fonction nécessite l’ajout de la clé de désinstallation en paramètre.
# -*- coding: utf-8 -*-
from setuphelpers import *
uninstallkey = []
def install():
print('installing tis-firefox-esr')
install_exe_if_needed("Firefox Setup 45.5.0esr.exe",silentflags="-ms",key='',min_version="4.42.0.0")
Options (Option par défaut) |
Description |
---|---|
|
Paramètres silencieux à passer en argument à l’installeur. |
|
Clé de désinstallation du programme. |
|
Définit la version minimale au dessus de laquelle le logiciel se mettra à jour. |
|
Liste des programmes à tuer avant de lancer l’installation. |
|
Définit les codes de retour autres que 0 ou 3010 acceptés en retour par la fonction. |
|
Définit la durée d’attente maximale d’installation (en secondes). |
|
Définit la valeur passée en paramètre pour le contrôle de version au lieu de celle retournée par la fonction installed_softwares. Exemple https://forum.tranquil.it/viewtopic.php?t=1337. |
|
Supprime automatiquement une ancienne version d’un logiciel dont la clé de désinstallation est identique. |
|
Force l’installation du logiciel même si une clé de désinstallation avec une version identique est trouvée. |
Le paquet aura alors ce comportement :
Le logiciel Firefox s’installera uniquement si le logiciel n’est pas installé et si la version est strictement inférieure à 45.5.0, sauf si l’option
--force
est indiquée lors de l’installation du paquet.A l’installation, les processus firefox.exe en cours d’exécution seront tués (avec la valeur indiquée dans
impacted_process
du fichiercontrol
).La fonction ajoutera elle-même la clé de désinstallation, donc laisser l’argument clé de désinstallation vide.
A la fin de l’installation, la fonction ira vérifier si la clé de désinstallation est bien présente sur le poste et si la version est bien égale ou supérieure à 45.5.0, si ce n’est pas le cas, elle basculera le paquet en ERREUR.
1.3.2.1. Trouver la clé de désinstallation¶
Contrairement aux fichiers .msi, la clé pour désinstaller un .exe n’est pas dans les propriétés du fichier.
Vous devez donc d’abord installer le logiciel pour connaître la clé de désinstallation.
Vous devez donc démarrer une fois l’installation à partir de pyscripter avec le run configuration et ensuite install.

Une fois le logiciel installé, allez à la Console WAPT, puis trouvez votre machine de développement.
Dans l’onglet inventaire des logiciels, trouvez votre logiciel et copiez la valeur indiquée dans la colonne clé de désinstallation.

Récupérer une clé de désinstallation depuis la Console WAPT¶
Vous devez également vérifier la valeur de la version avec la valeur indiquée dans min_version
dans votre setup.py
.
Modifier votre fichier setup.py
avec les nouveaux paramètres :
# -*- coding: utf-8 -*-
from setuphelpers import *
uninstallkey = []
def install():
print('installing tis-firefox-esr')
install_exe_if_needed("Firefox Setup 45.5.0esr.exe",silentflags="-ms",key='Mozilla Firefox 45.5.0 ESR (x64 fr)',min_version="45.5.0")
Pour tester que votre clé fonctionne correctement, vous DEVEZ relancer une installation dans pyscripter.

WAPT ne tentera pas d’installer le logiciel car il est déjà présent, le message suivant devrait donc s’afficher :
>>>
*** Remote Interpreter Reinitialized ***
Command Line : install "c:\waptdev\tis-firefox-esr_x64_PROD_fr-wapt\WAPT\.."
Using config file: C:\Program Files (x86)\wapt\wapt-get.ini
Installing WAPT files c:\waptdev\tis-firefox-esr_x64_PROD_fr-wapt
Exe setup Firefox_Setup_78.7.1esr.exe already installed. Skipping
Results:
=== install packages ===
c:\waptdev\tis-firefox-esr_x64_PROD_fr-wapt | tis-firefox-esr (78.7.1-102)
Vous pouvez maintenant tester la désinstallation :

Vous pouvez maintenant construire et envoyer votre paquet, veuillez vous référer à la documentation pour construire et envoyer des paquets depuis la Console WAPT.
Note
Si vous laissez la clé de désinstallation vide, la désinstallation de votre paquet ne fonctionnera pas.
1.3.2.2. Cas particulier d’un dé-installeur non-silencieux¶
Dans certains cas particuliers, un paquet utilisant install_exe_if_needed remplit la clé de désinstallation, mais la clé de désinstallation pointe vers un désinstalleur non silencieux.
Il nous faut contourner le problème en utilisant une fonction qui va supprimer la clé de désinstallation à la fin de l’installation.
:emphasize-lines: 13
# -*- coding: utf-8 -*-
from setuphelpers import *
uninstallkey = []
def install():
install_exe_if_needed("setup.exe",
silentflags="/s",
key='{D9E87643-0005-447E-9111-78697A9C1595}',
min_version="14.0")
uninstallkey.remove('{D9E87643-0005-447E-9111-78697A9C1595')
def uninstall():
run(r'"C:\Program Files\Kutl\uninstall.exe" /supersilent')
Indication
La fonction de désinstallation peut également être utilisée pour exécuter du code en plus de la désinstallation de logiciels, ex : supprimer un dossier, supprimer un raccourci …
1.3.2.3. Vidéo de démonstration¶
1.3.3. Packager des paquets linux simples¶
1.3.4. Construire le paquet et l’envoyer au Serveur WAPT¶
Une fois que le paquet est prêt, le construire et l’envoyer au Serveur WAPT, dans la Console WAPT.

Sélectionner le paquet dans le dossier
c:\waptdev
.

Fenêtre du navigateur permettant de sélectionner le paquet WAPT à importer dans le dépôt privé¶
Confirmer le paquet sélectionné.

Boîte de dialogue de la Console WAPT pour confirmer l’importation d’un paquet WAPT dans le dépôt privé¶
Vous venez de charger votre premier paquet wapt.
Avertissement
Une fois que votre paquet est téléversé, rafraîchissez la liste des paquets en utilisant le bouton Actualiser les paquets disponibles ou en appuyant sur la touche F5 de votre clavier.
1.3.4.1. Travailler avec des codes de retour non standard¶
Les codes de retour sont utilisés pour indiquer si un logiciel a été correctement installé.
Avec Windows, le code standard de retour pour une installation réussie est [0].
Si vous savez que vos paquets WAPT s’installent correctement, mais que vous obtenez quand même un code de retour différent de [0], alors vous pouvez explicitement dire à WAPT d’ignorer le code d’erreur en utilisant le paramètre accept_returncodes
.
Vous pouvez découvrir comment utiliser le paramètre accept_returncodes
en explorant le code de ce paquet.
# -*- coding: utf-8 -*-
from setuphelpers import *
import re
uninstallkey = []
def is_kb_installed(hotfixid):
installed_update = installed_windows_updates()
if [kb for kb in installed_update if kb['HotFixID' ].upper() == hotfixid.upper()]:
return True
return False
def waiting_for_reboot():
# Query WUAU from the registry
if reg_key_exists(HKEY_LOCAL_MACHINE,r"SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired") or \
reg_key_exists(HKEY_LOCAL_MACHINE,r"SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending") or \
reg_key_exists(HKEY_LOCAL_MACHINE,r'SOFTWARE\Microsoft\Updates\UpdateExeVolatile'):
return True
return False
def install():
kb_files = [
'windows10.0-kb4522355-x64_af588d16a8fbb572b70c3b3bb34edee42d6a460b.msu',
]
with EnsureWUAUServRunning():
for kb_file in kb_files:
kb_guess = re.findall(r'^.*-(KB.*)-',kb_file)
if not kb_guess or not is_kb_installed(kb_guess[0]):
print('Installing {}'.format(kb_file))
run('wusa.exe "{}" /quiet /norestart'.format(kb_file),accept_returncodes=[0,3010,2359302,-2145124329],timeout=3600)
else:
print('{} already installed'.format(kb_file))
if waiting_for_reboot():
print('A reboot is needed!')
Indication
La liste complète des messages d’erreur de l’installeur Windows peut être consultée sur cette page <https://docs.microsoft.com/en-us/windows/win32/msi/windows-installer-error-messages>`_.