mirror of https://gitee.com/godoos/godoos.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
149 lines
3.2 KiB
149 lines
3.2 KiB
package progress
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"godo/deps"
|
|
"godo/libs"
|
|
"log"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"runtime"
|
|
"sync"
|
|
)
|
|
|
|
type Process struct {
|
|
Name string
|
|
Running bool
|
|
ExitCode int
|
|
Cmd *exec.Cmd
|
|
}
|
|
|
|
var (
|
|
processesMu sync.RWMutex
|
|
processes = make(map[string]*Process)
|
|
)
|
|
|
|
func RegisterProcess(name string, cmdstr *exec.Cmd) {
|
|
processesMu.Lock()
|
|
defer processesMu.Unlock()
|
|
processes[name] = &Process{
|
|
Name: name,
|
|
Running: true,
|
|
Cmd: cmdstr,
|
|
}
|
|
}
|
|
func GetCmd(name string) *Process {
|
|
processesMu.Lock()
|
|
defer processesMu.Unlock()
|
|
return processes[name]
|
|
}
|
|
|
|
// StartCmd 执行指定名称的脚本。
|
|
// 参数:
|
|
// name - 脚本的名称。
|
|
// 返回值:
|
|
// 返回可能遇到的错误,如果执行成功,则返回nil。
|
|
func StartCmd(name string) error {
|
|
info, ok := processes[name]
|
|
if ok && info.Running {
|
|
return fmt.Errorf("process information for '%s' is runing", name)
|
|
}
|
|
|
|
path := name
|
|
appName := name
|
|
scriptPath, err := libs.GetCmdPath(path, name)
|
|
if err != nil {
|
|
// 不存在,解压应用
|
|
switch name {
|
|
case deps.FRPCAPP:
|
|
appName = deps.FRPCAPP
|
|
default:
|
|
return errors.New("app not found")
|
|
}
|
|
err = deps.ExtractZip(appName, libs.GetAppExecDir())
|
|
if err != nil {
|
|
return fmt.Errorf("failed to extract zip file: %v", err)
|
|
}
|
|
}
|
|
|
|
// 设置并启动脚本执行命令
|
|
var cmd *exec.Cmd
|
|
switch name {
|
|
case "frpc":
|
|
// 检查配置文件
|
|
configPath := filepath.Join(libs.GetAppExecDir(), appName, "frpc.ini")
|
|
if !libs.PathExists(configPath) {
|
|
return fmt.Errorf("frpc config file not found")
|
|
}
|
|
|
|
params := []string{
|
|
"-c",
|
|
configPath,
|
|
}
|
|
cmd = exec.Command(scriptPath, params...)
|
|
default:
|
|
cmd = exec.Command(scriptPath)
|
|
}
|
|
|
|
if runtime.GOOS == "windows" {
|
|
// 在Windows上,通过设置CreationFlags来隐藏窗口
|
|
cmd = SetHideConsoleCursor(cmd)
|
|
}
|
|
go func() {
|
|
// 启动脚本命令并返回可能的错误
|
|
if err := cmd.Start(); err != nil {
|
|
log.Printf("failed to start process %s: %v", name, err)
|
|
return
|
|
}
|
|
RegisterProcess(name, cmd)
|
|
// 等待命令完成
|
|
if err := cmd.Wait(); err != nil {
|
|
log.Printf("command failed for %s: %v", name, err)
|
|
return
|
|
} else {
|
|
log.Printf("%s command completed successfully", name)
|
|
}
|
|
|
|
// 命令完成后,更新进程信息
|
|
processesMu.Lock()
|
|
defer processesMu.Unlock()
|
|
if p, ok := processes[name]; ok {
|
|
p.Running = false
|
|
p.ExitCode = cmd.ProcessState.ExitCode()
|
|
}
|
|
}()
|
|
return nil
|
|
}
|
|
func StopCmd(name string) error {
|
|
cmd, ok := processes[name]
|
|
if !ok {
|
|
return fmt.Errorf("process information for '%s' not found", name)
|
|
}
|
|
|
|
// 停止进程并更新status
|
|
if err := cmd.Cmd.Process.Kill(); err != nil {
|
|
return fmt.Errorf("failed to kill process %s: %v", name, err)
|
|
}
|
|
//delete(processes, name) // 更新status,表示进程已停止
|
|
cmd.Running = false
|
|
return nil
|
|
}
|
|
func RestartCmd(name string) error {
|
|
if err := StopCmd(name); err != nil {
|
|
return err
|
|
}
|
|
return StartCmd(name)
|
|
}
|
|
func StopAllCmd() error {
|
|
processesMu.Lock()
|
|
defer processesMu.Unlock()
|
|
|
|
for name, cmd := range processes {
|
|
if err := cmd.Cmd.Process.Signal(os.Interrupt); err != nil {
|
|
return fmt.Errorf("failed to stop process %s: %v", name, err)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|