From dd0df78341a58eeb685e807a05e6bcb6824d0606 Mon Sep 17 00:00:00 2001 From: Johnny Date: Fri, 4 Sep 2026 20:52:24 +0200 Subject: [PATCH] chore(release): v0.7.14 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remplace l'enregistrement du service wgsecure-helper (sc.exe create/ start via [Run]) par un appel Exec()+AddQuotes en Pascal script : l'échappement de guillemets imbriqués dans la chaîne Parameters produisait une commande sc.exe invalide, silencieusement, alors que la même commande fonctionnait lancée à la main. Le service n'était donc jamais enregistré malgré une installation "réussie". Co-Authored-By: Claude Sonnet 5 --- CHANGELOG.md | 7 +++++ Makefile | 2 +- README.md | 4 +-- app/__init__.py | 2 +- wgsecure.iss | 68 ++++++++++++++++++++++++++++++++++++------------- 5 files changed, 62 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index db181ca..8422a48 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,13 @@ Ce projet suit le [Versionnage Sémantique](https://semver.org/lang/fr/). --- +## [0.7.14] — 2026-09-04 + +### Corrigé +- **Le service `wgsecure-helper` n'était jamais enregistré par l'installeur.** Les entrées `[Run]` posant `sc.exe create ...` via l'échappement de guillemets `""` imbriqués d'Inno Setup produisaient une commande invalide — silencieusement : aucune erreur affichée pendant l'installation, alors que la même commande, lancée à la main avec une syntaxe équivalente, fonctionnait. Remplacé par un appel `Exec()` scripté (Pascal, `AddQuotes`) après la copie des fichiers, qui construit et lance la commande sans juggler des niveaux d'échappement de chaîne imbriqués. Même mécanisme pour la désinstallation (arrêt + suppression du service). + +--- + ## [0.7.13] — 2026-09-04 ### Corrigé diff --git a/Makefile b/Makefile index 69f7f28..c608e54 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ ## ────────────────────────────────────────────── APP := wgsecure -VERSION := 0.7.13 +VERSION := 0.7.14 VENV := .venv PYTHON := $(VENV)/bin/python3 PIP := $(VENV)/bin/pip diff --git a/README.md b/README.md index c7d6f30..ca2b498 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # 🛡️ WGSecure (WGS) -🚀 v0.7.13 · 🐍 · 🪟🐧 · 🔐 MFA TOTP · 🛡️ WireGuard +🚀 v0.7.14 · 🐍 · 🪟🐧 · 🔐 MFA TOTP · 🛡️ WireGuard **WGSecure** est une interface graphique multiplateforme (Windows & Linux) pour gérer une connexion WireGuard avec une surcouche MFA (authentification à deux facteurs TOTP). @@ -210,4 +210,4 @@ WGSecure/ ## 👤 Auteur Développé par **Johnny** — [JT-Tools](https://github.com/JT-Tools) -Version : ![v0.7.13](https://img.shields.io/badge/v0.7.13-septembre%202026-2980b9?style=flat-square) — Septembre 2026 +Version : ![v0.7.14](https://img.shields.io/badge/v0.7.14-septembre%202026-2980b9?style=flat-square) — Septembre 2026 diff --git a/app/__init__.py b/app/__init__.py index 0f49901..b05d1c5 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,3 +1,3 @@ -__version__ = "0.7.13" +__version__ = "0.7.14" APP_NAME = "WGSecure" APP_SHORT = "WGS" diff --git a/wgsecure.iss b/wgsecure.iss index 48c9904..b09f49a 100644 --- a/wgsecure.iss +++ b/wgsecure.iss @@ -5,7 +5,7 @@ ; ────────────────────────────────────────────── #define MyAppName "WGSecure" -#define MyAppVersion "0.7.13" +#define MyAppVersion "0.7.14" #define MyAppPublisher "WGSecure" #define MyAppExeName "wgsecure.exe" @@ -59,20 +59,8 @@ Filename: "{tmp}\VC_redist.x64.exe"; Parameters: "/install /quiet /norestart"; S ; (PrivilegesRequired=admin ci-dessus), donc pas d'UAC supplémentaire non plus. ; `waituntilterminated` : l'app ne doit pas démarrer avant que wg.exe existe. Filename: "{tmp}\wireguard-installer.exe"; StatusMsg: "Installation de WireGuard…"; Check: WireGuardNeedsInstall; Flags: waituntilterminated -; Enregistre et démarre le service privilégié s'il a été fourni (cf. [Files] -; ci-dessus). "binPath= " avec l'espace après "=" est une exigence de la -; syntaxe sc.exe, pas d'Inno Setup — l'oublier fait échouer la commande. -Filename: "{sys}\sc.exe"; Parameters: "create WGSecureHelper binPath= ""{app}\wgsecure-helper.exe"" start= auto DisplayName= ""WGSecure Helper"""; StatusMsg: "Installation du service WGSecure Helper…"; Check: HelperServiceAvailable; Flags: runhidden -Filename: "{sys}\sc.exe"; Parameters: "start WGSecureHelper"; StatusMsg: "Démarrage du service WGSecure Helper…"; Check: HelperServiceAvailable; Flags: runhidden Filename: "{app}\{#MyAppExeName}"; Description: "Lancer {#MyAppName}"; Flags: nowait postinstall skipifsilent -[UninstallRun] -; Arrête puis supprime le service avant que ses fichiers ne disparaissent — -; sc.exe ignore silencieusement une commande sur un service déjà absent -; (ex. installeur généré sans le composant service), donc pas de Check ici. -Filename: "{sys}\sc.exe"; Parameters: "stop WGSecureHelper"; Flags: runhidden; RunOnceId: "StopWGSecureHelper" -Filename: "{sys}\sc.exe"; Parameters: "delete WGSecureHelper"; Flags: runhidden; RunOnceId: "DeleteWGSecureHelper" - [Code] function VCRedistNeedsInstall: Boolean; var @@ -90,9 +78,55 @@ begin Result := not FileExists(ExpandConstant('{pf}\WireGuard\wireguard.exe')); end; -function HelperServiceAvailable: Boolean; +// Enregistre et démarre le service privilégié (cf. app/service/) via +// Exec()+AddQuotes plutôt que des entrées [Run] à guillemets échappés +// ("" imbriqués) : une tentative précédente basée sur l'échappement de +// chaîne Inno Setup produisait une commande sc.exe invalide (silencieuse, +// aucune erreur visible pendant l'installation) alors que la même commande +// fonctionnait telle quelle lancée à la main — AddQuotes() gère le +// guillemetage de façon fiable, sans juggler des niveaux d'échappement +// imbriqués à la main. +procedure InstallHelperService; +var + ResultCode: Integer; + ExePath, Params: String; begin - // wgsecure-helper.exe est optionnel (skipifsourcedoesntexist dans - // [Files]) : n'enregistrer le service que si le binaire a bien été copié. - Result := FileExists(ExpandConstant('{app}\wgsecure-helper.exe')); + ExePath := ExpandConstant('{app}\wgsecure-helper.exe'); + // Optionnel (skipifsourcedoesntexist dans [Files]) : n'enregistrer le + // service que si le binaire a bien été copié. + if not FileExists(ExePath) then + exit; + + Params := 'create WGSecureHelper binPath= ' + AddQuotes(ExePath) + + ' start= auto DisplayName= ' + AddQuotes('WGSecure Helper'); + Exec(ExpandConstant('{sys}\sc.exe'), Params, '', SW_HIDE, + ewWaitUntilTerminated, ResultCode); + + Exec(ExpandConstant('{sys}\sc.exe'), 'start WGSecureHelper', '', SW_HIDE, + ewWaitUntilTerminated, ResultCode); +end; + +// sc.exe ignore silencieusement une commande sur un service déjà absent +// (ex. installeur généré sans le composant service) : pas besoin de tester +// son existence avant d'arrêter/supprimer. +procedure UninstallHelperService; +var + ResultCode: Integer; +begin + Exec(ExpandConstant('{sys}\sc.exe'), 'stop WGSecureHelper', '', SW_HIDE, + ewWaitUntilTerminated, ResultCode); + Exec(ExpandConstant('{sys}\sc.exe'), 'delete WGSecureHelper', '', SW_HIDE, + ewWaitUntilTerminated, ResultCode); +end; + +procedure CurStepChanged(CurStep: TSetupStep); +begin + if CurStep = ssPostInstall then + InstallHelperService; +end; + +procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep); +begin + if CurUninstallStep = usUninstall then + UninstallHelperService; end;