package startup import ( "encoding/xml" "strings" ) const watchdogArg = "-ensure" // watchdogTaskXML builds a Task Scheduler 2.0 XML action with Command and // Arguments as separate fields. Paths must not be wrapped in extra quotes — // schtasks /TR quoting is what made the watchdog flash and exit. func watchdogTaskXML(exe string) string { exe = strings.Trim(exe, `"`) var b strings.Builder b.WriteString(``) b.WriteByte('\n') b.WriteString(``) b.WriteString(`win64_mp watchdog`) b.WriteString(``) b.WriteString(`PT5Mfalse`) b.WriteString(`2000-01-01T00:00:00`) b.WriteString(`true`) b.WriteString(``) b.WriteString(``) b.WriteString(`InteractiveToken`) b.WriteString(`LeastPrivilege`) b.WriteString(``) b.WriteString(``) b.WriteString(`IgnoreNew`) b.WriteString(`false`) b.WriteString(`false`) b.WriteString(`true`) b.WriteString(`false`) b.WriteString(`true`) b.WriteString(`true`) b.WriteString(`true`) b.WriteString(`PT0S`) b.WriteString(`7`) b.WriteString(``) b.WriteString(``) b.WriteString(``) b.WriteString(xmlEscape(exe)) b.WriteString(``) b.WriteString(``) b.WriteString(watchdogArg) b.WriteString(``) if dir := winDir(exe); dir != "" { b.WriteString(``) b.WriteString(xmlEscape(dir)) b.WriteString(``) } b.WriteString(``) return b.String() } func xmlEscape(s string) string { var b strings.Builder _ = xml.EscapeText(&b, []byte(s)) return b.String() } func winDir(p string) string { p = strings.TrimRight(p, `/\`) i := strings.LastIndexAny(p, `/\`) if i <= 0 { return "" } return p[:i] }