2024-01-29 21:55:01 +01:00
|
|
|
package admin_service
|
|
|
|
|
|
|
|
|
|
import (
|
2024-02-02 13:47:41 +01:00
|
|
|
"fmt"
|
2024-01-29 21:55:01 +01:00
|
|
|
"log"
|
2024-02-02 13:47:41 +01:00
|
|
|
"os"
|
|
|
|
|
"path/filepath"
|
2024-01-29 21:55:01 +01:00
|
|
|
|
|
|
|
|
"github.com/hiddify/libcore/global"
|
|
|
|
|
"github.com/kardianos/service"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var logger service.Logger
|
|
|
|
|
|
|
|
|
|
type hiddifyNext struct{}
|
|
|
|
|
|
|
|
|
|
var port int = 18020
|
|
|
|
|
|
|
|
|
|
func (m *hiddifyNext) Start(s service.Service) error {
|
|
|
|
|
go m.run()
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
func (m *hiddifyNext) Stop(s service.Service) error {
|
2024-02-02 13:47:41 +01:00
|
|
|
err := global.StopServiceC()
|
2024-01-29 21:55:01 +01:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
// Stop should not block. Return with a few seconds.
|
|
|
|
|
// <-time.After(time.Second * 1)
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
func (m *hiddifyNext) run() {
|
|
|
|
|
StartWebServer(port, false)
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-02 13:47:41 +01:00
|
|
|
func getCurrentExecutableDirectory() string {
|
|
|
|
|
executablePath, err := os.Executable()
|
|
|
|
|
if err != nil {
|
|
|
|
|
return ""
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Extract the directory (folder) containing the executable
|
|
|
|
|
executableDirectory := filepath.Dir(executablePath)
|
|
|
|
|
|
|
|
|
|
return executableDirectory
|
|
|
|
|
}
|
|
|
|
|
func StartService(goArg string) (int, string) {
|
2024-01-29 21:55:01 +01:00
|
|
|
svcConfig := &service.Config{
|
|
|
|
|
Name: "Hiddify Tunnel Service",
|
|
|
|
|
DisplayName: "Hiddify Tunnel Service",
|
|
|
|
|
Description: "This is a bridge for tunnel",
|
2024-02-02 13:47:41 +01:00
|
|
|
Option: map[string]interface{}{
|
|
|
|
|
"RunAtLoad": true,
|
|
|
|
|
"WorkingDirectory": getCurrentExecutableDirectory(),
|
|
|
|
|
},
|
2024-01-29 21:55:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
prg := &hiddifyNext{}
|
|
|
|
|
s, err := service.New(prg, svcConfig)
|
|
|
|
|
if err != nil {
|
2024-02-02 13:47:41 +01:00
|
|
|
// log.Printf("Error: %v", err)
|
|
|
|
|
return 1, fmt.Sprintf("Error: %v", err)
|
2024-01-29 21:55:01 +01:00
|
|
|
}
|
|
|
|
|
|
2024-02-02 13:47:41 +01:00
|
|
|
if len(goArg) > 0 {
|
|
|
|
|
return control(s, goArg)
|
2024-01-29 21:55:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
logger, err = s.Logger(nil)
|
|
|
|
|
if err != nil {
|
2024-02-02 13:47:41 +01:00
|
|
|
log.Printf("Error: %v", err)
|
2024-01-29 21:55:01 +01:00
|
|
|
}
|
|
|
|
|
err = s.Run()
|
|
|
|
|
if err != nil {
|
|
|
|
|
logger.Error(err)
|
2024-02-02 13:47:41 +01:00
|
|
|
return 3, fmt.Sprintf("Error: %v", err)
|
2024-01-29 21:55:01 +01:00
|
|
|
}
|
2024-02-02 13:47:41 +01:00
|
|
|
return 0, ""
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func control(s service.Service, goArg string) (int, string) {
|
|
|
|
|
dolog := false
|
|
|
|
|
var err error
|
|
|
|
|
status, serr := s.Status()
|
|
|
|
|
if dolog {
|
|
|
|
|
fmt.Printf("Current Status: %+v %+v!\n", status, serr)
|
|
|
|
|
}
|
|
|
|
|
switch goArg {
|
|
|
|
|
case "uninstall":
|
|
|
|
|
if status == service.StatusRunning {
|
|
|
|
|
s.Stop()
|
|
|
|
|
}
|
|
|
|
|
if dolog {
|
|
|
|
|
fmt.Printf("Tunnel Service Uninstalled Successfully.\n")
|
|
|
|
|
}
|
|
|
|
|
err = s.Uninstall()
|
|
|
|
|
case "start":
|
|
|
|
|
if status == service.StatusRunning {
|
|
|
|
|
if dolog {
|
|
|
|
|
fmt.Printf("Tunnel Service Already Running.\n")
|
|
|
|
|
}
|
|
|
|
|
return 0, "Tunnel Service Already Running."
|
|
|
|
|
} else if status == service.StatusUnknown {
|
|
|
|
|
s.Install()
|
|
|
|
|
status, serr = s.Status()
|
|
|
|
|
if dolog {
|
|
|
|
|
fmt.Printf("Check status again: %+v %+v!", status, serr)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if status != service.StatusRunning {
|
|
|
|
|
err = s.Start()
|
|
|
|
|
}
|
|
|
|
|
case "install":
|
|
|
|
|
err = s.Install()
|
|
|
|
|
status, serr = s.Status()
|
|
|
|
|
if dolog {
|
|
|
|
|
fmt.Printf("Check Status Again: %+v %+v", status, serr)
|
|
|
|
|
}
|
|
|
|
|
if status != service.StatusRunning {
|
|
|
|
|
err = s.Start()
|
|
|
|
|
}
|
|
|
|
|
case "stop":
|
|
|
|
|
if status == service.StatusStopped {
|
|
|
|
|
if dolog {
|
|
|
|
|
fmt.Printf("Tunnel Service Already Stopped.\n")
|
|
|
|
|
}
|
|
|
|
|
return 0, "Tunnel Service Already Stopped."
|
|
|
|
|
}
|
|
|
|
|
err = s.Stop()
|
|
|
|
|
default:
|
|
|
|
|
err = service.Control(s, goArg)
|
|
|
|
|
}
|
|
|
|
|
if err == nil {
|
|
|
|
|
out := fmt.Sprintf("Tunnel Service %sed Successfully.", goArg)
|
|
|
|
|
if dolog {
|
|
|
|
|
fmt.Printf(out)
|
|
|
|
|
}
|
|
|
|
|
return 0, out
|
|
|
|
|
} else {
|
|
|
|
|
out := fmt.Sprintf("Error: %v", err)
|
|
|
|
|
if dolog {
|
|
|
|
|
log.Printf(out)
|
|
|
|
|
}
|
|
|
|
|
return 2, out
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-29 21:55:01 +01:00
|
|
|
}
|