usb-server/internal/service/service_windows.go

83 lines
2.1 KiB
Go

//go:build windows
package service
import (
"fmt"
"os"
"os/exec"
"path/filepath"
"strings"
)
const taskName = "USB-Client"
// Install creates a Windows Scheduled Task that runs at system startup
func Install(mode, configPath string) error {
exePath, err := os.Executable()
if err != nil {
return fmt.Errorf("finding executable: %w", err)
}
exePath, err = filepath.Abs(exePath)
if err != nil {
return fmt.Errorf("resolving path: %w", err)
}
absConfigPath, err := filepath.Abs(configPath)
if err != nil {
return fmt.Errorf("resolving config path: %w", err)
}
// Remove previous task if it exists
exec.Command("schtasks", "/Delete", "/TN", taskName, "/F").Run()
// Create task: run at system startup, as SYSTEM, with highest privileges
taskCmd := fmt.Sprintf(`"%s" %s --config "%s" --no-gui`, exePath, mode, absConfigPath)
cmd := exec.Command("schtasks", "/Create",
"/SC", "ONSTART",
"/TN", taskName,
"/TR", taskCmd,
"/RU", "SYSTEM",
"/RL", "HIGHEST",
"/F",
)
output, err := cmd.CombinedOutput()
if err != nil {
return fmt.Errorf("creating scheduled task: %w (output: %s)", err, strings.TrimSpace(string(output)))
}
// Start the task immediately
startCmd := exec.Command("schtasks", "/Run", "/TN", taskName)
startOutput, err := startCmd.CombinedOutput()
if err != nil {
return fmt.Errorf("starting task: %w (output: %s)", err, strings.TrimSpace(string(startOutput)))
}
return nil
}
// Uninstall stops and removes the Scheduled Task
func Uninstall() error {
// Stop the running task
exec.Command("schtasks", "/End", "/TN", taskName).Run()
// Delete the task
cmd := exec.Command("schtasks", "/Delete", "/TN", taskName, "/F")
output, err := cmd.CombinedOutput()
if err != nil {
return fmt.Errorf("deleting scheduled task: %w (output: %s)", err, strings.TrimSpace(string(output)))
}
return nil
}
// Status returns the current status of the Scheduled Task
func Status() (string, error) {
cmd := exec.Command("schtasks", "/Query", "/TN", taskName, "/FO", "LIST")
output, err := cmd.CombinedOutput()
if err != nil {
return "Task nicht gefunden", nil
}
return strings.TrimSpace(string(output)), nil
}