//go:build windows package cafegame import ( "os" "path/filepath" "sync" "time" ) // ProcessMonitor 单个游戏进程的监视器:等待进程退出后向 waitChan 发送结果 type ProcessMonitor struct { pid int exeName string exePath string AppData status int waitChan chan AppWaitData } // NewProcessMonitor 创建进程监视器 func NewProcessMonitor(pid int, exePath string, app AppData, waitChan chan AppWaitData) *ProcessMonitor { process := new(ProcessMonitor) process.pid = pid process.exeName = filepath.Base(exePath) process.exePath = exePath process.waitChan = waitChan process.AppData = app return process } // monitor 阻塞等待进程退出 func (receiver *ProcessMonitor) monitor() error { defer func() { receiver.waitChan <- AppWaitData{Pid: receiver.pid, AppData: receiver.AppData} }() process, err := os.FindProcess(receiver.pid) if err != nil { // 查找进程失败 return err } _, err = process.Wait() if err != nil { //"进程运行错误 return err } // 进程已经结束 return nil } // Start 在后台协程中开始监视进程 func (receiver *ProcessMonitor) Start() { go receiver.monitor() } // AppMonitor 单个游戏的监控器:聚合该游戏的所有进程 type AppMonitor struct { AppData processList []*ProcessMonitor mux sync.Mutex waitChan chan AppWaitData recordId int startTime int64 } // NewAppMonitor 创建游戏监控器 func NewAppMonitor(app AppData, path string, waitChan chan AppWaitData) *AppMonitor { monitor := new(AppMonitor) monitor.AppData = app monitor.waitChan = waitChan monitor.startTime = time.Now().Unix() return monitor } // AddProcess 添加该游戏的一个进程(之前无进程时重置开始时间) func (receiver *AppMonitor) AddProcess(pid int, exePath string) { receiver.mux.Lock() defer receiver.mux.Unlock() // 没有进程,重新设置开始时间为当前时间 if len(receiver.processList) == 0 { receiver.startTime = time.Now().Unix() } process := NewProcessMonitor(pid, exePath, receiver.AppData, receiver.waitChan) process.Start() receiver.processList = append(receiver.processList, process) } // RemoveProcess 移除指定 PID 的进程 func (receiver *AppMonitor) RemoveProcess(pid int) { receiver.mux.Lock() defer receiver.mux.Unlock() for i := 0; i < len(receiver.processList); i++ { if pid == receiver.processList[i].pid { receiver.processList = append(receiver.processList[0:i], receiver.processList[i+1:]...) i-- } } } // AppIsRun 该游戏是否仍有进程在运行 func (receiver *AppMonitor) AppIsRun() bool { receiver.mux.Lock() defer receiver.mux.Unlock() return len(receiver.processList) > 0 } // GetStartInterval 返回游戏开始运行至今的秒数 func (receiver *AppMonitor) GetStartInterval() int64 { receiver.mux.Lock() defer receiver.mux.Unlock() now := time.Now().Unix() interval := now - receiver.startTime return interval }