diff --git a/golang_learn/data_func/go_to_cmd/a.vbs b/golang_learn/data_func/go_to_command/run_vbs/a.vbs similarity index 100% rename from golang_learn/data_func/go_to_cmd/a.vbs rename to golang_learn/data_func/go_to_command/run_vbs/a.vbs diff --git a/golang_learn/data_func/go_to_cmd/main.go b/golang_learn/data_func/go_to_command/run_vbs/main.go similarity index 100% rename from golang_learn/data_func/go_to_cmd/main.go rename to golang_learn/data_func/go_to_command/run_vbs/main.go diff --git a/golang_learn/data_func/go_to_dir/delDirChild/main.go b/golang_learn/data_func/go_to_dir/delDirChild/main.go new file mode 100644 index 0000000..94756f1 --- /dev/null +++ b/golang_learn/data_func/go_to_dir/delDirChild/main.go @@ -0,0 +1,14 @@ +package main + +import ( + "io/ioutil" + "os" + "path" +) + +func main() { + dir, _ := ioutil.ReadDir("/tmp") + for _, d := range dir { + os.RemoveAll(path.Join([]string{"tmp", d.Name()}...)) + } +} diff --git a/golang_learn/data_func/go_to_walk/demo15/main.go b/golang_learn/data_func/go_to_walk/demo15/main.go new file mode 100644 index 0000000..57b4f89 --- /dev/null +++ b/golang_learn/data_func/go_to_walk/demo15/main.go @@ -0,0 +1,97 @@ +package main + +import ( + "fmt" + "io" + "os" + "strings" + + "github.com/lxn/walk" + . "github.com/lxn/walk/declarative" +) + +type MyMainWindow struct { + *walk.MainWindow + edit *walk.TextEdit +} + +func main() { + mw := &MyMainWindow{} + err := MainWindow{ + AssignTo: &mw.MainWindow, //窗口重定向至mw,重定向后可由重定向变量控制控件 + Icon: "test.ico", //窗体图标 + Title: "文件选择对话框", //标题 + MinSize: Size{Width: 150, Height: 200}, + Size: Size{300, 400}, + Layout: VBox{}, //样式,纵向 + Children: []Widget{ //控件组 + TextEdit{ + AssignTo: &mw.edit, + }, + PushButton{ + Text: "打开", + OnClicked: mw.selectFile, //点击事件响应函数 + }, + PushButton{ + Text: "另存为", + OnClicked: mw.saveFile, + }, + }, + }.Create() //创建 + + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + + mw.Run() //运行 +} + +func (mw *MyMainWindow) selectFile() { + + dlg := new(walk.FileDialog) + dlg.Title = "选择文件" + dlg.Filter = "可执行文件 (*.exe)|*.exe|所有文件 (*.*)|*.*" + + mw.edit.SetText("") //通过重定向变量设置TextEdit的Text + if ok, err := dlg.ShowOpen(mw); err != nil { + mw.edit.AppendText("Error : File Open\r\n") + return + } else if !ok { + mw.edit.AppendText("Cancel\r\n") + return + } + s := fmt.Sprintf("Select : %s\r\n", dlg.FilePath) + mw.edit.AppendText(s) +} + +func (mw *MyMainWindow) saveFile() { + + dlg := new(walk.FileDialog) + dlg.Title = "另存为" + + if ok, err := dlg.ShowSave(mw); err != nil { + fmt.Fprintln(os.Stderr, err) + return + } else if !ok { + fmt.Fprintln(os.Stderr, "Cancel") + return + } + + data := mw.edit.Text() + filename := dlg.FilePath + f, err := os.Open(filename) + if err != nil { + f, _ = os.Create(filename) + } else { + f.Close() + //打开文件,参数:文件路径及名称,打开方式,控制权限 + f, err = os.OpenFile(filename, os.O_WRONLY, 0x666) + } + if len(data) == 0 { + f.Close() + return + } + io.Copy(f, strings.NewReader(data)) + f.Close() +} diff --git a/golang_learn/data_func/go_to_walk/demo16/main.go b/golang_learn/data_func/go_to_walk/demo16/main.go new file mode 100644 index 0000000..1b50698 --- /dev/null +++ b/golang_learn/data_func/go_to_walk/demo16/main.go @@ -0,0 +1,163 @@ +package main + +import ( + "fmt" + "io" + "os" + "strings" + + "github.com/lxn/walk" + . "github.com/lxn/walk/declarative" +) + +type MyMainWindow struct { + *walk.MainWindow + edit *walk.TextEdit +} + +func main() { + mw := &MyMainWindow{} + if err := (MainWindow{ + AssignTo: &mw.MainWindow, + MinSize: Size{400, 300}, + Size: Size{600, 400}, + MenuItems: []MenuItem{ + Menu{ + Text: "文件", + Items: []MenuItem{ + Action{ + Text: "打开文件", + Shortcut: Shortcut{ //定义快捷键后会有响应提示显示 + Modifiers: walk.ModControl, + Key: walk.KeyO, + }, + OnTriggered: mw.openFileActionTriggered, //点击动作触发响应函数 + }, + Action{ + Text: "另存为", + Shortcut: Shortcut{ + Modifiers: walk.ModControl | walk.ModShift, + Key: walk.KeyS, + }, + OnTriggered: mw.saveFileActionTriggered, + }, + Action{ + Text: "退出", + OnTriggered: func() { + mw.Close() + }, + }, + }, + }, + Menu{ + Text: "帮助", + Items: []MenuItem{ + Action{ + Text: "关于", + OnTriggered: func() { + walk.MsgBox(mw, "关于", "这是一个菜单和工具栏的实例", + walk.MsgBoxIconInformation|walk.MsgBoxDefButton1) + }, + }, + }, + }, + }, + ToolBar: ToolBar{ //工具栏 + ButtonStyle: ToolBarButtonTextOnly, + Items: []MenuItem{ + Menu{ + Text: "New", + Items: []MenuItem{ + Action{ + Text: "A", + OnTriggered: mw.newAction_Triggered, + }, + Action{ + Text: "B", + OnTriggered: mw.newAction_Triggered, + }, + }, + OnTriggered: mw.newAction_Triggered, //在菜单中不可如此定义,会无响应 + }, + Separator{}, //分隔符 + Action{ + Text: "View", + OnTriggered: mw.changeViewAction_Triggered, + }, + }, + }, + Layout: VBox{}, + Children: []Widget{ + TextEdit{ + AssignTo: &mw.edit, + }, + }, + OnDropFiles: mw.dropFiles, //放置文件事件响应函数 + }).Create(); err != nil { + fmt.Fprintln(os.Stderr, err) + return + } + + mw.Run() +} + +func (mw *MyMainWindow) openFileActionTriggered() { + dlg := new(walk.FileDialog) + dlg.Title = "打开文件" + dlg.Filter = "文本文件 (*.txt)|*.txt|所有文件 (*.*)|*.*" + + if ok, err := dlg.ShowOpen(mw); err != nil { + fmt.Fprintln(os.Stderr, "错误:打开文件时\r\n") + return + } else if !ok { + fmt.Fprintln(os.Stderr, "用户取消\r\n") + return + } + + s := fmt.Sprintf("选择了:%s\r\n", dlg.FilePath) + mw.edit.SetText(s) +} + +func (mw *MyMainWindow) saveFileActionTriggered() { + dlg := new(walk.FileDialog) + dlg.Title = "另存为" + + if ok, err := dlg.ShowSave(mw); err != nil { + fmt.Fprintln(os.Stderr, err) + return + } else if !ok { + fmt.Fprintln(os.Stderr, "取消") + return + } + + data := mw.edit.Text() + filename := dlg.FilePath + f, err := os.Open(filename) + if err != nil { + f, _ = os.Create(filename) + } else { + f.Close() + f, err = os.OpenFile(filename, os.O_WRONLY, 0x666) + } + if len(data) == 0 { + f.Close() + return + } + io.Copy(f, strings.NewReader(data)) + f.Close() +} + +func (mw *MyMainWindow) newAction_Triggered() { + walk.MsgBox(mw, "New", "Newing something up... or not.", walk.MsgBoxIconInformation) +} + +func (mw *MyMainWindow) changeViewAction_Triggered() { + walk.MsgBox(mw, "Change View", "By now you may have guessed it. Nothing changed.", walk.MsgBoxIconInformation) +} + +func (mw *MyMainWindow) dropFiles(files []string) { + mw.edit.SetText("") + for _, v := range files { + mw.edit.AppendText(v + "\r\n") + } +} diff --git a/golang_learn/data_func/go_to_walk/demo17/main.go b/golang_learn/data_func/go_to_walk/demo17/main.go new file mode 100644 index 0000000..9405bbe --- /dev/null +++ b/golang_learn/data_func/go_to_walk/demo17/main.go @@ -0,0 +1,95 @@ +// Copyright 2016 The Walk Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "log" + + "github.com/lxn/walk" + . "github.com/lxn/walk/declarative" +) + +func main() { + var slv, slh *walk.Slider + var maxEdit, minEdit, valueEdit *walk.NumberEdit + + data := struct{ Min, Max, Value int }{0, 100, 30} + + MainWindow{ + Title: "Walk Slider Example", + MinSize: Size{320, 240}, + Layout: HBox{}, + Children: []Widget{ + Slider{ + AssignTo: &slv, + MinValue: data.Min, + MaxValue: data.Max, + Value: data.Value, + Orientation: Vertical, + OnValueChanged: func() { + data.Value = slv.Value() + valueEdit.SetValue(float64(data.Value)) + + }, + }, + Composite{ + Layout: Grid{Columns: 3}, + StretchFactor: 4, + Children: []Widget{ + Label{Text: "Min value"}, + Label{Text: "Value"}, + Label{Text: "Max value"}, + NumberEdit{ + AssignTo: &minEdit, + Value: float64(data.Min), + OnValueChanged: func() { + data.Min = int(minEdit.Value()) + slh.SetRange(data.Min, data.Max) + slv.SetRange(data.Min, data.Max) + }, + }, + NumberEdit{ + AssignTo: &valueEdit, + Value: float64(data.Value), + OnValueChanged: func() { + data.Value = int(valueEdit.Value()) + slh.SetValue(data.Value) + slv.SetValue(data.Value) + }, + }, + NumberEdit{ + AssignTo: &maxEdit, + Value: float64(data.Max), + OnValueChanged: func() { + data.Max = int(maxEdit.Value()) + slh.SetRange(data.Min, data.Max) + slv.SetRange(data.Min, data.Max) + }, + }, + Slider{ + ColumnSpan: 3, + AssignTo: &slh, + MinValue: data.Min, + MaxValue: data.Max, + Value: data.Value, + OnValueChanged: func() { + data.Value = slh.Value() + valueEdit.SetValue(float64(data.Value)) + }, + }, + VSpacer{}, + PushButton{ + ColumnSpan: 3, + Text: "Print state", + OnClicked: func() { + log.Printf("H: < %d | %d | %d >\n", slh.MinValue(), slh.Value(), slh.MaxValue()) + log.Printf("V: < %d | %d | %d >\n", slv.MinValue(), slv.Value(), slv.MaxValue()) + }, + }, + }, + }, + }, + }.Run() +} diff --git a/golang_learn/data_func/go_to_walk/demo18/main.go b/golang_learn/data_func/go_to_walk/demo18/main.go new file mode 100644 index 0000000..be4fe79 --- /dev/null +++ b/golang_learn/data_func/go_to_walk/demo18/main.go @@ -0,0 +1,49 @@ +// Copyright 2010 The Walk Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "strings" + + "github.com/lxn/walk" + . "github.com/lxn/walk/declarative" +) + +func main() { + var le *walk.LineEdit + var wv *walk.WebView + + MainWindow{ + Icon: Bind("'../img/' + icon(wv.URL) + '.ico'"), + Title: "Walk WebView Example'", + MinSize: Size{800, 600}, + Layout: VBox{MarginsZero: true}, + Children: []Widget{ + LineEdit{ + AssignTo: &le, + Text: Bind("wv.URL"), + OnKeyDown: func(key walk.Key) { + if key == walk.KeyReturn { + wv.SetURL(le.Text()) + } + }, + }, + WebView{ + AssignTo: &wv, + Name: "wv", + URL: "https://github.com/lxn/walk", + }, + }, + Functions: map[string]func(args ...interface{}) (interface{}, error){ + "icon": func(args ...interface{}) (interface{}, error) { + if strings.HasPrefix(args[0].(string), "https") { + return "check", nil + } + + return "stop", nil + }, + }, + }.Run() +} diff --git a/golang_learn/data_func/go_to_walk/demo19/main.go b/golang_learn/data_func/go_to_walk/demo19/main.go new file mode 100644 index 0000000..b5ca4b9 --- /dev/null +++ b/golang_learn/data_func/go_to_walk/demo19/main.go @@ -0,0 +1,239 @@ +// Copyright 2011 The Walk Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package main + +import ( + "fmt" + "math/rand" + "sort" + "strings" + "time" +) + +import ( + "github.com/lxn/walk" + . "github.com/lxn/walk/declarative" +) + +type Foo struct { + Index int + Bar string + Baz float64 + Quux time.Time + checked bool +} + +type FooModel struct { + walk.TableModelBase + walk.SorterBase + sortColumn int + sortOrder walk.SortOrder + items []*Foo +} + +func NewFooModel() *FooModel { + m := new(FooModel) + m.ResetRows() + return m +} + +// Called by the TableView from SetModel and every time the model publishes a +// RowsReset event. +func (m *FooModel) RowCount() int { + return len(m.items) +} + +// Called by the TableView when it needs the text to display for a given cell. +func (m *FooModel) Value(row, col int) interface{} { + item := m.items[row] + + switch col { + case 0: + return item.Index + + case 1: + return item.Bar + + case 2: + return item.Baz + + case 3: + return item.Quux + } + + panic("unexpected col") +} + +// Called by the TableView to retrieve if a given row is checked. +func (m *FooModel) Checked(row int) bool { + return m.items[row].checked +} + +// Called by the TableView when the user toggled the check box of a given row. +func (m *FooModel) SetChecked(row int, checked bool) error { + m.items[row].checked = checked + + return nil +} + +// Called by the TableView to sort the model. +func (m *FooModel) Sort(col int, order walk.SortOrder) error { + m.sortColumn, m.sortOrder = col, order + + sort.SliceStable(m.items, func(i, j int) bool { + a, b := m.items[i], m.items[j] + + c := func(ls bool) bool { + if m.sortOrder == walk.SortAscending { + return ls + } + + return !ls + } + + switch m.sortColumn { + case 0: + return c(a.Index < b.Index) + + case 1: + return c(a.Bar < b.Bar) + + case 2: + return c(a.Baz < b.Baz) + + case 3: + return c(a.Quux.Before(b.Quux)) + } + + panic("unreachable") + }) + + return m.SorterBase.Sort(col, order) +} + +func (m *FooModel) ResetRows() { + // Create some random data. + m.items = make([]*Foo, rand.Intn(50000)) + + now := time.Now() + + for i := range m.items { + m.items[i] = &Foo{ + Index: i, + Bar: strings.Repeat("*", rand.Intn(5)+1), + Baz: rand.Float64() * 1000, + Quux: time.Unix(rand.Int63n(now.Unix()), 0), + } + } + + // Notify TableView and other interested parties about the reset. + m.PublishRowsReset() + + m.Sort(m.sortColumn, m.sortOrder) +} + +func main() { + rand.Seed(time.Now().UnixNano()) + + boldFont, _ := walk.NewFont("Segoe UI", 9, walk.FontBold) + goodIcon, _ := walk.Resources.Icon("../img/check.ico") + badIcon, _ := walk.Resources.Icon("../img/stop.ico") + + barBitmap, err := walk.NewBitmap(walk.Size{100, 1}) + if err != nil { + panic(err) + } + defer barBitmap.Dispose() + + canvas, err := walk.NewCanvasFromImage(barBitmap) + if err != nil { + panic(err) + } + defer barBitmap.Dispose() + + canvas.GradientFillRectangle(walk.RGB(255, 0, 0), walk.RGB(0, 255, 0), walk.Horizontal, walk.Rectangle{0, 0, 100, 1}) + + canvas.Dispose() + + model := NewFooModel() + + var tv *walk.TableView + + MainWindow{ + Title: "Walk TableView Example", + Size: Size{800, 600}, + Layout: VBox{MarginsZero: true}, + Children: []Widget{ + PushButton{ + Text: "Reset Rows", + OnClicked: model.ResetRows, + }, + PushButton{ + Text: "Select first 5 even Rows", + OnClicked: func() { + tv.SetSelectedIndexes([]int{0, 2, 4, 6, 8}) + }, + }, + TableView{ + AssignTo: &tv, + AlternatingRowBG: true, + CheckBoxes: true, + ColumnsOrderable: true, + MultiSelection: true, + Columns: []TableViewColumn{ + {Title: "#"}, + {Title: "Bar"}, + {Title: "Baz", Alignment: AlignFar}, + {Title: "Quux", Format: "2006-01-02 15:04:05", Width: 150}, + }, + StyleCell: func(style *walk.CellStyle) { + item := model.items[style.Row()] + + if item.checked { + if style.Row()%2 == 0 { + style.BackgroundColor = walk.RGB(159, 215, 255) + } else { + style.BackgroundColor = walk.RGB(143, 199, 239) + } + } + + switch style.Col() { + case 1: + if canvas := style.Canvas(); canvas != nil { + bounds := style.Bounds() + bounds.X += 2 + bounds.Y += 2 + bounds.Width = int((float64(bounds.Width) - 4) / 5 * float64(len(item.Bar))) + bounds.Height -= 4 + canvas.DrawBitmapPartWithOpacity(barBitmap, bounds, walk.Rectangle{0, 0, 100 / 5 * len(item.Bar), 1}, 127) + + bounds.X += 4 + bounds.Y += 2 + canvas.DrawText(item.Bar, tv.Font(), 0, bounds, walk.TextLeft) + } + + case 2: + if item.Baz >= 900.0 { + style.TextColor = walk.RGB(0, 191, 0) + style.Image = goodIcon + } else if item.Baz < 100.0 { + style.TextColor = walk.RGB(255, 0, 0) + style.Image = badIcon + } + + case 3: + if item.Quux.After(time.Now().Add(-365 * 24 * time.Hour)) { + style.Font = boldFont + } + } + }, + Model: model, + OnSelectedIndexesChanged: func() { + fmt.Printf("SelectedIndexes: %v\n", tv.SelectedIndexes()) + }, + }, + }, + }.Run() +} diff --git a/golang_learn/data_func/go_to_windows/main.go b/golang_learn/data_func/go_to_windows/main.go index 4d81fe9..54e54f6 100644 --- a/golang_learn/data_func/go_to_windows/main.go +++ b/golang_learn/data_func/go_to_windows/main.go @@ -1,20 +1,36 @@ -// +build windows -// +build 386 +// + build windows +// + build 386 package main import ( + "archive/zip" "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" + "io" + "os" "os/exec" + "path/filepath" + "strings" "syscall" "time" ) +var version = "V2021 1.0.1" + +func (mw *myApp) aboutactionTriggered() { + walk.MsgBox(mw.mw, "功能说明", strings.Join([]string{ + "1. 启动、终止并设置 应用和数据库 服务", + "2. 清除 浏览器和应用 缓存", + "3. 设置 应用和数据库 内存大小", + fmt.Sprintf("版本:%s", version)}, "\n"), + walk.MsgBoxIconQuestion) +} + type myApp struct { title string msg *walk.TextEdit @@ -32,8 +48,11 @@ type myService struct { var app myApp var service1, service3 myService + +// 该部分不存在最后 横线 (格式为 D:\hzb2021),使用时需要补充横线 var path string +// init 初始化 func init() { app.title = "公务员管理系统-运行监控" service1 = myService{ @@ -41,18 +60,21 @@ func init() { serviceName: "GWY20_Mysql", } service3 = myService{ - text: "消防系统", + text: "公务员系统", serviceName: "GWY20_Tomcat", } - path = `D:\hzb2021` + path, _ = os.Getwd() } +// main 程序入口 func main() { _ = getWindows() walk.App().SetProductName(app.title) walk.App().SetOrganizationName("网新") + showMsg(fmt.Sprintf(" 当前获取的目录为:%s", path)) + _ = service1.labelState.SetText("未安装") _ = service3.labelState.SetText("未安装") service1.btnRegister.Clicked().Attach(func() { @@ -81,6 +103,7 @@ func main() { app.mw.Run() } +// setServiceState 设置 服务状态描述和按钮状态 func setServiceState(service myService, msg string, btnStartStatus, btnStopStatus, btnRegisterStatus bool) { _ = service.labelState.SetText(msg) service.btnStart.SetEnabled(btnStartStatus) @@ -88,19 +111,19 @@ func setServiceState(service myService, msg string, btnStartStatus, btnStopStatu 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, true) + setServiceState(service, "未安装", false, false, false) } else { - setServiceState(service, "服务打开失败", false, false, false) + setServiceState(service, "服务打开失败", false, false, true) } } else { if winService.IsStop() { - setServiceState(service, "已经停止", true, false, false) + setServiceState(service, "已经停止", true, false, true) } else if winService.IsRunning() { setServiceState(service, "正在运行", false, true, false) } @@ -109,7 +132,7 @@ func flushServiceStat(service myService) { } } -// 注册服务 +// registerService 【0】注册服务 func registerService(service myService) { if service.serviceName == "GWY20_Mysql" { // 注册 MYSQL 服务 @@ -122,7 +145,7 @@ func registerService(service myService) { `SYSTEM\CurrentControlSet\Services\GWY20_Mysql`, `LocalSystem`, `GWY20_Mysql`, - fmt.Sprintf(`%s\mysql\bin\mysqld --defaults-file=%smysql\my.ini GWY20_Mysql`, path, path)) + fmt.Sprintf(`%s\mysql\bin\mysqld --defaults-file=%s\mysql\my.ini GWY20_Mysql`, path, path)) } else { // 注册 TOMCAT 服务 registerWindows(service.serviceName, @@ -148,7 +171,7 @@ func registerService(service myService) { showMsg(service.serviceName + " 服务注册成功!") } -// 启动服务 +// startService 启动服务 func startService(service myService) { s, err := NewWinService(service.serviceName) if s == nil || err != nil { @@ -156,6 +179,7 @@ func startService(service myService) { } showMsg(service.serviceName + " 服务开始启动......") err = s.StartService() + time.Sleep(40 * time.Second) if err != nil { showMsg(service.serviceName + " 服务启动失败!") } else { @@ -163,7 +187,7 @@ func startService(service myService) { } } -// 停止服务 +// stopService 停止服务 func stopService(service myService) { s, err := NewWinService(service.serviceName) if s == nil || err != nil { @@ -178,6 +202,7 @@ func stopService(service myService) { } } +// showMsg 显示内容到 控制面板 func showMsg(msg string) { app.msg.AppendText(time.Now().Format("2006-01-02 15:04:05 ")) app.msg.AppendText(msg) @@ -191,34 +216,75 @@ func getWindows() error { Visible: false, AssignTo: &app.mw, Title: app.title, - Size: Size{500, 360}, + Size: Size{Width: 500, Height: 360}, Font: Font{Family: "微软雅黑", PointSize: 9}, Icon: icon, Layout: VBox{}, + MenuItems: []MenuItem{ + Menu{ + Text: "&编辑", + Items: []MenuItem{ + Separator{}, + Action{ + Text: "清除缓存", + OnTriggered: clearAll, + }, + Action{ + Text: "退出", + OnTriggered: func() { + walk.App().Exit(0) + }, + }, + }, + }, + Menu{ + Text: "&设置", + Items: []MenuItem{ + Separator{}, + Action{ + Text: "设置数据库内存", + OnTriggered: setDbSize, + }, + Action{ + Text: "设置应用内存", + OnTriggered: setServerSize, + }, + }, + }, + Menu{ + Text: "&帮助", + Items: []MenuItem{ + Action{ + Text: "关于", + OnTriggered: app.aboutactionTriggered, + }, + }, + }, + }, 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}}, + 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{198, 30}, + MaxSize: Size{Width: 198, Height: 30}, Children: []Widget{ PushButton{ AssignTo: &service1.btnRegister, - MaxSize: Size{60, 30}, - Text: "注册", + MaxSize: Size{Width: 60, Height: 30}, + Text: "注册表", }, PushButton{ AssignTo: &service1.btnStop, - MaxSize: Size{60, 30}, + MaxSize: Size{Width: 60, Height: 30}, Text: "停止", }, PushButton{ AssignTo: &service1.btnStart, - MaxSize: Size{60, 30}, + MaxSize: Size{Width: 60, Height: 30}, Text: "启动", }, }, @@ -229,25 +295,25 @@ func getWindows() error { Title: "业务服务状态", Layout: Grid{Columns: 3}, Children: []Widget{ - Label{Text: service3.text, MinSize: Size{220, 30}}, - Label{AssignTo: &service3.labelState, Text: "正在运行", MinSize: Size{80, 30}}, + 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{198, 30}, + MaxSize: Size{Width: 198, Height: 30}, Children: []Widget{ PushButton{ AssignTo: &service3.btnRegister, - MaxSize: Size{60, 30}, - Text: "注册", + MaxSize: Size{Width: 60, Height: 30}, + Text: "注册表", }, PushButton{ AssignTo: &service3.btnStop, - MaxSize: Size{60, 30}, + MaxSize: Size{Width: 60, Height: 30}, Text: "停止", }, PushButton{ AssignTo: &service3.btnStart, - MaxSize: Size{60, 30}, + MaxSize: Size{Width: 60, Height: 30}, Text: "启动", }, }, @@ -259,19 +325,13 @@ func getWindows() error { 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)) - } - }, + MinSize: Size{Width: 200, Height: 30}, + Text: "打开windows服务管理程序", + OnClicked: openServices, }, HSpacer{}, PushButton{ - MinSize: Size{121, 30}, + MinSize: Size{Width: 140, Height: 30}, Text: "关闭本监控窗口", OnClicked: func() { walk.App().Exit(0) @@ -281,7 +341,7 @@ func getWindows() error { }, }, OnSizeChanged: func() { - _ = app.mw.SetSize(walk.Size(Size{500, 360})) + _ = app.mw.SetSize(walk.Size(Size{Width: 500, Height: 360})) }, }.Create() winLong := win.GetWindowLong(app.mw.Handle(), win.GWL_STYLE) @@ -296,7 +356,7 @@ func getWindows() error { } /* 注册服务部分 */ - +// registerWindows 【1】修改注册表 func registerWindows(serviceName, regStr, objectName, displayName, imagePath string) { key, exists, _ := registry.CreateKey(registry.LOCAL_MACHINE, regStr, registry.ALL_ACCESS) defer key.Close() @@ -317,8 +377,11 @@ func registerWindows(serviceName, regStr, objectName, displayName, imagePath str _ = 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) { 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() @@ -328,14 +391,22 @@ func registerJava(serviceName, path string) { 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.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`, + `-XX:PermSize=128m`, + `-XX:MaxPermSize=256m`, + }) _ = 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)) } +// 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() @@ -345,10 +416,11 @@ func registerLog(serviceName, path string) { showMsg(serviceName + " Log 新建注册表记录!") } _ = key.SetStringValue(`Path`, fmt.Sprintf(`%s\tomcat8\logs`, path)) - _ = key.SetStringValue(`StdErrorStdError`, `auto`) + _ = 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() @@ -358,7 +430,100 @@ func registerState(serviceName, regStr, state, path string) { showMsg(serviceName + " " + state + " 新建注册表记录!") } _ = key.SetStringValue(`Class`, `org.apache.catalina.startup.Bootstrap`) - _ = key.SetStringValue(`Params`, state) + _ = 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 { + 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) + if err != nil { + return err + } + } + } + return nil +} + +// 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() { + +} + +// doSetDbSize 设置数据库内存大小,重启MySQL服务 +func doSetDbSize() { + stopService(service1) +} + +// setServerSize 显示设置应用内存大小界面,等待保存 +func setServerSize() { + +} + +// doSetServerSize 设置应用内存大小,重启应用服务 +func doSetServerSize() { + stopService(service3) + +} diff --git a/golang_learn/data_func/go_to_windows/serviceMonitor.ico b/golang_learn/data_func/go_to_windows/serviceMonitor.ico index 2a088ca..80e3a5c 100644 Binary files a/golang_learn/data_func/go_to_windows/serviceMonitor.ico and b/golang_learn/data_func/go_to_windows/serviceMonitor.ico differ