307 lines
12 KiB
Markdown
307 lines
12 KiB
Markdown
# Build Windows One-Click
|
|
|
|
Le packaging Windows standard du projet repose sur :
|
|
|
|
- `build_windows_oneclick.bat`
|
|
- `build_windows_gui_v6_oneclick.bat`
|
|
- `build_windows_installer_oneclick.bat`
|
|
- `scripts/build_windows_oneclick.ps1`
|
|
- `anonymisation_onefile.spec`
|
|
- `anonymisation_gui_v6_onefile.spec`
|
|
- `installer/Anonymisation.iss`
|
|
|
|
## Usage
|
|
|
|
Sur la machine Windows de build :
|
|
|
|
1. ouvrir le dossier du projet
|
|
2. double-cliquer sur `build_windows_oneclick.bat`
|
|
|
|
Le script :
|
|
|
|
- crée un venv de build local `.venv_build_win`
|
|
- installe les dépendances nécessaires au packaging
|
|
- génère `build_info.py`
|
|
- lance `PyInstaller` avec `anonymisation_onefile.spec`
|
|
- vérifie la présence de l'exécutable final
|
|
- prépare un dossier de livraison et une archive ZIP
|
|
- crée `release\Anonymisation-Setup.exe` si Inno Setup 6 est installé
|
|
|
|
## Sorties attendues
|
|
|
|
- exécutable : `dist\Anonymisation.exe`
|
|
- dossier de livraison : `release\Anonymisation-Windows\`
|
|
- archive : `release\Anonymisation-Windows.zip`
|
|
- installateur : `release\Anonymisation-Setup.exe`
|
|
- hash : `release\Anonymisation.exe.sha256.txt`
|
|
|
|
## Installateur Windows
|
|
|
|
L'installateur est généré avec Inno Setup 6. Il fournit :
|
|
|
|
- choix du dossier d'installation
|
|
- installation utilisateur par défaut sans droits administrateur
|
|
- raccourci menu Démarrer
|
|
- option d'icône sur le bureau
|
|
- désinstallation Windows standard
|
|
|
|
Si Inno Setup n'est pas présent sur la machine de build, le script conserve le
|
|
build EXE/ZIP et affiche un avertissement. Installer Inno Setup 6 depuis le site
|
|
officiel puis relancer le build.
|
|
|
|
Installation automatisée de la dépendance de build Inno Setup :
|
|
|
|
```powershell
|
|
powershell -ExecutionPolicy Bypass -File .\scripts\install_inno_setup_build_dep.ps1
|
|
```
|
|
|
|
Recompiler uniquement l'installateur à partir de `release\Anonymisation-Windows\Anonymisation.exe` :
|
|
|
|
```powershell
|
|
powershell -ExecutionPolicy Bypass -File .\scripts\build_windows_installer_only.ps1
|
|
```
|
|
|
|
Pour ne générer que l'exécutable et le ZIP :
|
|
|
|
```powershell
|
|
powershell -ExecutionPolicy Bypass -File .\scripts\build_windows_oneclick.ps1 -SkipInstaller
|
|
```
|
|
|
|
## GUI V6
|
|
|
|
La GUI V6 utilise le même pipeline PyInstaller + Inno Setup, mais avec l'entrée
|
|
`Pseudonymisation_Gui_V6.py` et la spec dédiée `anonymisation_gui_v6_onefile.spec`.
|
|
Le comportement historique reste le défaut du script one-click.
|
|
|
|
Sur la machine Windows de build :
|
|
|
|
```powershell
|
|
powershell -ExecutionPolicy Bypass -File .\scripts\build_windows_oneclick.ps1 -GuiV6
|
|
```
|
|
|
|
ou double-cliquer sur :
|
|
|
|
```text
|
|
build_windows_gui_v6_oneclick.bat
|
|
```
|
|
|
|
Sorties attendues identiques :
|
|
|
|
- `dist\Anonymisation.exe` : exécutable GUI V6 ;
|
|
- `release\Anonymisation-Windows\Anonymisation.exe` : paquet local ;
|
|
- `release\Anonymisation-Windows.zip` : archive locale ;
|
|
- `release\Anonymisation-Setup.exe` : installateur destiné au portail après GO
|
|
diffusion ;
|
|
- `release\Anonymisation.exe.sha256.txt` : hash de l'exécutable.
|
|
|
|
## Build GUI V6 torch-free (Plan 3)
|
|
|
|
Depuis le Plan 3 (2026-07), le flavor `-GuiV6` :
|
|
|
|
1. **Purge torch/optimum du venv de build** (P0-3) : `optimum[onnxruntime]`
|
|
(requirements.txt) tire `torch>=1.11` en dépendance cœur ; la GUI V6 ne
|
|
l'utilise jamais (NER = onnxruntime brut, OCR = OnnxTR). Le script échoue
|
|
si `torch` reste importable après purge. La spec legacy V5
|
|
(`anonymisation_onefile.spec`) garde torch — ne pas builder V5 et V6 dans
|
|
le même venv sans réinstaller les requirements.
|
|
2. **Précache les poids OnnxTR** (P0-4) : `db_resnet50` + `crnn_vgg16_bn`
|
|
téléchargés explicitement avant PyInstaller (la spec raise s'ils manquent).
|
|
Le build ne dépend plus du cache résiduel de la machine.
|
|
3. **Injecte la version release** (P1-7) : `yyyy.MM.dd.HHmm` calculée une fois,
|
|
écrite dans `build_info.py` (BUILD_VERSION), `gui_v6/_build_version.py`
|
|
(affichage GUI + télémétrie) et l'installeur (`/DAppVersion`). En dev,
|
|
`gui_v6.__version__` retombe sur `6.0.0-dev`.
|
|
|
|
### Validation torch-free (à chaque build)
|
|
|
|
- Taille EXE mesurée et comparée au build précédent (~697 MB avec torch ;
|
|
attendu nettement inférieur — consigner la valeur).
|
|
- `Select-String -Path build\anonymisation_gui_v6_onefile\xref-*.html -Pattern "torch|optimum"`
|
|
→ 0 résultat (l'arbo PyInstaller fait foi, pas le diff de la spec).
|
|
- Smoke OCR sur PDF scanné (`ocr_used=True`) : les poids OnnxTR viennent de
|
|
`_MEIPASS/models/onnxtr/models`, aucun téléchargement runtime.
|
|
|
|
### Mise à jour en place (D8) — comportement de l'installeur
|
|
|
|
- L'installeur pose `AppMutex=AivanonymAnonymisationV6` (= `gui_v6/single_instance.py:APP_MUTEX_NAME`)
|
|
et `CloseApplications=yes` : Inno Setup envoie `WM_CLOSE` à l'app en cours et attend
|
|
sa fermeture avant de remplacer l'EXE.
|
|
- **Cas où l'app ne se ferme pas seule** : si l'application est gelée (ne répond plus au
|
|
`WM_CLOSE`), Inno Setup n'effectue **pas** de force-kill silencieux — il affiche un
|
|
**dialogue à l'utilisateur** (forcer la fermeture / annuler la MAJ). Il n'y a donc pas
|
|
d'échec silencieux, mais la MAJ requiert une action manuelle dans ce cas.
|
|
- Précondition : la GUI V6 n'a **pas** de réduction en zone de notification (tray). Si une
|
|
telle fonctionnalité était ajoutée, revoir D8 (un process en tray survivrait au `WM_CLOSE`).
|
|
|
|
## Important
|
|
|
|
- les utilisateurs finaux n'ont pas besoin d'installer Python
|
|
- le build doit être lancé depuis Windows
|
|
- le modèle ONNX embarqué requis doit exister localement dans :
|
|
`models\camembert-bio-deid\onnx\model.onnx`
|
|
- limitation MVP frozen : voir `docs/limitations-frozen-mvp.md` pour les moteurs
|
|
effectivement embarqués, notamment l'absence d'EDS-Pseudo dans le paquet MVP.
|
|
|
|
## CLI Windows (sans GUI) — fichier unique
|
|
|
|
En plus de la GUI, un exécutable **CLI de production** permet d'anonymiser un
|
|
fichier (ou un dossier) en ligne de commande, sans interface graphique.
|
|
|
|
- entrypoint : `scripts/anonymize_cli.py`
|
|
- spec PyInstaller : `anonymisation_cli_onefile.spec`
|
|
- exécutable produit : `dist\Anonymisation-CLI.exe` (ne remplace pas
|
|
`Anonymisation.exe`)
|
|
|
|
### Build CLI
|
|
|
|
Sur la machine Windows de build, dans le venv de build :
|
|
|
|
```powershell
|
|
pyinstaller --noconfirm --clean anonymisation_cli_onefile.spec
|
|
```
|
|
|
|
Le `.spec` embarque les mêmes ressources que la GUI : `config\`, `data\`,
|
|
`models\camembert-bio-deid\onnx\`, `detectors\`, `assets\`, plus les
|
|
hiddenimports NER / docTR / ONNX. Le modèle ONNX obligatoire
|
|
`models\camembert-bio-deid\onnx\model.onnx` doit exister localement avant le
|
|
build (sinon il ne sera pas embarqué et le CLI échouera au lancement).
|
|
|
|
### Utilisation
|
|
|
|
```powershell
|
|
Anonymisation-CLI.exe "C:\chemin\document.pdf" "C:\chemin\sortie"
|
|
Anonymisation-CLI.exe --help
|
|
```
|
|
|
|
- argument 1 : fichier unique existant (ou dossier parcouru récursivement) ;
|
|
- argument 2 : dossier de sortie (créé si absent) ; `--out` reste accepté ;
|
|
- chemins avec espaces et accents supportés ;
|
|
- options : `--no-ner` (regex seul), `--gliner` (vote croisé optionnel),
|
|
`--limit N`, `--config <dictionnaires.yml>`.
|
|
|
|
Sorties produites dans le dossier demandé (identiques à la GUI v5, burn raster) :
|
|
`<doc>.redacted_raster.pdf`, `<doc>.pseudonymise.txt`, `<doc>.audit.jsonl`.
|
|
Un log lisible est écrit à côté de l'EXE : `anonymisation_cli.log`.
|
|
|
|
### Codes retour
|
|
|
|
| Code | Signification |
|
|
|------|---------------|
|
|
| `0` | anonymisation terminée, sortie produite |
|
|
| `1` | erreur de traitement (exception) |
|
|
| `2` | entrée manquante (fichier/dossier introuvable, aucun document) |
|
|
| `3` | modèle OBLIGATOIRE absent / illisible (fail-closed, pas de mode dégradé) |
|
|
| `4` | sortie non produite (quarantaine résiduelle ou PDF absent) |
|
|
|
|
### Modèles (dernière version du moteur)
|
|
|
|
- **OBLIGATOIRE** : CamemBERT-bio ONNX (`models\camembert-bio-deid\onnx\model.onnx`).
|
|
Embarqué dans le build. S'il est absent/illisible et que le NER est demandé,
|
|
le CLI **échoue clairement (code 3)** — il n'affiche jamais « OK » en mode
|
|
dégradé silencieux.
|
|
- **OPTIONNELS** : EDS-Pseudo, GLiNER. Chargés best effort et **tracés dans le
|
|
log** ; leur absence est signalée explicitement, jamais masquée. ⚠️ EDS-Pseudo
|
|
peut ne pas être embarqué dans le paquet MVP frozen — voir
|
|
`docs/limitations-frozen-mvp.md`. Dans ce cas le log indique
|
|
« EDS-Pseudo (optionnel) INDISPONIBLE » et le traitement se poursuit avec
|
|
CamemBERT-bio ONNX (impact qualité faible, validé en bêta interne).
|
|
- `--no-ner` : mode regex seul **assumé** par l'opérateur (aucun modèle
|
|
obligatoire), à n'utiliser qu'en connaissance de cause.
|
|
|
|
### Limitations CLI frozen
|
|
|
|
- pas d'EDS-Pseudo garanti dans le MVP frozen (cf. ci-dessus) ;
|
|
- pas de dépendance internet : tous les modèles déclarés obligatoires sont
|
|
locaux/embarqués ;
|
|
- rastérisation séquentielle en mode frozen (cf. limitations GUI).
|
|
|
|
### Installateur CLI dédié (Inno Setup, séparé de la GUI)
|
|
|
|
Pour les tests internes et l'intégration de la brique CLI dans un autre logiciel,
|
|
un installateur Inno Setup **distinct de la GUI** est fourni :
|
|
|
|
- script : `installer\Anonymisation-CLI.iss` (AppId propre, ne partage pas la
|
|
désinstallation de la GUI ; `installer\Anonymisation.iss` n'est pas modifié) ;
|
|
- build : `scripts\build_windows_cli_installer_only.ps1` ;
|
|
- sortie : `release\Anonymisation-CLI-Setup.exe` (+ `.sha256.txt`).
|
|
|
|
```powershell
|
|
# 1. builder l'EXE CLI (cf. section précédente) -> dist\Anonymisation-CLI.exe
|
|
# 2. builder l'installateur :
|
|
powershell -ExecutionPolicy Bypass -File .\scripts\build_windows_cli_installer_only.ps1
|
|
```
|
|
|
|
Caractéristiques de l'installateur :
|
|
|
|
- **sans droits admin** (`PrivilegesRequired=lowest`) ;
|
|
- dossier par défaut : `%LOCALAPPDATA%\Programs\Anonymisation-CLI` ;
|
|
- **pas** d'ajout au PATH système, **pas** de raccourci bureau (entrée menu
|
|
Démarrer vers le README seulement) ;
|
|
- désinstalleur Windows standard, qui **supprime les clés de registre créées**.
|
|
|
|
#### Clés de registre HKCU (intégration logicielle tierce)
|
|
|
|
```
|
|
HKCU\Software\CHUXX\Anonymisation-CLI
|
|
InstallPath = <dossier d'installation>
|
|
ExePath = <dossier>\Anonymisation-CLI.exe
|
|
Version = <version>
|
|
|
|
HKCU\Software\Microsoft\Windows\CurrentVersion\App Paths\Anonymisation-CLI.exe
|
|
(Default) = <dossier>\Anonymisation-CLI.exe
|
|
Path = <dossier>
|
|
```
|
|
|
|
Un autre logiciel retrouve l'exe ainsi (PowerShell) :
|
|
|
|
```powershell
|
|
$exe = (Get-ItemProperty 'HKCU:\Software\CHUXX\Anonymisation-CLI').ExePath
|
|
& $exe "C:\doc.pdf" "C:\sortie"
|
|
```
|
|
|
|
## Blocage Windows / SmartScreen
|
|
|
|
Un exécutable PyInstaller non signé peut déclencher Microsoft Defender SmartScreen, surtout s'il est téléchargé depuis Internet ou envoyé par e-mail. La signature réduit fortement le risque et évite l'éditeur inconnu, mais elle ne garantit pas toujours l'absence totale d'avertissement SmartScreen pour une toute nouvelle version : Windows tient aussi compte de la réputation du fichier et de son hash.
|
|
|
|
Pour une diffusion à des utilisateurs novices, la voie recommandée est :
|
|
|
|
- signer `Anonymisation.exe` avec un certificat Authenticode
|
|
- horodater la signature
|
|
- diffuser par partage réseau interne, Intune, GPO ou portail établissement
|
|
- conserver le hash `release\Anonymisation.exe.sha256.txt`
|
|
- éviter de demander aux utilisateurs de cliquer sur `Exécuter quand même`
|
|
|
|
Le script prend en charge la signature si un certificat est disponible.
|
|
|
|
### Signature automatique avec configuration locale
|
|
|
|
Sur la machine Windows de build :
|
|
|
|
1. copier `build_signing.example.ps1` en `build_signing.local.ps1`
|
|
2. renseigner l'empreinte du certificat ou le chemin du PFX
|
|
3. double-cliquer comme d'habitude sur `build_windows_oneclick.bat`
|
|
|
|
`build_signing.local.ps1` est ignoré par Git pour éviter de versionner des secrets.
|
|
|
|
### Signature manuelle via PowerShell
|
|
|
|
Avec un certificat installé dans le magasin Windows :
|
|
|
|
```powershell
|
|
powershell -ExecutionPolicy Bypass -File .\scripts\build_windows_oneclick.ps1 -Sign -CertThumbprint "EMPREINTE_CERTIFICAT"
|
|
```
|
|
|
|
Avec un fichier PFX :
|
|
|
|
```powershell
|
|
powershell -ExecutionPolicy Bypass -File .\scripts\build_windows_oneclick.ps1 -Sign -PfxPath "C:\chemin\certificat.pfx" -PfxPassword "mot-de-passe"
|
|
```
|
|
|
|
Si aucun certificat n'est disponible, le build reste possible, mais Windows peut afficher un avertissement de réputation au premier lancement.
|
|
|
|
Références Microsoft :
|
|
|
|
- SmartScreen reputation : https://learn.microsoft.com/en-us/windows/apps/package-and-deploy/smartscreen-reputation
|
|
- SignTool : https://learn.microsoft.com/en-us/windows/win32/seccrypto/signtool
|
|
- Authenticode timestamping : https://learn.microsoft.com/en-us/windows/win32/seccrypto/time-stamping-authenticode-signatures
|