// +build windows package main import ( "bufio" "database/sql" "errors" "fmt" _ "github.com/go-sql-driver/mysql" "github.com/lxn/walk" . "github.com/lxn/walk/declarative" "github.com/lxn/win" "github.com/mzky/zip" "golang.org/x/sys/windows" "golang.org/x/sys/windows/registry" "io" "io/fs" "io/ioutil" "log" "os" "os/exec" "path/filepath" "runtime" "strings" "syscall" "time" ) var version = "V2021 1.0.1" var passwordname = "Qw^e1@10&++Hzb...?8" func (mw *myApp) aboutactionTriggered() { walk.MsgBox(mw.mw, "功能说明", strings.Join([]string{ "1. 启动、终止并设置 应用和数据库 服务", "2. 清除 浏览器和应用 缓存", "3. 设置 应用和数据库 内存大小", "4. 实现 数据备份 压缩备份脚本与备份照片", "5. 实现 数据还原 执行还原脚本与还原照片", fmt.Sprintf("版本:%s", version)}, "\n"), walk.MsgBoxIconQuestion) } 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 // 该部分不存在最后 横线 (格式为 D:\hzb2021),使用时需要补充横线 var path string // init 初始化 func init() { app.title = "公务员管理系统-运行监控" service1 = myService{ text: "⚡数据存储库", serviceName: "GWY20_Mysql", } service3 = myService{ text: "⚡公务员系统", serviceName: "GWY20_Tomcat", } path, _ = os.Getwd() } // main 程序入口 func main() { _ = getWindows() if e := HasHzb(); e != nil { walk.MsgBox(app.mw, "错误", "请先下载并安装 组工 软件,才可以正常使用软件!", walk.MsgBoxIconWarning) OpenUrl("https://www.12371.cn/zgrjxz/gwywx/") return } if e := InHzb(); e != nil { walk.MsgBox(app.mw, "错误", "当前工具未在正确的位置,请将工具移至安装软件目录下(如:./hzb2020/HyServer.exe)!", walk.MsgBoxIconWarning) return } walk.App().SetProductName(app.title) walk.App().SetOrganizationName("网新") walk.App().SetProductName("网新") showMsg(fmt.Sprintf(" 当前获取的目录为:%s", path)) _ = 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 getWindows() error { icon, _ := walk.NewIconFromResourceId(3) err := MainWindow{ Visible: false, AssignTo: &app.mw, Title: app.title, Size: Size{Width: 500, Height: 360}, Font: Font{Family: "微软雅黑", PointSize: 9}, Icon: icon, Layout: VBox{}, MenuItems: []MenuItem{ Menu{ Text: "&编辑", // Image: "./image//media.png", Items: []MenuItem{ Separator{}, Action{ // Image: "./image//qinghuancun.png", Text: "清除缓存", OnTriggered: clearAll, }, Action{ // Image: "./image//beifen.png", Text: "数据备份", OnTriggered: dbBak, }, Action{ // Image: "./image//huanyuan.png", Text: "数据还原", OnTriggered: reDbBak, }, Action{ // Image: "./image//tuichu.png", Text: "退出", OnTriggered: func() { walk.App().Exit(0) }, }, }, }, Menu{ Text: "&设置", // Image: "./image//shezhi.png", Items: []MenuItem{ Separator{}, Action{ // Image: "./image//shujuku.png", Text: "设置数据库内存", OnTriggered: setDbSize, }, Action{ // Image: "./image//yingyong.png", Text: "设置应用内存", OnTriggered: setServerSize, }, }, }, Menu{ Text: "&帮助", // Image: "./image//bangzhu.png", Items: []MenuItem{ Action{ // Image: "./image//guanyu.png", Text: "关于", OnTriggered: app.aboutactionTriggered, }, /*Action{ // Image: "./image//yaoqiu.png", Text: "要求", OnTriggered: app.aboutactionTriggered, },*/ }, }, }, Children: []Widget{GroupBox{ Title: "基础服务状态", Layout: Grid{Columns: 3}, Children: []Widget{ Label{Text: service1.text, MinSize: Size{Width: 220, Height: 30}, TextColor: walk.RGB(255, 255, 0)}, Label{AssignTo: &service1.labelState, Text: "正在运行", MinSize: Size{Width: 80, Height: 30}}, Composite{ Layout: HBox{}, MaxSize: Size{Width: 198, Height: 30}, Children: []Widget{ PushButton{ AssignTo: &service1.btnRegister, MaxSize: Size{Width: 60, Height: 30}, Text: "注册表", }, PushButton{ AssignTo: &service1.btnStop, MaxSize: Size{Width: 60, Height: 30}, Text: "停止", }, PushButton{ AssignTo: &service1.btnStart, MaxSize: Size{Width: 60, Height: 30}, Text: "启动", }, }, }, }, }, GroupBox{ Title: "业务服务状态", Layout: Grid{Columns: 3}, Children: []Widget{ Label{Text: service3.text, MinSize: Size{Width: 220, Height: 30}}, Label{AssignTo: &service3.labelState, Text: "正在运行", MinSize: Size{Width: 80, Height: 30}}, Composite{ Layout: HBox{}, MaxSize: Size{Width: 198, Height: 30}, Children: []Widget{ PushButton{ AssignTo: &service3.btnRegister, MaxSize: Size{Width: 60, Height: 30}, Text: "注册表", }, PushButton{ AssignTo: &service3.btnStop, MaxSize: Size{Width: 60, Height: 30}, Text: "停止", }, PushButton{ AssignTo: &service3.btnStart, MaxSize: Size{Width: 60, Height: 30}, Text: "启动", }, }, }, }, }, TextEdit{AssignTo: &app.msg, VScroll: true, ReadOnly: true}, Composite{ Layout: HBox{}, Children: []Widget{ PushButton{ MinSize: Size{Width: 200, Height: 30}, Text: "打开windows服务管理程序", OnClicked: openServices, }, HSpacer{}, PushButton{ MinSize: Size{Width: 140, Height: 30}, Text: "关闭本监控窗口", OnClicked: func() { walk.App().Exit(0) }, }, }, }}, OnSizeChanged: func() { _ = app.mw.SetSize(walk.Size(Size{Width: 500, Height: 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 } // setServiceState 设置 服务状态描述和按钮状态 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) } // flushServiceStat 刷新服务状态的协程程序 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, false) } else { setServiceState(service, "服务打开失败", false, false, true) } } else { if winService.IsStop() { setServiceState(service, "已经停止", true, false, true) } else if winService.IsRunning() { setServiceState(service, "正在运行", false, true, false) } } time.Sleep(time.Second) } } // registerService 【0】注册服务 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=%s\mysql\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, 128, 256, 512, 512) 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 + " 服务注册成功!") } // startService 启动服务 func startService(service myService) { s, err := NewWinService(service.serviceName) if s == nil || err != nil { return } showMsg(service.serviceName + " 服务开始启动......") err = s.StartService() time.Sleep(15 * time.Second) if err != nil { showMsg(service.serviceName + " 服务启动失败!") } else { showMsg(service.serviceName + " 服务启动成功。") } } // stopService 停止服务 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 + " 服务停止成功。") } } // showMsg 显示内容到 控制面板 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") } /* 注册服务部分 */ // registerWindows 【1】修改注册表 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`}) } key, exists, _ = registry.CreateKey(registry.LOCAL_MACHINE, regStr+`\Parameters`, registry.ALL_ACCESS) defer key.Close() } // registerJava 【2】修改注册表 func registerJava(serviceName, path string, permSize, maxPermSize, xms, xmx int) { 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.SetStringsValue(`Options`, []string{ fmt.Sprintf(`-Dcatalina.home=%s\tomcat8`, path), fmt.Sprintf(`-Djava.endorsed.dirs=%s\tomcat8\endorsed`, path), fmt.Sprintf(`-Djava.io.tmpdir=%s\tomcat8\temp`, path), `-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager`, fmt.Sprintf(`-Djava.util.logging.config.file=%s\tomcat8\conf\logging.properties`, path), `-Dfile.encoding=GBK`, fmt.Sprintf(`-XX:PermSize=%dm`, permSize), fmt.Sprintf(`-XX:MaxPermSize=%dm`, maxPermSize), }) _ = key.SetStringValue(`Classpath`, fmt.Sprintf(`%s\tomcat8\bin\bootstrap.jar;%s\tomcat8\bin\tomcat-juli.jar`, path, path)) _ = key.SetDWordValue(`JvmMs`, uint32(xms)) _ = key.SetDWordValue(`JvmMx`, uint32(xmx)) } // registerLog 【3】修改注册表 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(`StdError`, `auto`) _ = key.SetStringValue(`StdOutput`, `auto`) } // registerState 【4】修改注册表 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.SetStringsValue(`Params`, []string{state}) _ = key.SetStringValue(`Mode`, `jvm`) _ = key.SetStringValue(`WorkingPath`, fmt.Sprintf(`%s\tomcat8`, path)) } // Unzip 执行 解压文件操作,目的路径不带本级文件名称 func Unzip(zipFile string, destDir string) error { zipReader, err := zip.OpenReader(zipFile) if err != nil { return err } defer zipReader.Close() for _, f := range zipReader.File { fpath := filepath.Join(destDir, f.Name) if f.FileInfo().IsDir() { _ = os.MkdirAll(fpath, os.ModePerm) } else { return runUnzip(fpath, f) } } return nil } func runUnzip(fpath string, f *zip.File) error { if err := os.MkdirAll(filepath.Dir(fpath), os.ModePerm); err != nil { return err } inFile, err := f.Open() if err != nil { return err } defer inFile.Close() outFile, err := os.OpenFile(fpath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode()) if err != nil { return err } defer outFile.Close() _, err = io.Copy(outFile, inFile) return err } // openServices 打开本地 服务 func openServices() { 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)) } } // clearAll 清除缓存 和 重启服务 func clearAll() { showMsg("执行清除缓存!") stopService(service3) showMsg("正在退出浏览器...") err := exec.Command("cmd.exe", "/c", "taskkill /f /im 360se.exe").Run() if err != nil { showMsg(fmt.Sprintf("退出浏览器发生异常: %s", err.Error())) } showMsg("浏览器退出成功!") showMsg("正在清除浏览器缓存...") _ = os.RemoveAll(fmt.Sprintf(`%s\360se6\User Data`, path)) _ = Unzip(fmt.Sprintf(`%s\tools\User Data.zip`, path), fmt.Sprintf(`%s\360se6`, path)) showMsg("浏览器缓存清除成功!") showMsg("正在清除应用缓存...") _ = os.RemoveAll(fmt.Sprintf(`%s\tomcat8\temp`, path)) _ = os.RemoveAll(fmt.Sprintf(`%s\tomcat8\work\Catalina\localhost\qggwy`, path)) showMsg("应用缓存清除成功!") startService(service3) } // setDbSize 显示设置数据库内存大小界面,等待保存 func setDbSize() { app.RunDbSetingDialog(app.mw, func(setings *DbSetings) { // 停服务 stopService(service1) // 设置修改参数 setDbIni(setings.InnodbBufferPoolSize) // 起服务 startService(service1) showMsg("数据库内存调整完毕!") }) } func setDbIni(innodbBufferPoolSize int) { //读写方式打开文件 myIniFile := fmt.Sprintf(`%s/mysql/my.ini`, path) file, err := os.OpenFile(myIniFile, os.O_RDWR, 0666) if err != nil { showMsg("【异常】打开文件发生错误!" + myIniFile) log.Fatal("打开文件异常:", err) return } //defer关闭文件 defer file.Close() //读取文件内容到io中 reader := bufio.NewReader(file) pos := int64(0) innodbBufferPoolSizeStr := []byte(fmt.Sprintf(`innodb_buffer_pool_size=%dM`, innodbBufferPoolSize)) for { //读取每一行内容 line, err := reader.ReadString('\n') if err != nil { //读到末尾 if err == io.EOF { showMsg("打开读取文件完毕!") break } else { showMsg("【异常】读取文件发生错误:" + line) log.Fatal("读取文件异常:", err) return } } //根据关键词覆盖当前行 if strings.Contains(line, "innodb_buffer_pool_size") { _, _ = file.WriteAt(innodbBufferPoolSizeStr, pos) } //每一行读取完后记录位置 pos += int64(len(line)) } } // setServerSize 显示设置应用内存大小界面,等待保存 func setServerSize() { app.RunAppSetingDialog(app.mw, func(setings *AppSetings) { // 停服务 stopService(service3) // 设置数据库内存大小 //registerJava(service3.serviceName, path, 129, 259, 500, 500) registerJava(service3.serviceName, path, setings.PermSize, setings.MaxPermSize, setings.Xms, setings.Xmx) // 起服务 startService(service3) showMsg("应用内存调整完毕!") }) } // dbBak 数据备份功能 func dbBak() { db, _ := sql.Open("mysql", "root:admin@tcp(127.0.0.1:35017)/hy_qggwy?charset=utf8") showMsg("连接数据库成功!") // 创建临时文件夹 dir := time.Now().Format("2006102150405") if err := os.MkdirAll(dir, os.ModePerm); err != nil { showMsg("创建临时目录时发生异常!") } QuerySQL(db, dir, "select * from a01 where STATUS=1", "a01", []string{"A0155", "JSNLSJ", "TBSJ", "XGSJ"}) QuerySQL(db, dir, "select * from a02 where a0000 in (select a0000 from a01 where status=1)", "a02", []string{}) QuerySQL(db, dir, "select * from a05 where a0000 in (select a0000 from a01 where status=1)", "a05", []string{}) QuerySQL(db, dir, "select * from a06 where a0000 in (select a0000 from a01 where status=1)", "a06", []string{}) QuerySQL(db, dir, "select * from a08 where a0000 in (select a0000 from a01 where status=1)", "a08", []string{}) QuerySQL(db, dir, "select * from a14 where a0000 in (select a0000 from a01 where status=1)", "a14", []string{}) QuerySQL(db, dir, "select * from a15 where a0000 in (select a0000 from a01 where status=1)", "a15", []string{}) QuerySQL(db, dir, "select * from a17 where a0000 in (select a0000 from a01 where status=1)", "a17", []string{}) QuerySQL(db, dir, "select * from a36 where a0000 in (select a0000 from a01 where status=1)", "a36", []string{}) QuerySQL(db, dir, "select * from a30 where a0000 in (select a0000 from a01 where status=1)", "a30", []string{}) QuerySQL(db, dir, "select * from a33 where a0000 in (select a0000 from a01 where status=1)", "a33", []string{}) QuerySQL(db, dir, "select * from a57 where a0000 in (select a0000 from a01 where status=1)", "a57", []string{}) QuerySQL(db, dir, "select * from a65 where a0000 in (select a0000 from a01 where status=1)", "a65", []string{}) QuerySQL(db, dir, "select * from a99z1 where a0000 in (select a0000 from a01 where status=1)", "a99z1", []string{}) QuerySQL(db, dir, "select * from b01", "b01", []string{}) // 处理照片信息 copyFileByA57(db, dir) dirName := fmt.Sprintf("./%s/", dir) fileName := fmt.Sprintf("%s.gz", dir) // 进行压缩操作 并 删除压缩前目录 Zip(dirName, fileName) if err := os.RemoveAll(dir); err != nil { showMsg("删除历史目录时发生异常!") } showMsg("已完成数据备份!") showMsg(fmt.Sprintf(`⭐数据备份:%s`, fileName)) } // reDbBak 备份数据还原 func reDbBak() { // 执行还原操作 // runSQL("mysqlPath", "sqlPath") showMsg("【待完善】备份数据还原!") } //数据库配置结构 type DbSetings struct { InnodbBufferPoolSize int // 数据库缓存大小 } // 运行 数据库设置 Dialog func (mw *myApp) RunDbSetingDialog(owner walk.Form, confirmCall func(*DbSetings)) { var seting *DbSetings var dlg *walk.Dialog var db *walk.DataBinder var acceptPB, cancelPB *walk.PushButton seting = new(DbSetings) // 设置预定值 seting.InnodbBufferPoolSize = 512 _, _ = Dialog{ AssignTo: &dlg, Title: "数据源内存设置", Font: Font{Family: "微软雅黑", PointSize: 9}, DefaultButton: &acceptPB, CancelButton: &cancelPB, DataBinder: DataBinder{ AssignTo: &db, Name: "setings", DataSource: seting, ErrorPresenter: ToolTipErrorPresenter{}, }, MinSize: Size{Width: 450, Height: 220}, Layout: VBox{}, Children: []Widget{ Composite{ Layout: Grid{Columns: 2}, Children: []Widget{ Label{Text: `      数据库内存:`}, NumberEdit{Value: Bind("InnodbBufferPoolSize", Range{Min: 64, Max: 10240}), Suffix: " M", Decimals: 0}, }, }, Composite{ Layout: HBox{}, Children: []Widget{ HSpacer{}, PushButton{ AssignTo: &acceptPB, Text: "保存", OnClicked: func() { if err := db.Submit(); err != nil { showMsg("【异常】处理设置数据库内存时,发生异常!") log.Fatal(err) return } // 关闭页面 dlg.Cancel() // 应用 回调函数 confirmCall(seting) }, }, PushButton{ AssignTo: &cancelPB, Text: "取消", OnClicked: func() { dlg.Cancel() }, }, }, }, }, }.Run(owner) } //应用配置结构 type AppSetings struct { PermSize int // 非堆区初始内存分配大小 MaxPermSize int // 非堆区分配的内存的最大上限 Xms int // 堆区内存初始内存分配的大小 Xmx int // 堆区内存可被分配的最大上限 } // 运行 应用设置 Dialog func (mw *myApp) RunAppSetingDialog(owner walk.Form, confirmCall func(*AppSetings)) { var seting *AppSetings var dlg *walk.Dialog var db *walk.DataBinder var acceptPB, cancelPB *walk.PushButton seting = new(AppSetings) // 设置预定值 seting.PermSize = 128 seting.MaxPermSize = 256 seting.Xmx = 512 seting.Xms = 512 _, _ = Dialog{ AssignTo: &dlg, Title: "应用内存设置", Font: Font{Family: "微软雅黑", PointSize: 9}, DefaultButton: &acceptPB, CancelButton: &cancelPB, DataBinder: DataBinder{ AssignTo: &db, Name: "setings", DataSource: seting, ErrorPresenter: ToolTipErrorPresenter{}, }, MinSize: Size{Width: 450, Height: 320}, Layout: VBox{}, Children: []Widget{ Composite{ Layout: Grid{Columns: 2}, Children: []Widget{ Label{Text: `  PermSize(非堆区)初始内存分配大小:`}, NumberEdit{Value: Bind("PermSize", Range{Min: 64, Max: 10240}), Suffix: " m", Decimals: 0}, Label{Text: `MaxPermSize(非堆区)最大内存分配上限:`}, NumberEdit{Value: Bind("MaxPermSize", Range{Min: 64, Max: 10240}), Suffix: " m", Decimals: 0}, Label{Text: `      Xms(堆区)初始内存分配大小:`}, NumberEdit{Value: Bind("Xms", Range{Min: 64, Max: 10240}), Suffix: " m", Decimals: 0}, Label{Text: `      Xmx(堆区)最大内存分配上限:`}, NumberEdit{Value: Bind("Xmx", Range{Min: 64, Max: 10240}), Suffix: " m", Decimals: 0}, }, }, Composite{ Layout: HBox{}, Children: []Widget{ HSpacer{}, PushButton{ AssignTo: &acceptPB, Text: "保存", OnClicked: func() { if err := db.Submit(); err != nil { showMsg("【异常】处理设置数据库内存时,发生异常!") log.Fatal(err) return } // 关闭页面 dlg.Cancel() // DB 回调函数 confirmCall(seting) }, }, PushButton{ AssignTo: &cancelPB, Text: "取消", OnClicked: func() { dlg.Cancel() }, }, }, }, }, }.Run(owner) } // runSQL 执行sql脚本 func runSQL(mysqlPath, sqlPath string) { log.Print("调用执行对应的SQL脚本:", sqlPath) c := exec.Command("cmd", "/C", mysqlPath+"mysql -uroot -padmin hy_qggwy < "+sqlPath) if err := c.Run(); err != nil { log.Print("【不影响执行】执行时发生异常!异常为:", err) } log.Print("预置脚本数据成功!") } // QuerySQL 获取表数据 func QuerySQL(db *sql.DB, dir, sqlStr, tableName string, colNil []string) { rows, _ := db.Query(sqlStr) showMsg(fmt.Sprintf(`开始备份数据:%s;`, tableName)) defer rows.Close() cloumns, _ := rows.Columns() values := make([]sql.RawBytes, len(cloumns)) scanArgs := make([]interface{}, len(values)) for i := range values { scanArgs[i] = &values[i] } aa := fmt.Sprintf("truncate table %s;\n", tableName) for rows.Next() { _ = rows.Scan(scanArgs...) key, value := "(", "(" aa = aa + "insert into " + tableName + " " for i, col := range values { kk := cloumns[i] if inStr(colNil, kk) { continue } if i == len(values)-1 { key = key + kk if value == "(" { if col == nil { value = value + "NULL" } else { value = value + "'" + string(col) + "'" } } else { if col == nil { value = value + ",NULL" } else { value = value + ",'" + string(col) + "'" } } } else { key = key + kk + "," if value == "(" { if col == nil { value = value + "NULL" } else { value = value + "'" + string(col) + "'" } } else { if col == nil { value = value + ",NULL" } else { value = value + ",'" + string(col) + "'" } } } } key = key + ")" value = value + ");\n" aa = aa + key + " values " + value } var path string path = fmt.Sprintf("%s/%s.sql", dir, tableName) file3, _ := os.Create(path) _, _ = file3.WriteString(aa) file3.Close() } // inStr 判断字段关系 func inStr(colNil []string, kk string) bool { for _, s := range colNil { if s == kk { return true } } return false } // copyFileByA57 复制需要备份的照片文件 func copyFileByA57(db *sql.DB, mysqlPath string) { codeValues, _ := db.Query("select concat('tomcat8/HZBPHOTOS/', PHOTOPATH) filePath, PHOTONAME fileName from " + "a57 where a0000 in (select a0000 from a01 where status=1);") //返回所有列 filePath, fileName := "", "" for codeValues.Next() { _ = codeValues.Scan(&filePath, &fileName) if filePath != "" { from := path + "/" + filePath + fileName to := mysqlPath + "/" + filePath _ = os.MkdirAll(to, os.ModePerm) if _, err := CopyFile(from, to+fileName); err != nil { showMsg(fmt.Sprintf(`发现存在照片无法复制:%s`, filePath+fileName)) } } } } // CopyFile 复制文件操作 func CopyFile(src, des string) (w int64, err error) { srcFile, _ := os.Open(src) defer srcFile.Close() desFile, _ := os.Create(des) defer desFile.Close() return io.Copy(desFile, srcFile) } // Zip 打包成zip文件 func Zip(srcDir string, zipFileName string) { // 预防:旧文件无法覆盖 _ = os.RemoveAll(zipFileName) // 创建:zip文件 zipfile, _ := os.Create(zipFileName) defer zipfile.Close() // 打开:zip文件 archive := zip.NewWriter(zipfile) defer archive.Close() // 遍历路径信息 _ = filepath.Walk(srcDir, func(path string, info os.FileInfo, _ error) error { // 如果是源路径,提前进行下一个遍历 if path == srcDir { return nil } // 获取:文件头信息 header, _ := zip.FileInfoHeader(info) header.Name = strings.TrimPrefix(path, srcDir+`/`) // 判断:文件是不是文件夹 if info.IsDir() { header.Name += `/` } else { // 设置:zip的文件压缩算法 header.Method = zip.Deflate } // 创建:压缩包头部信息 writer, _ := archive.Encrypt(header.Name, passwordname, zip.AES256Encryption) if !info.IsDir() { file, _ := os.Open(path) defer file.Close() _, _ = io.Copy(writer, file) } return nil }) } // open opens the specified URL in the default browser of the user. func OpenUrl(url string) error { var cmd string var args []string switch runtime.GOOS { case "windows": cmd = "cmd" args = []string{"/c", "start"} case "darwin": cmd = "open" default: // "linux", "freebsd", "openbsd", "netbsd" cmd = "xdg-open" } args = append(args, url) c := exec.Command(cmd, args...) c.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} return c.Start() } // hasHzb 判断软件是否安装 func HasHzb() error { return nil } // inHzb 判断当前软件是否在正确的位置 func InHzb() error { pwd, _ := os.Getwd() // 判断依据 为是否存在 360se6、tools、Tomcat8 和 mysql 目录下 fileInfoList, _ := ioutil.ReadDir(pwd) if Contains(fileInfoList, "360se6") == -1 { return errors.New("目录错误") } if Contains(fileInfoList, "mysql") == -1 { return errors.New("目录错误") } if Contains(fileInfoList, "tomcat8") == -1 { return errors.New("目录错误") } if Contains(fileInfoList, "tools") == -1 { return errors.New("目录错误") } return nil } func Contains(array []fs.FileInfo, val string) (index int) { index = -1 for i := range array { // fmt.Println(array[i].Name()) //打印当前文件或目录下的文件或目录名 if array[i].Name() == val { index = i return } } return }