//go:build windows package main // notify_windows.go — M8-4 R5-D1:Windows OS 原生通知 // // 優先用 PowerShell + BurntToast 模組(原生系統 toast); // 若沒裝 BurntToast → fallback 到 `msg *`(老派但無需額外模組)。 // // TDD ground truth: // - .autoflow/04-architecture/v2/server-lifecycle.md §10.4 import ( "fmt" "os" "os/exec" "strings" ) // sendCrashNotification 發一則 OS 原生通知。非阻塞、fire-and-forget。 func sendCrashNotification(title, body string) { psScript := fmt.Sprintf(` if (Get-Module -ListAvailable -Name BurntToast) { Import-Module BurntToast -ErrorAction SilentlyContinue New-BurntToastNotification -Text '%s','%s' -AppLogo '' } else { # 若沒裝 BurntToast 模組,直接用老派 msg * 廣播 msg * /TIME:10 "%s - %s" } `, escapePSString(title), escapePSString(body), escapePSString(title), escapePSString(body)) cmd := exec.Command("powershell", "-NoProfile", "-NonInteractive", "-Command", psScript) configureSysProcAttr(cmd) // 沿用現有的 hide-window flag if err := cmd.Run(); err != nil { fmt.Fprintf(os.Stderr, "[notify] powershell notify failed: %v\n", err) } } // escapePSString 對 PowerShell 單引號字串做 escape。 // 在 PS 中單引號字串裡要表示單引號需要連寫兩個 ''。 func escapePSString(s string) string { return strings.ReplaceAll(s, "'", "''") }