mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-18 04:36:44 +02:00
Socle du renommage jean -> AJEAN, sans aucun impact visible pour le parc installe. Trois briques : - module github.com/nathaninline/ajean, cmd/ajean, internal/ajean, package ajean. Purement interne. - AjeanHome() remplace JeanHome(). Les defauts deviennent %ProgramData%\ajean et /etc/ajean, avec migration du dossier existant au premier lancement. La migration est un os.Rename dans le dossier parent de l'ancien chemin : intra-volume, donc atomique et instantane meme avec des .gguf de plusieurs dizaines de Go. Si le rename echoue (handle ouvert sous Windows, droits, volume en lecture seule) on CONTINUE sur l'ancien chemin et on retentera : jamais de copie, jamais de suppression, le pire cas est "rien n'a bouge". $AJEAN_HOME et $JEAN_HOME restent tous deux honores, ainsi que /etc/default/ajean et /etc/default/jean : un chemin impose a la main est un ordre, on ne le migre pas. - l'auto-MAJ accepte desormais ajean-<os>-<arch> ET jean-<os>-<arch>, dans cet ordre. Indispensable dans les deux sens : les binaires deja installes ne connaissent que jean-*, et ce binaire-ci doit pouvoir s'installer depuis une release anterieure au renommage. Couvert par des tests, dont le repli quand un handle ouvert bloque le rename sous Windows.
65 lines
2.5 KiB
Go
65 lines
2.5 KiB
Go
//go:build windows
|
|
|
|
package ajean
|
|
|
|
// sys_console_windows.go — gestion de la console sous Windows.
|
|
//
|
|
// Le binaire est compilé en sous-système GUI (`-H=windowsgui`) : au double-clic,
|
|
// Windows n'alloue AUCUNE console → plus jamais de « fenêtre noire de terminal »
|
|
// qui s'ouvre et se ferme. En contrepartie, un binaire GUI lancé depuis un
|
|
// terminal (cmd/PowerShell) n'écrit nulle part par défaut : on se rattache alors
|
|
// explicitement à la console du parent et on réouvre stdout/stderr/stdin dessus,
|
|
// pour que l'usage CLI (`jean web`, `jean status`, …) reste lisible.
|
|
|
|
import (
|
|
"os"
|
|
"syscall"
|
|
"unsafe"
|
|
)
|
|
|
|
// setupConsole rattache le process à la console de son parent si elle existe.
|
|
// Retourne true si on dispose d'une console (→ usage CLI), false sinon (double-
|
|
// clic sans console → expérience « application »).
|
|
func setupConsole() bool {
|
|
const attachParentProcess = ^uintptr(0) // (DWORD)-1 = ATTACH_PARENT_PROCESS
|
|
k := syscall.NewLazyDLL("kernel32.dll")
|
|
r, _, _ := k.NewProc("AttachConsole").Call(attachParentProcess)
|
|
if r == 0 {
|
|
return false // aucune console parente = lancé par double-clic (mode app)
|
|
}
|
|
// Réouvre les flux standard sur la console fraîchement rattachée : sans ça,
|
|
// os.Stdout/Stderr pointent sur des handles invalides (sous-système GUI).
|
|
if con, err := os.OpenFile("CONOUT$", os.O_WRONLY, 0); err == nil {
|
|
os.Stdout = con
|
|
os.Stderr = con
|
|
}
|
|
if cin, err := os.OpenFile("CONIN$", os.O_RDONLY, 0); err == nil {
|
|
os.Stdin = cin
|
|
}
|
|
configureConsole()
|
|
return true
|
|
}
|
|
|
|
// configureConsole passe la console en UTF-8 + traitement des séquences ANSI
|
|
// (couleurs/curseur), comme le faisait l'init() au chargement — mais APRÈS le
|
|
// rattachement, sinon ça ciblait une console encore inexistante.
|
|
func configureConsole() {
|
|
const (
|
|
cpUTF8 = 65001
|
|
enableVirtualTerminalProcessing = 0x0004
|
|
stdOutputHandle = ^uintptr(10) // -11
|
|
)
|
|
k := syscall.NewLazyDLL("kernel32.dll")
|
|
_, _, _ = k.NewProc("SetConsoleOutputCP").Call(uintptr(cpUTF8))
|
|
_, _, _ = k.NewProc("SetConsoleCP").Call(uintptr(cpUTF8))
|
|
h, _, _ := k.NewProc("GetStdHandle").Call(stdOutputHandle)
|
|
var mode uint32
|
|
if r, _, _ := k.NewProc("GetConsoleMode").Call(h, uintptr(unsafe.Pointer(&mode))); r != 0 {
|
|
_, _, _ = k.NewProc("SetConsoleMode").Call(h, uintptr(mode|enableVirtualTerminalProcessing))
|
|
}
|
|
}
|
|
|
|
// appWarning : rien à signaler sous Windows (pas d'App Translocation). Voir
|
|
// sys_console_darwin.go.
|
|
func appWarning() string { return "" }
|