// +build windows // +build 386 package main import ( "fmt" "github.com/lxn/walk" . "github.com/lxn/walk/declarative" "github.com/lxn/win" "golang.org/x/sys/windows" "golang.org/x/sys/windows/registry" "os/exec" "syscall" "time" ) type myApp struct { title string msg *walk.TextEdit mw *walk.MainWindow } type myService struct { text string serviceName string labelState *walk.Label btnRegister *walk.PushButton btnStart *walk.PushButton btnStop *walk.PushButton } var app myApp var service1, service3 myService var path string func init() { app.title = "公务员管理系统-运行监控" service1 = myService{ text: "数据存储库", serviceName: "GWY20_Mysql", } service3 = myService{ text: "消防系统", serviceName: "GWY20_Tomcat", } path = `D:\hzb2021` } func main() { _ = getWindows() walk.App().SetProductName(app.title) walk.App().SetOrganizationName("网新") _ = service1.labelState.SetText("未安装") _ = service3.labelState.SetText("未安装") service1.btnRegister.Clicked().Attach(func() { registerService(service1) }) service1.btnStart.Clicked().Attach(func() { startService(service1) }) service1.btnStop.Clicked().Attach(func() { stopService(service1) }) service3.btnRegister.Clicked().Attach(func() { registerService(service3) }) service3.btnStart.Clicked().Attach(func() { startService(service3) }) service3.btnStop.Clicked().Attach(func() { stopService(service3) }) go flushServiceStat(service1) go flushServiceStat(service3) app.mw.Show() app.mw.Run() } func setServiceState(service myService, msg string, btnStartStatus, btnStopStatus, btnRegisterStatus bool) { _ = service.labelState.SetText(msg) service.btnStart.SetEnabled(btnStartStatus) service.btnStop.SetEnabled(btnStopStatus) service.btnRegister.SetEnabled(btnRegisterStatus) } // 刷新服务状态的协程程序 func flushServiceStat(service myService) { for { winService, err := NewWinService(service.serviceName) if winService == nil || err != nil { if err == windows.ERROR_SERVICE_DOES_NOT_EXIST { setServiceState(service, "未安装", false, false, true) } else { setServiceState(service, "服务打开失败", false, false, false) } } else { if winService.IsStop() { setServiceState(service, "已经停止", true, false, false) } else if winService.IsRunning() { setServiceState(service, "正在运行", false, true, false) } } time.Sleep(time.Second) } } // 注册服务 func registerService(service myService) { if service.serviceName == "GWY20_Mysql" { // 注册 MYSQL 服务 registerWindows(service.serviceName, `SYSTEM\ControlSet001\Services\GWY20_Mysql`, `LocalSystem`, `GWY20_Mysql`, fmt.Sprintf(`%s\mysql\bin\mysqld GWY20_Mysql`, path)) registerWindows(service.serviceName, `SYSTEM\CurrentControlSet\Services\GWY20_Mysql`, `LocalSystem`, `GWY20_Mysql`, fmt.Sprintf(`%s\mysql\bin\mysqld --defaults-file=%smysql\my.ini GWY20_Mysql`, path, path)) } else { // 注册 TOMCAT 服务 registerWindows(service.serviceName, `SYSTEM\ControlSet001\Services\GWY20_Tomcat`, `NT Authority\LocalService`, `GWY20_Tomcat`, fmt.Sprintf(`%s\tomcat8\bin\Tomcat8.exe //RS//GWY20_Tomcat`, path)) registerWindows(service.serviceName, `SYSTEM\CurrentControlSet\Services\GWY20_Tomcat`, `NT Authority\LocalService`, `GWY20_Tomcat`, fmt.Sprintf(`%s\tomcat8\bin\Tomcat8.exe //RS//GWY20_Tomcat`, path)) registerJava(service.serviceName, path) registerLog(service.serviceName, path) registerState(service.serviceName, `SOFTWARE\WOW6432Node\Apache Software Foundation\Procrun 2.0\GWY20_Tomcat\Parameters\Start`, `start`, path) registerState(service.serviceName, `SOFTWARE\WOW6432Node\Apache Software Foundation\Procrun 2.0\GWY20_Tomcat\Parameters\Stop`, `stop`, path) } showMsg(service.serviceName + " 服务注册成功!") } // 启动服务 func startService(service myService) { s, err := NewWinService(service.serviceName) if s == nil || err != nil { return } showMsg(service.serviceName + " 服务开始启动......") err = s.StartService() if err != nil { showMsg(service.serviceName + " 服务启动失败!") } else { showMsg(service.serviceName + " 服务启动成功。") } } // 停止服务 func stopService(service myService) { s, err := NewWinService(service.serviceName) if s == nil || err != nil { return } showMsg(service.serviceName + " 服务开始停止......") err = s.StopService() if err != nil { showMsg(service.serviceName + " 服务停止失败!") } else { showMsg(service.serviceName + " 服务停止成功。") } } func showMsg(msg string) { app.msg.AppendText(time.Now().Format("2006-01-02 15:04:05 ")) app.msg.AppendText(msg) app.msg.AppendText("\r\n") } // 初始始化窗体 func getWindows() error { icon, _ := walk.NewIconFromResourceId(3) err := MainWindow{ Visible: false, AssignTo: &app.mw, Title: app.title, Size: Size{500, 360}, Font: Font{Family: "微软雅黑", PointSize: 9}, Icon: icon, Layout: VBox{}, Children: []Widget{ GroupBox{ Title: "基础服务状态", Layout: Grid{Columns: 3}, Children: []Widget{ Label{Text: service1.text, MinSize: Size{220, 30}, TextColor: walk.RGB(255, 255, 0)}, Label{AssignTo: &service1.labelState, Text: "正在运行", MinSize: Size{80, 30}}, Composite{ Layout: HBox{}, MaxSize: Size{198, 30}, Children: []Widget{ PushButton{ AssignTo: &service1.btnRegister, MaxSize: Size{60, 30}, Text: "注册", }, PushButton{ AssignTo: &service1.btnStop, MaxSize: Size{60, 30}, Text: "停止", }, PushButton{ AssignTo: &service1.btnStart, MaxSize: Size{60, 30}, Text: "启动", }, }, }, }, }, GroupBox{ Title: "业务服务状态", Layout: Grid{Columns: 3}, Children: []Widget{ Label{Text: service3.text, MinSize: Size{220, 30}}, Label{AssignTo: &service3.labelState, Text: "正在运行", MinSize: Size{80, 30}}, Composite{ Layout: HBox{}, MaxSize: Size{198, 30}, Children: []Widget{ PushButton{ AssignTo: &service3.btnRegister, MaxSize: Size{60, 30}, Text: "注册", }, PushButton{ AssignTo: &service3.btnStop, MaxSize: Size{60, 30}, Text: "停止", }, PushButton{ AssignTo: &service3.btnStart, MaxSize: Size{60, 30}, Text: "启动", }, }, }, }, }, TextEdit{AssignTo: &app.msg, VScroll: true, ReadOnly: true}, Composite{ Layout: HBox{}, Children: []Widget{ PushButton{ MinSize: Size{160, 30}, Text: "打开windows服务管理程序", OnClicked: func() { c := exec.Command("cmd", "/C", "SERVICES.MSC") c.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} // 不显示命令窗口 if err := c.Start(); err != nil { showMsg(fmt.Sprintf("打开windows服务管理程序失败, 错误信息: %s", err)) } }, }, HSpacer{}, PushButton{ MinSize: Size{121, 30}, Text: "关闭本监控窗口", OnClicked: func() { walk.App().Exit(0) }, }, }, }, }, OnSizeChanged: func() { _ = app.mw.SetSize(walk.Size(Size{500, 360})) }, }.Create() winLong := win.GetWindowLong(app.mw.Handle(), win.GWL_STYLE) // 不能调整窗口大小,禁用最大化按钮 win.SetWindowLong(app.mw.Handle(), win.GWL_STYLE, winLong & ^win.WS_SIZEBOX & ^win.WS_MAXIMIZEBOX & ^win.WS_SIZEBOX) // 设置窗体生成在屏幕的正中间,并处理高分屏的情况 // 窗体横坐标 = ( 屏幕宽度 - 窗体宽度 ) / 2 // 窗体纵坐标 = ( 屏幕高度 - 窗体高度 ) / 2 _ = app.mw.SetX((int(win.GetSystemMetrics(0)) - app.mw.Width()) / 2 / app.mw.DPI() * 96) _ = app.mw.SetY((int(win.GetSystemMetrics(1)) - app.mw.Height()) / 2 / app.mw.DPI() * 96) return err } /* 注册服务部分 */ func registerWindows(serviceName, regStr, objectName, displayName, imagePath string) { key, exists, _ := registry.CreateKey(registry.LOCAL_MACHINE, regStr, registry.ALL_ACCESS) defer key.Close() // 判断是否已经存在了 if !exists { showMsg(serviceName + " 新建注册表记录!") } _ = key.SetDWordValue(`Type`, uint32(16)) _ = key.SetDWordValue(`Start`, uint32(2)) _ = key.SetDWordValue(`ErrorControl`, uint32(1)) _ = key.SetDWordValue(`WOW64`, uint32(332)) _ = key.SetStringValue(`ObjectName`, objectName) _ = key.SetStringValue(`DisplayName`, displayName) _ = key.SetExpandStringValue(`ImagePath`, imagePath) if serviceName == "GWY20_Tomcat" { _ = key.SetStringValue(`Description`, `Apache Tomcat 8.5.55 Server - https://tomcat.apache.org/`) _ = key.SetStringsValue(`DependOnService`, []string{`Tcpip`, `Afd`}) } } func registerJava(serviceName, path string) { key, exists, _ := registry.CreateKey(registry.LOCAL_MACHINE, `SOFTWARE\WOW6432Node\Apache Software Foundation\Procrun 2.0\GWY20_Tomcat\Parameters\Java`, registry.ALL_ACCESS) defer key.Close() // 判断是否已经存在了 if !exists { showMsg(serviceName + " Java 新建注册表记录!") } _ = key.SetStringValue(`Jvm`, fmt.Sprintf(`%s\tomcat8/JDK1.8/jre\bin\server\jvm.dll`, path)) _ = key.SetStringValue(`Options`, fmt.Sprintf(`-Dcatalina.home=%s\tomcat8\0-Dcatalina.base=%s\tomcat8\0-Djava.endorsed.dirs=%s\tomcat8\endorsed\0-Djava.io.tmpdir=%s\tomcat8\temp\0-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager\0-Djava.util.logging.config.file=%s\tomcat8\conf\logging.properties\0-Dfile.encoding=GBK\0-XX:PermSize=128m\0-XX:MaxPermSize=256m`, path, path, path, path, path)) _ = key.SetStringValue(`Classpath`, fmt.Sprintf(`%s\tomcat8\bin\bootstrap.jar;%s\tomcat8\bin\tomcat-juli.jar`, path, path)) _ = key.SetDWordValue(`JvmMs`, uint32(512)) _ = key.SetDWordValue(`JvmMx`, uint32(512)) } func registerLog(serviceName, path string) { key, exists, _ := registry.CreateKey(registry.LOCAL_MACHINE, `SOFTWARE\WOW6432Node\Apache Software Foundation\Procrun 2.0\GWY20_Tomcat\Parameters\Log`, registry.ALL_ACCESS) defer key.Close() // 判断是否已经存在了 if !exists { showMsg(serviceName + " Log 新建注册表记录!") } _ = key.SetStringValue(`Path`, fmt.Sprintf(`%s\tomcat8\logs`, path)) _ = key.SetStringValue(`StdErrorStdError`, `auto`) _ = key.SetStringValue(`StdOutput`, `auto`) } func registerState(serviceName, regStr, state, path string) { key, exists, _ := registry.CreateKey(registry.LOCAL_MACHINE, regStr, registry.ALL_ACCESS) defer key.Close() // 判断是否已经存在了 if !exists { showMsg(serviceName + " " + state + " 新建注册表记录!") } _ = key.SetStringValue(`Class`, `org.apache.catalina.startup.Bootstrap`) _ = key.SetStringValue(`Params`, state) _ = key.SetStringValue(`Mode`, `jvm`) _ = key.SetStringValue(`WorkingPath`, fmt.Sprintf(`%s\tomcat8`, path)) }