mirror of
https://github.com/R0m1k3/Loki.git
synced 2026-10-12 01:37:06 +02:00
- module github.com/R0m1k3/Loki, cmd/loki, internal/loki (package loki) - LOKI_HOME, LOKI_MODEL_DIRS, LOKI_SERVICE, LOKI_DL_CONNS ; /etc/loki ; units loki-engine / loki-ui ; binaire et aide CLI - updateRepo pointe sur R0m1k3/Loki (l'auto-update ne tirera plus les binaires AJEAN amont) Conservé à l'identique : le domaine ajean.link (service de tunnel amont), les littéraux de migration 0.7.x (migrate_07.go), RELEASE_NOTES.md et LICENSE (historique et licence de l'amont). go build/vet/test : verts.
101 lines
3.8 KiB
Go
101 lines
3.8 KiB
Go
//go:build windows
|
|
|
|
package loki
|
|
|
|
// sys_console_windows.go — gestion de la console sous Windows.
|
|
//
|
|
// Le binaire est compilé en sous-système CONSOLE. C'est ce qui fait que `cmd`
|
|
// ATTEND la fin du programme : avec un binaire graphique, il rendait la main
|
|
// aussitôt et réaffichait son invite AVANT la sortie d'Loki, ce qui donnait
|
|
//
|
|
// C:\Users\Nathan>loki
|
|
//
|
|
// C:\Users\Nathan>loki 0.8.0 — manager llama.cpp + UI web
|
|
//
|
|
// La même cause cassait la redirection et les tubes, et rendait `loki chat`
|
|
// inutilisable depuis un terminal (le shell et Loki se disputaient l'entrée).
|
|
//
|
|
// EN CONTREPARTIE, Windows alloue une console à tout lancement sans terminal —
|
|
// un double-clic. On la referme alors immédiatement : voir setupConsole. Les
|
|
// raccourcis créés par l'installation demandent en plus un démarrage minimisé,
|
|
// si bien que cette console n'est jamais peinte à l'écran.
|
|
|
|
import (
|
|
"syscall"
|
|
"unsafe"
|
|
)
|
|
|
|
// win appelle une procédure Win32 et renvoie (résultat, trouvée).
|
|
//
|
|
// LazyProc.Call PANIQUE quand la procédure est introuvable. Or tout ce fichier
|
|
// s'exécute AVANT le reste du programme : une panique ici et il ne reste rien à
|
|
// l'écran pour la comprendre, l'application ne démarre tout simplement plus.
|
|
// C'est exactement ce qui est arrivé en cherchant ShowWindow dans kernel32
|
|
// alors qu'elle vit dans user32. Aucun réglage de confort ne mérite ça.
|
|
func win(dll *syscall.LazyDLL, name string, a ...uintptr) (uintptr, bool) {
|
|
p := dll.NewProc(name)
|
|
if err := p.Find(); err != nil {
|
|
return 0, false
|
|
}
|
|
r, _, _ := p.Call(a...)
|
|
return r, true
|
|
}
|
|
|
|
var kernel32 = syscall.NewLazyDLL("kernel32.dll")
|
|
|
|
// setupConsole décide dans quel monde on tourne et renvoie true en usage CLI.
|
|
//
|
|
// Le signal est le nombre de processus rattachés à notre console : si nous
|
|
// sommes le SEUL, c'est que Windows l'a créée pour nous, donc qu'aucun terminal
|
|
// ne nous a lancés. On la fait disparaître et on bascule en mode application.
|
|
// Un shell rattaché (cmd, PowerShell, Windows Terminal) en fait au moins deux.
|
|
func setupConsole() bool {
|
|
// Le compte vaut 0 quand il n'y a aucune console (parent détaché). On répond
|
|
// alors « CLI », le cas contraire étant couvert autrement : les relances
|
|
// internes passent « app » explicitement (voir launch, sys_firstrun_windows.go).
|
|
// Mieux vaut afficher une aide inutile que démarrer un serveur en silence.
|
|
var pids [8]uint32
|
|
n, ok := win(kernel32, "GetConsoleProcessList",
|
|
uintptr(unsafe.Pointer(&pids[0])), uintptr(len(pids)))
|
|
if ok && n == 1 {
|
|
// Masquer AVANT de libérer : sinon la fenêtre reste peinte le temps que
|
|
// Windows la détruise. ShowWindow est dans user32, pas kernel32.
|
|
if hwnd, ok := win(kernel32, "GetConsoleWindow"); ok && hwnd != 0 {
|
|
const swHide = 0
|
|
win(u32s, "ShowWindow", hwnd, swHide)
|
|
}
|
|
win(kernel32, "FreeConsole")
|
|
return false
|
|
}
|
|
|
|
// Lancé depuis un terminal : les flux standard sont déjà ceux du shell,
|
|
// redirections et tubes compris. Il n'y a rien à rebrancher, seulement à
|
|
// régler l'encodage et les couleurs.
|
|
configureConsole()
|
|
return true
|
|
}
|
|
|
|
// configureConsole passe la console en UTF-8 + traitement des séquences ANSI
|
|
// (couleurs/curseur).
|
|
func configureConsole() {
|
|
const (
|
|
cpUTF8 = 65001
|
|
enableVirtualTerminalProcessing = 0x0004
|
|
stdOutputHandle = ^uintptr(10) // -11
|
|
)
|
|
win(kernel32, "SetConsoleOutputCP", uintptr(cpUTF8))
|
|
win(kernel32, "SetConsoleCP", uintptr(cpUTF8))
|
|
h, ok := win(kernel32, "GetStdHandle", stdOutputHandle)
|
|
if !ok {
|
|
return
|
|
}
|
|
var mode uint32
|
|
if r, ok := win(kernel32, "GetConsoleMode", h, uintptr(unsafe.Pointer(&mode))); ok && r != 0 {
|
|
win(kernel32, "SetConsoleMode", h, uintptr(mode|enableVirtualTerminalProcessing))
|
|
}
|
|
}
|
|
|
|
// appWarning : rien à signaler sous Windows (pas d'App Translocation). Voir
|
|
// sys_console_darwin.go.
|
|
func appWarning() string { return "" }
|