Skip to content

fix(kiosk): la console du poste ne reste plus devant le client - #37

Merged
lostmind84 merged 1 commit into
mainfrom
fix/la-console-du-kiosque-reste-a-l-ecran
Jul 31, 2026
Merged

lostmind84 merged 1 commit into
mainfrom
fix/la-console-du-kiosque-reste-a-l-ecran

Conversation

@lostmind84

Copy link
Copy Markdown
Owner

Le défaut

Signalé depuis le poste : « quand l'app démarre, il y a un terminal qui s'ouvre et qui reste ouvert avec une tâche en suspens ».

La cause, mesurée

openscale.exe est une application console : le champ Subsystem de son en-tête PE vaut 3, IMAGE_SUBSYSTEM_WINDOWS_CUI — mesuré sur un binaire fraîchement construit, et c'est ce que produit la chaîne Go sur Windows sans réglage. La tâche planifiée de §15.2 lance openscale kiosk dans la session interactive du compte non privilégié : Windows lui alloue donc une console, et cette fenêtre reste devant le client aussi longtemps que tourne le superviseur — indéfiniment, par conception. La « tâche en suspens » est la boucle de supervision elle-même.

Le service serve n'a jamais été concerné : le gestionnaire de services le tient en session 0, invisible quel que soit le sous-système.

Le correctif

platform.HideOwnConsole(), appelé par openscale kiosk juste avant d'entrer dans la boucle du superviseur.

Le garde-fou, qui est le tout de la décision

La règle n'est pas « masquer la console », c'est « masquer la console qu'on nous a donnée ». Le même binaire se lance à la main depuis un terminal quand un poste n'affiche rien (§15.4) : la console est alors celle de l'opérateur, et la masquer lui retirerait sa fenêtre en plein diagnostic.

Le discriminant est GetConsoleProcessList, exact et non heuristique — c'est le nombre de processus attachés à la console. Mesuré aux trois lancements :

Lancement processus attachés
depuis une invite PowerShell 4
Start-Process (console neuve) 1
cmd /c start (console neuve) 1

Le Planificateur de tâches est dans le second cas, comme tout CreateProcess portant CREATE_NEW_CONSOLE.

ShowWindow et jamais FreeConsole

Les deux font disparaître la fenêtre ; un seul laisse une sortie standard qui fonctionne. Mesuré : après ShowWindow(SW_HIDE), une écriture sur os.Stdout rend toujours n=37, err=nil.

Or openscale kiosk écrit à travers un io.MultiWriter posé sur la sortie standard et sur le journal du superviseur, et io.MultiWriter abandonne au premier writer en échec : détacher la console arrêterait le journal à la ligne qui précède l'appel. Le seul fichier que quelqu'un ouvre quand un poste n'affiche rien deviendrait muet, pour cacher une fenêtre.

Deux voies écartées

  • -H=windowsgui — ne cache pas la fenêtre des sous-commandes, leur retire leur sortie. doctor et ses 15 contrôles, drivers, label, capture, replay, config export existent pour écrire dans un terminal qu'un humain lit. Un poste en panne se diagnostique par ces lignes.
  • Un second binaire openscale-kiosk.exe en windowsgui — aucun défaut de conception, seulement un coût : deux exécutables pour trois cibles, deux dans l'archive de §17.2, deux dans SHA256SUMS, deux à remplacer par update.ps1, deux dans l'empreinte. La mécanique de livraison entière double, pour une fenêtre.

Ce qu'on accepte en échange

L'appel est placé après la recherche du navigateur : « aucun navigateur trouvé sur ce poste » n'est rapporté par rien d'autre, et masquer plus tôt enverrait cette phrase à une fenêtre déjà sortie de l'écran. Le prix est une console visible pendant les quelques centaines de millisecondes qui précèdent le navigateur, devant un bureau Windows que le client ne regarde pas. Un échec de démarrage garde sa fenêtre — c'est voulu.

Trouvé en chemin

start.bat ouvrait trois fenêtres — console de serve, console de kiosk, navigateur — là où son propre en-tête en annonce deux. Elle en ouvre maintenant deux. La fenêtre « OpenScale - poste » est conservée : c'est le seul geste d'arrêt documenté sans ligne de commande.

Vérification

make test exit 0 : passe -race (cgo), passe CGO_ENABLED=0, boundary, deps. 2 914 tests Go (2 905 verts, 9 écartés) sur 35 paquets. Compilation GOOS=linux vérifiée.

Le banc du garde-fou a des dents : garde-fou neutralisé, il tombe avec « la console partagée avec le shell a été masquée — un développeur vient de perdre son terminal ».

Le banc du cas de production reproduit le lancement réel — le binaire de test se relance lui-même avec CREATE_NEW_CONSOLE — et vérifie les deux promesses : la fenêtre est partie, et la sortie standard accepte encore une ligne.

Une réserve, dite franchement

Une exécution sur les huit premières de la suite complète a échoué, et je ne l'ai pas capturée. Elle ne s'est pas reproduite : 14 passes complètes vertes depuis, plus 20 répétitions des trois paquets touchés. Les bancs ajoutés ici ne sont pas en cause. Le test fautif reste non identifié.

Documentation

  • ADR-054 dans docs/02-architecture.md §20, et un paragraphe en §15.2.
  • SUIVI.md : entrée de journal, et compteur d'ADR porté à 54 — contigus de 001 à 054, revérifié sans trou.

Le binaire est une application console — champ PE Subsystem = 3,
IMAGE_SUBSYSTEM_WINDOWS_CUI, ce que produit la chaîne Go sur Windows sans
qu'on demande rien — et la tâche planifiée de §15.2 lance « openscale kiosk »
dans la session interactive. Windows lui alloue donc une console, et cette
fenêtre reste à l'écran aussi longtemps que tourne la boucle du superviseur,
c'est-à-dire indéfiniment. Le service n'a jamais été concerné : la session 0
n'a pas de bureau.

platform.HideOwnConsole() retire la fenêtre, et seulement quand ce processus
est seul attaché à cette console. Mesuré : GetConsoleProcessList rend 1 sur
une console neuve — Planificateur, Start-Process, cmd start — et 4 depuis une
invite PowerShell. Sans ce garde, « openscale kiosk » lancé à la main pour
diagnostiquer un poste noir (§15.4) ferait disparaître le terminal de
l'opérateur en plein diagnostic ; un banc le vérifie.

ShowWindow et jamais FreeConsole : les deux font disparaître la fenêtre, un
seul laisse une sortie standard qui marche. Mesuré : après masquage, une
écriture sur os.Stdout rend n=37, err=nil. Le kiosque écrit par un
io.MultiWriter posé sur la sortie standard ET sur son journal, et
io.MultiWriter abandonne au premier writer en échec — détacher la console
aurait rendu muet le seul fichier qu'on ouvre quand un poste n'affiche rien.

Écartés : -H=windowsgui, qui ne cache pas la fenêtre des sous-commandes mais
leur retire leur sortie, et un second binaire kiosque, qui double la mécanique
de livraison entière pour une fenêtre.

L'appel est placé après la recherche du navigateur, parce que « aucun
navigateur trouvé sur ce poste » n'est rapporté par rien d'autre.

ADR-054.
@lostmind84
lostmind84 merged commit 2383dfa into main Jul 31, 2026
6 checks passed
@lostmind84
lostmind84 deleted the fix/la-console-du-kiosque-reste-a-l-ecran branch July 31, 2026 17:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant