mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-13 10:17:58 +02:00
L'elevation ajoutee en 0.7.3 n'etait jamais atteinte. Elle n'etait cablee que dans `install` et dans l'installeur de mise a jour (double-clic sur l'exe telecharge) ; or les utilisateurs font `ajean update` ou cliquent le bouton de l'interface. restartAfterUpdate ne fait rien sous Windows, et au redemarrage appFirstRun sort avant d'arriver la (l'application se reconnait comme etant deja l'installee). Aucun poste ne migrait donc jamais. postUpdateMigrate est appele apres une mise a jour reussie, cote CLI comme cote UI web. Une hypothese a ete invalidee au passage, et elle changeait tout : on croyait qu'un binaire en cours d'execution empechait de renommer le dossier qui le contient. C'est faux — Windows verrouille le fichier .exe, pas le nom de ses dossiers parents. Verifie sur banc d'essai. La migration peut donc se faire depuis l'application en marche, ce qui rend ce chemin possible. Consequence non anticipee, traitee ici : le binaire installe vit DANS le dossier de donnees. Le renommer deplace donc le programme, et laisse un raccourci du menu Demarrer et une entree de PATH pointant dans le vide. relinkAfterMigration repointe le raccourci, ajoute le nouveau dossier bin au PATH et retire l'ancien. Course de donnees corrigee : retryHomeMigration reinitialisait le cache du dossier resolu sans verrou, alors qu'il est desormais appele depuis un handler HTTP pendant que le serveur sert d'autres requetes. sync.Once est remplace par un RWMutex, et les reinitialisations directes des installeurs Unix passent par resetResolvedHome.
52 lines
2.1 KiB
Go
52 lines
2.1 KiB
Go
//go:build windows
|
|
|
|
package ajean
|
|
|
|
import (
|
|
"fmt"
|
|
"path/filepath"
|
|
)
|
|
|
|
// Migration du dossier juste après une mise à jour, sous Windows.
|
|
//
|
|
// C'est le chaînon qui manquait. Les utilisateurs ne relancent pas `install` et
|
|
// ne retéléchargent pas l'exécutable : ils font `ajean update`, ou cliquent le
|
|
// bouton de l'interface. Or ce chemin-là ne tentait rien — l'élévation n'était
|
|
// câblée que dans `install` et dans l'installeur de mise à jour. Résultat : un
|
|
// poste sans droits administrateur restait sur %ProgramData%\jean pour toujours,
|
|
// sans qu'aucune fenêtre ne propose jamais de le régler.
|
|
//
|
|
// Contrairement à ce qu'on pourrait croire, le binaire en cours d'exécution
|
|
// n'empêche PAS de renommer le dossier qui le contient : Windows verrouille le
|
|
// fichier .exe lui-même, pas le nom de ses dossiers parents. Vérifié sur banc
|
|
// d'essai. La migration peut donc se faire depuis l'application en marche.
|
|
func postUpdateMigrate() {
|
|
if !retryHomeMigration() && !elevateForHomeMigration() {
|
|
return
|
|
}
|
|
fmt.Printf("%s dossier de données migré vers %s\n", green("✓"), AjeanHome())
|
|
relinkAfterMigration()
|
|
}
|
|
|
|
// relinkAfterMigration répare ce que le déplacement laisse derrière lui.
|
|
//
|
|
// Le binaire installé vit DANS le dossier de données (%AJEAN_HOME%\bin). Le
|
|
// renommer déplace donc aussi le programme : le raccourci du menu Démarrer et
|
|
// l'entrée de PATH désignent un chemin qui n'existe plus. Sans cette étape, la
|
|
// migration « réussit » et l'utilisateur se retrouve avec un raccourci mort et
|
|
// une commande `ajean` introuvable — soit exactement ce qu'on cherchait à éviter.
|
|
func relinkAfterMigration() {
|
|
target := installedExePath()
|
|
binDir := filepath.Dir(target)
|
|
|
|
if _, err := addToUserPath(binDir); err != nil {
|
|
fmt.Printf(" %s PATH non mis à jour (%v) — ajoute %s à la main\n", dim("•"), err, binDir)
|
|
}
|
|
// L'ancienne entrée ne désigne plus rien : la laisser encombrerait le PATH
|
|
// d'un chemin mort, et ferait échouer un `jean` tapé par habitude.
|
|
if legacyBin := filepath.Join(legacyDefaultHome(), "bin"); legacyBin != binDir {
|
|
_, _ = removeFromUserPath(legacyBin)
|
|
}
|
|
ensureShortcuts(target)
|
|
}
|