diff --git a/Common/commonfunc.go b/Common/commonfunc.go index 1fcc22c..4e16fb5 100644 --- a/Common/commonfunc.go +++ b/Common/commonfunc.go @@ -4,9 +4,12 @@ import ( "crypto/md5" "encoding/hex" "encoding/json" + "errors" "fmt" "io" + "path/filepath" "runtime" + "syscall" "net" "os" @@ -1002,6 +1005,13 @@ func FormatTime(timeStr string) string { } func FormatTimes(now time.Time, format string) string { + + defer func() { + if r := recover(); r != nil { + log.Error("FormatTimes:", r) + } + }() + // 替换常见的日期时间格式标记 format = strings.ReplaceAll(format, "YYYY", "2006") format = strings.ReplaceAll(format, "YY", "06") @@ -1027,6 +1037,13 @@ func FormatTimes(now time.Time, format string) string { } func GetAvailableEndpoint() string { + + defer func() { + if r := recover(); r != nil { + log.Error("GetAvailableEndpoint:", r) + } + }() + primaryIP := LoadConfig().SeverData.ServerIP backupIP := LoadConfig().SeverData.BackUpServerIP // 替换为实际备选IP @@ -1040,6 +1057,12 @@ func GetAvailableEndpoint() string { } func IsIPReachable(ip string, port string) bool { + defer func() { + if r := recover(); r != nil { + log.Error("IsIPReachable:", r) + } + }() + var cmd *exec.Cmd // cmd := exec.Command("ping", "-c", "1", "-W", "1", ip) timeout := 100 // 毫秒 @@ -1053,3 +1076,104 @@ func IsIPReachable(ip string, port string) bool { } return false } + +func closeBrowser(cmd *exec.Cmd) { + if cmd == nil || cmd.Process == nil { + return + } + + // Windows系统 + if runtime.GOOS == "windows" { + kill := exec.Command("taskkill", "/F", "/T", "/PID", fmt.Sprint(cmd.Process.Pid)) + if err := kill.Run(); err != nil { + log.Printf("强制结束进程失败: %v", err) + } + } else { + // Unix-like系统 + if err := cmd.Process.Signal(syscall.SIGTERM); err != nil { + if err := cmd.Process.Kill(); err != nil { + log.Printf("强制结束进程失败: %v", err) + } + } + } +} + +func CloseChromeWindow(cmd *exec.Cmd) error { + defer func() { + if r := recover(); r != nil { + log.Error("closeChromeWindow:", r) + } + }() + cmd.Process.Kill() // 强制终止 + // 获取程序名称 + // programName := os.Args[0] // 使用当前程序的路径 + // 获取当前线程 ID + // pid := os.Getpid() + // fmt.Println(KillProcess) + // KillProcess(pid) + if cmd.Process == nil { + return errors.New("process not running") + } + + return nil +} + +func KillProcess(pid int) error { + + defer func() { + if r := recover(); r != nil { + log.Error("KillProcess:", r) + } + }() + + switch runtime.GOOS { + case "windows": + return exec.Command("taskkill", "/F", "/PID", strconv.Itoa(pid)).Run() + default: + proc, err := os.FindProcess(pid) + if err != nil { + return err + } + return proc.Kill() // 使用os包替代syscall + } +} + +func RestartSelf() error { + defer func() { + if r := recover(); r != nil { + log.Error("RestartSelf:", r) + } + }() + // 获取程序的完整路径 + exePath, err := filepath.Abs(os.Args[0]) // 获取当前程序的绝对路径 + if err != nil { + log.Fatalf("无法获取当前程序路径: %v", err) + } + + // 打印路径,检查是否正确 + log.Println("程序路径:", exePath) + + cmd := exec.Command(exePath, "--new-instance") // 添加启动参数 + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + + // 启动新实例 + if err := cmd.Start(); err != nil { + return err + } + + // 新进程启动后立即退出当前进程 + os.Exit(0) + return nil +} + +func ShowSimpleAlert(msg string) { + switch runtime.GOOS { + case "windows": + exec.Command("mshta", "javascript:alert('"+msg+"');close()").Start() + case "darwin": + exec.Command("osascript", "-e", "display alert \""+msg+"\"").Start() + case "linux": + exec.Command("zenity", "--info", "--text="+msg).Start() + } +} diff --git a/Device/FLXNetworkController/FlxNetworkCmdReader.go b/Device/FLXNetworkController/FlxNetworkCmdReader.go index 3513f91..adb1756 100644 --- a/Device/FLXNetworkController/FlxNetworkCmdReader.go +++ b/Device/FLXNetworkController/FlxNetworkCmdReader.go @@ -3,9 +3,12 @@ package FLXNetworkController import ( "bytes" "encoding/binary" + "flx/Common" + "flx/localcache" "fmt" "io/ioutil" "net" + "os" "os/exec" "runtime" "strconv" @@ -151,6 +154,23 @@ func (para *FlxNetworkCmdReader) UDPValidateRecvBuffer(packLen int, RecvBuffer [ cmd.Run() } + if PackBuff[0] == 0x7e && RecvBuffer[1] == 0x24 && RecvBuffer[2] == 0x07 { + Common.CloseChromeWindow(localcache.ChromeCmd) + os.Exit(0) + } + if PackBuff[0] == 0x7e && RecvBuffer[1] == 0x24 && RecvBuffer[2] == 0x06 { + + // Common.RestartSelf() + // 启动新程序 + programName := os.Args[0] + // programName := "d:\\workspace\\go\\src\\Door\\flx.exe" + cmd := exec.Command(programName, "--auto-restart") + if err := cmd.Start(); err != nil { + log.Printf("启动程序失败: %v", err) + } + Common.CloseChromeWindow(localcache.ChromeCmd) + } + if CRCBuff[0] != PackBuff[packLen-2] || CRCBuff[1] != PackBuff[packLen-1] { //InvokeOnDataReciveLogHandler(string.Format(FlxNetCCUConstantText.ReciveDataBufferImperfect_Error, "飞利信网口中控机")); //--写日志 return false diff --git a/frmScreen.go b/frmScreen.go index a8a3ce3..db68536 100644 --- a/frmScreen.go +++ b/frmScreen.go @@ -2,7 +2,7 @@ package main import ( "encoding/json" - "errors" + "flx/Common" "flx/DAL" "flx/Model" @@ -82,7 +82,6 @@ var SNoArriveNum int // ScreenWindow.Show() // go ReLocal() // } -var ChromeCmd *exec.Cmd func SMainWindowControl() { @@ -107,7 +106,7 @@ func SMainWindowControl() { url := "http://localhost:9999/screen/web/meetingview.html?id=" + doorName windowsize := Common.LoadConfig().CheckInDoor.Windowsize windowposition := Common.LoadConfig().CheckInDoor.Windowposition - ChromeCmd = exec.Command( + localcache.ChromeCmd = exec.Command( chromePath, // `C:\Program Files\Google\Chrome\Application\chrome.exe`, "--app="+url, // 使用 --app 参数,去掉 UI 控件 @@ -118,10 +117,10 @@ func SMainWindowControl() { "--window-position="+windowposition, // 设置窗口在第二个屏幕左上角 ) - if err := ChromeCmd.Start(); err != nil { + if err := localcache.ChromeCmd.Start(); err != nil { log.Fatal("Firefox launch failed:", err) } - fmt.Println("Firefox started with PID:", ChromeCmd.Process.Pid) + fmt.Println("Firefox started with PID:", localcache.ChromeCmd.Process.Pid) // w := webview.NewWindow(true, nil) // defer w.Destroy() @@ -162,39 +161,6 @@ func SMainWindowControl() { // go ReLocal() } -func closeChromeWindow(cmd *exec.Cmd) error { - defer func() { - if r := recover(); r != nil { - log.Error("closeChromeWindow:", r) - } - }() - cmd.Process.Kill() // 强制终止 - // 获取程序名称 - // programName := os.Args[0] // 使用当前程序的路径 - // 获取当前线程 ID - pid := os.Getpid() - fmt.Println(KillProcess) - KillProcess(pid) - if cmd.Process == nil { - return errors.New("process not running") - } - - return nil -} - -func KillProcess(pid int) error { - switch runtime.GOOS { - case "windows": - return exec.Command("taskkill", "/F", "/PID", strconv.Itoa(pid)).Run() - default: - proc, err := os.FindProcess(pid) - if err != nil { - return err - } - return proc.Kill() // 使用os包替代syscall - } -} - type Chrome struct { Path string } diff --git a/localcache/CongressCtrlCenter.go b/localcache/CongressCtrlCenter.go index 856524d..0f19699 100644 --- a/localcache/CongressCtrlCenter.go +++ b/localcache/CongressCtrlCenter.go @@ -7,6 +7,7 @@ import ( "flx/Model" "flx/websocketservers" "fmt" + "os/exec" "reflect" "sort" "strconv" @@ -130,6 +131,8 @@ var MScreenData = make(map[string]map[string]interface{}) // 照片列表人员信息 var Allperpiccontent []map[string]interface{} +var ChromeCmd *exec.Cmd + func TacitScreen(parametermap map[string]interface{}) (resultmap map[string]interface{}) { defer func() { diff --git a/main.go b/main.go index 0fcd5ac..fb0cbf3 100644 --- a/main.go +++ b/main.go @@ -15,6 +15,8 @@ import ( "fmt" "image/color" "io" + "os/exec" + "runtime" "sync" "math" @@ -208,6 +210,51 @@ func main() { log.Error("main:", r) } }() + //登陆的时候看是否有相同的进程,如果是鼠标点击打开的弹窗提示,如果是通过命令打开的杀掉当前的。 + + if len(os.Args) > 1 && os.Args[1] == "--auto-restart" { + fmt.Println("程序由命令行自动重启") + + // 获取程序名称 + programName := os.Args[0] // 使用当前程序的路径 + // 获取当前线程 ID + pid := os.Getpid() + fmt.Println(pid) + // 查找是否有相同进程正在运行 + + // D:\workspace\go\src\Door\flx.exe + // programName = "d:\\workspace\\go\\src\\Door\\flx.exe" + + runningProc, err := findProcessByName(programName[strings.LastIndex(programName, "\\")+1:]) + if err != nil { + log.Println("Error while checking running process: %v", err) + fmt.Println("Error while checking running process: %v", err) + } + fmt.Println("-----------------------------------------------") + log.Error("main:", programName) + fmt.Println(programName) + // 如果进程已经在运行,关闭它 + if runningProc != nil { + if runningProc.Pid != pid { + + fmt.Println("==========================================================") + fmt.Println("Process %s is already running, attempting to kill it...\n", programName) + err = killProcess(runningProc) + if err != nil { + log.Fatalf("Failed to kill process: %v", err) + } + + // 等待旧进程关闭 + time.Sleep(2 * time.Second) // 等待进程关闭的时间,具体时间可根据情况调整 + fmt.Println("Process %s terminated. Proceeding to start new instance...\n", programName) + } + } + fmt.Println("+++++++++++++++++++++++++++++++++++++++++++++++") + + } else { + fmt.Println("程序由用户手动启动") + // Common.ShowSimpleAlert("程序已启动") + } Common.InitLog("./log/", "", "gb18030") log.WithFields(log.Fields{"animal": "walrus"}).Info("A walrus appears") @@ -312,7 +359,7 @@ func MainWindowControl() { MainWindow.SetCloseIntercept(func() { fmt.Println("正在执行自定义操作...") // 此处添加业务逻辑 - closeChromeWindow(ChromeCmd) + Common.CloseChromeWindow(localcache.ChromeCmd) MainWindow.Close() }) @@ -628,7 +675,7 @@ func DefaultLayout() fyne.CanvasObject { btnPersonManage.Move(fyne.NewPos(1400*BigPara, 1000*BigPara)) //退出 btnClose := widget.NewButton("退出", func() { - closeChromeWindow(ChromeCmd) + Common.CloseChromeWindow(localcache.ChromeCmd) MainWindow.Close() // GPersonlist.Refresh() }) @@ -1150,7 +1197,7 @@ func ReportLayout() fyne.CanvasObject { SetCongressStatus(3) } else { MainWindow.Close() - closeChromeWindow(ChromeCmd) + Common.CloseChromeWindow(localcache.ChromeCmd) } }) btnRClose.Resize(fyne.NewSize(200*BigPara, 50*BigPara)) @@ -1630,35 +1677,43 @@ func OnDeviceEventHandler(eventSource FLXDevice.EventArgSource, eventType FLXDev } } // OnCheckInOne(person) - - // case FlxNetworkComPara.Data_Down_Control: - // switch (arg.Value_ExtraInt){ - // case FlxNetworkComPara.Data_Down_ControlShutDown://关机 - // WindowsContols.PowerOff(); - // break; - // case FlxNetworkComPara.Data_Down_ControlRestart://重启 - // WindowsContols.Reboot(); - // break; - // case FlxNetworkComPara.CMD_Control_RestartProgram://软件重启 - // PaperNetCtrler.StopClient(); - // Process p = new Process(); - // p.StartInfo.FileName = System.AppDomain.CurrentDomain.BaseDirectory + "Philisense.Congress.CheckInDoor.exe"; - // p.StartInfo.UseShellExecute = false; - // p.Start(); - // break; - // case FlxNetworkComPara.Data_Down_BarSub_Hide://隐藏 - // WindowsContols.HideTaskBar(); - // break; - // case FlxNetworkComPara.Data_Down_BarSub_Show://显示 - // WindowsContols.ShowTaskBar(); - // break; - // case FlxNetworkComPara.CMD_Control_ExitProgram://软件关闭 - // Process Current = Process.GetCurrentProcess(); - // Process processesByID = Process.GetProcessById(Current.Id); - // processesByID.Kill(); - // break; - - // } + case FLXNetworkController.FlxNetworkComPara_Data_Down_ControlShutDown: //关机 + var cmd *exec.Cmd + if runtime.GOOS == "windows" { + cmd = exec.Command("shutdown", "/s", "/t", "0") + } else { + cmd = exec.Command("shutdown", "-h", "now") + } + cmd.Run() + break + // case FLXNetworkController.Data_Down_Control: + // switch arg.Value_ExtraInt { + // case FlxNetworkComPara.Data_Down_ControlShutDown: //关机 + // WindowsContols.PowerOff() + // break + // case FlxNetworkComPara.Data_Down_ControlRestart: //重启 + // WindowsContols.Reboot() + // break + // case FlxNetworkComPara.CMD_Control_RestartProgram: //软件重启 + // // PaperNetCtrler.StopClient(); + // // Process p = new Process(); + // // p.StartInfo.FileName = System.AppDomain.CurrentDomain.BaseDirectory + "Philisense.Congress.CheckInDoor.exe"; + // // p.StartInfo.UseShellExecute = false; + // // p.Start(); + // // break; + // case FlxNetworkComPara.Data_Down_BarSub_Hide: //隐藏 + // WindowsContols.HideTaskBar() + // break + // case FlxNetworkComPara.Data_Down_BarSub_Show: //显示 + // WindowsContols.ShowTaskBar() + // break + // case FlxNetworkComPara.CMD_Control_ExitProgram: //软件关闭 + // // Process Current = Process.GetCurrentProcess(); + // // Process processesByID = Process.GetProcessById(Current.Id); + // // processesByID.Kill(); + // // break; + + // } } } }