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:
@@ -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
Binary file not shown.
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user