package main;
 
import (
    "github.com/fsnotify/fsnotify"
    "log"
    "fmt"
    "os/exec"
    "regexp"
    "strconv"
    "bytes"
    "errors"
    "os"
    "path/filepath"
)
 
const (
    confFilePath = "./conf";
)
 
//获取进程ID
func getPid(processName string) (int, error) {
    //通过wmic process get name,processid | findstr server.exe获取进程ID
    buf := bytes.Buffer{};
    cmd := exec.Command("wmic", "process", "get", "name,processid");
    cmd.Stdout = &buf;
    cmd.Run();
    cmd2 := exec.Command("findstr", processName);
    cmd2.Stdin = &buf;
    data, _ := cmd2.CombinedOutput();
    iflen(data) == 0 {
        return-1, errors.New("not find");
    }
    info := string(data);
    //这里通过正则把进程id提取出来
    reg := regexp.MustCompile(`[0-9]+`);
    pid := reg.FindString(info);
    returnstrconv.Atoi(pid);
}
 
//启动进程
func startProcess(exePath string, args []string) error {
    attr := &os.ProcAttr{
        //files指定新进程继承的活动文件对象
        //前三个分别为,标准输入、标准输出、标准错误输出
        Files: []*os.File{os.Stdin, os.Stdout, os.Stderr},
        //新进程的环境变量
        Env: os.Environ(),
    }
 
    p, err := os.StartProcess(exePath, args, attr);
    iferr != nil {
        returnerr;
    }
    fmt.Println(exePath, "进程启动");
    p.Wait();
    returnnil;
}
 
func main() {
    //创建一个监控对象
    watch, err := fsnotify.NewWatcher();
    iferr != nil {
        log.Fatal(err);
    }
    defer watch.Close();
    //添加要监控的文件
    err = watch.Add(confFilePath);
    iferr != nil {
        log.Fatal(err);
    }
    //我们另启一个goroutine来处理监控对象的事件
    go func() {
        for{
            select {
            caseev := <-watch.Events:
                {
                    //我们只需关心文件的修改
                    ifev.Op&fsnotify.Write == fsnotify.Write {
                        fmt.Println(ev.Name, "文件写入");
                        //查找进程
                        pid, err := getPid("server.exe");
                        //获取运行文件的绝对路径
                        exePath, _ := filepath.Abs("./server.exe")
                        iferr != nil {
                            //启动进程
                            go startProcess(exePath, []string{});
                        } else{
                            //找到进程,并退出
                            process, err := os.FindProcess(pid);
                            iferr == nil {
                                //让进程退出
                                process.Kill();
                                fmt.Println(exePath, "进程退出");
                            }
                            //启动进程
                            go startProcess(exePath, []string{});
                        }
                    }
                }
            caseerr := <-watch.Errors:
                {
                    fmt.Println("error : ", err);
                    return;
                }
            }
        }
    }();
 
    //循环
    select {};
}