v0.7.5 : le bouton de mise a jour redemarre l'application (Windows)

Un process ne peut pas se relancer lui-meme : tant qu'il tourne, il occupe le
port et tient son propre dossier de donnees. On delegue donc a un
accompagnateur detache — une copie de nous lancee avec une sous-commande
interne — qui attend notre disparition, migre pendant cette fenetre, puis
relance l'application.

C'est cette fenetre qui manquait depuis le debut. Une mise a jour en place
laisse AJEAN tourner, donc le dossier tenu, donc le renommage echoue avec
« Acces refuse » — que Windows renvoie aussi bien pour un verrou que pour un
manque de droits. D'ou des postes bloques sur l'ancien nom malgre 0.7.1 a
0.7.4. Le retour terrain le confirme : la migration n'a abouti qu'en lancant
l'exe telecharge, seul chemin qui arretait les instances avant de migrer.

installedExePath() est relu APRES la migration avant de relancer : le binaire
installe vit dans le dossier de donnees, il change donc de place avec lui, et
relancer l'ancien chemin echouerait. Repli sur le binaire courant si la cible
a disparu — mieux vaut relancer quelque chose que laisser l'utilisateur sans
application.

L'attente est bornee a 30 s. Un depassement n'interrompt pas la suite : la
migration echouera peut-etre et sera retentee plus tard, alors que rester
coince laisserait l'utilisateur sans rien.

Verifie de bout en bout sur banc d'essai : l'accompagnateur attend la
fermeture du process cible, se termine proprement, et l'application est bien
relancee et ressert l'UI.
This commit is contained in:
nathaninline committed 2026-08-04 17:31:06 +02:00
1 parent 1f773151a6
commit d72578ea55
8 files changed
+127 -13

No files matched your search

+7 -1
View File
@@ -405,7 +405,6 @@ func handleUpdateApply(w http.ResponseWriter, r *http.Request) {
sendJSON(w, 500, map[string]any{"ok": false, "error": err.Error()})
return
}
postUpdateMigrate()
restarting, msg := restartAfterUpdate()
if !restarting {
msg = restartHintText()
@@ -423,6 +422,13 @@ func handleUpdateApply(w http.ResponseWriter, r *http.Request) {
// et l'UI se reconnecte toute seule (boucle de reconnexion du flux). Renvoie
// (déclenché, message). Non-serveur (poste client, Windows) → (false, "").
func restartAfterUpdate() (bool, string) {
// Windows : pas de superviseur pour nous relancer, on delegue a un
// accompagnateur detache (voir sys_restart_windows.go). C'est aussi ce qui
// cree la fenetre ou plus rien ne tient le dossier de donnees, donc ou la
// migration peut aboutir.
if runtime.GOOS == "windows" {
return scheduleAppRestart()
}
if runtime.GOOS != "linux" || !linkServiceActive() {
return false, ""
}