feat(windows): add windows boot service support

- Add registry-based boot service creation for Windows
- Update detectInitSystem to handle Windows platform
This commit is contained in:
2026-03-04 22:17:56 +08:00
parent 29011c2fb4
commit 541f881825
3 changed files with 55 additions and 4 deletions
+6
View File
@@ -56,6 +56,12 @@ GOOS=linux GOARCH=amd64 go build -o super-frpc
For detailed API documentation, please see [docs/api.md](docs/api.md)
## TODO
- [x] Add Windows boot service support
- [ ] Add session management API
- [ ] Add codes per file documentation
## License
GPL-3.0
BIN
View File
Binary file not shown.
+45
View File
@@ -6,7 +6,10 @@ import (
"os"
"os/exec"
"path/filepath"
"runtime"
"super-frpc/postLog"
"golang.org/x/sys/windows/registry"
)
func GetConfigDir() (string, error) {
@@ -28,12 +31,17 @@ func GetFrpcPath() (string, error) {
}
func detectInitSystem() string {
if runtime.GOOS == "windows" {
return "windows"
}
if runtime.GOOS == "linux" {
if _, err := os.Stat("/run/systemd/system"); err == nil {
return "systemd"
}
if _, err := os.Stat("/etc/init.d"); err == nil {
return "init.d"
}
}
return "unknown"
}
@@ -45,6 +53,8 @@ func createBootService(username, instanceName, configPath, runUser string) error
return createSystemdService(username, instanceName, configPath, runUser)
case "init.d":
return createInitDService(username, instanceName, configPath, runUser)
case "windows":
return createWindowsBootService(username, instanceName, configPath)
default:
return errors.New("unsupported init system")
}
@@ -221,6 +231,28 @@ exit 0
return nil
}
func createWindowsBootService(username, instanceName, configPath string) error {
frpcPath, err := GetFrpcPath()
if err != nil {
return err
}
serviceName := fmt.Sprintf("superfrpc_%s_%s", username, instanceName)
command := fmt.Sprintf("\"%s\" -c \"%s\"", frpcPath, configPath)
key, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows\CurrentVersion\Run`, registry.WRITE|registry.WOW64_64KEY)
if err != nil {
return fmt.Errorf("failed to open registry key: %w", err)
}
defer key.Close()
if err := key.SetStringValue(serviceName, command); err != nil {
return fmt.Errorf("failed to set registry value: %w", err)
}
return nil
}
func removeBootService(username, instanceName string) error {
initSystem := detectInitSystem()
@@ -243,6 +275,19 @@ func removeBootService(username, instanceName string) error {
servicePath := filepath.Join("/etc/init.d", serviceName)
os.Remove(servicePath)
case "windows":
key, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows\CurrentVersion\Run`, registry.WRITE|registry.WOW64_64KEY)
if err != nil {
postLog.Error(fmt.Sprintf("[removeBootService] Failed to open registry key: %v", err))
} else {
defer key.Close()
if err := key.DeleteValue(serviceName); err != nil {
postLog.Error(fmt.Sprintf("[removeBootService] Failed to delete registry value: %v", err))
}
}
default:
postLog.Error(fmt.Sprintf("[removeBootService] Unsupported init system: %s", initSystem))
}
return nil