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)
|
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
|
## License
|
||||||
|
|
||||||
GPL-3.0
|
GPL-3.0
|
||||||
|
|||||||
BIN
Binary file not shown.
@@ -6,7 +6,10 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
"super-frpc/postLog"
|
"super-frpc/postLog"
|
||||||
|
|
||||||
|
"golang.org/x/sys/windows/registry"
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetConfigDir() (string, error) {
|
func GetConfigDir() (string, error) {
|
||||||
@@ -28,11 +31,16 @@ func GetFrpcPath() (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func detectInitSystem() string {
|
func detectInitSystem() string {
|
||||||
if _, err := os.Stat("/run/systemd/system"); err == nil {
|
if runtime.GOOS == "windows" {
|
||||||
return "systemd"
|
return "windows"
|
||||||
}
|
}
|
||||||
if _, err := os.Stat("/etc/init.d"); err == nil {
|
if runtime.GOOS == "linux" {
|
||||||
return "init.d"
|
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"
|
return "unknown"
|
||||||
}
|
}
|
||||||
@@ -45,6 +53,8 @@ func createBootService(username, instanceName, configPath, runUser string) error
|
|||||||
return createSystemdService(username, instanceName, configPath, runUser)
|
return createSystemdService(username, instanceName, configPath, runUser)
|
||||||
case "init.d":
|
case "init.d":
|
||||||
return createInitDService(username, instanceName, configPath, runUser)
|
return createInitDService(username, instanceName, configPath, runUser)
|
||||||
|
case "windows":
|
||||||
|
return createWindowsBootService(username, instanceName, configPath)
|
||||||
default:
|
default:
|
||||||
return errors.New("unsupported init system")
|
return errors.New("unsupported init system")
|
||||||
}
|
}
|
||||||
@@ -221,6 +231,28 @@ exit 0
|
|||||||
return nil
|
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 {
|
func removeBootService(username, instanceName string) error {
|
||||||
initSystem := detectInitSystem()
|
initSystem := detectInitSystem()
|
||||||
|
|
||||||
@@ -243,6 +275,19 @@ func removeBootService(username, instanceName string) error {
|
|||||||
|
|
||||||
servicePath := filepath.Join("/etc/init.d", serviceName)
|
servicePath := filepath.Join("/etc/init.d", serviceName)
|
||||||
os.Remove(servicePath)
|
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
|
return nil
|
||||||
|
|||||||
Reference in New Issue
Block a user