package main import ( "os" "os/exec" "path/filepath" "syscall" "fyne.io/fyne/v2/app" "fyne.io/fyne/v2/container" "fyne.io/fyne/v2/widget" "fyne.io/fyne/v2" ) var currentProcess *exec.Cmd // checkSingBox checks if sing-box.exe exists in the bin folder func checkSingBox() bool { singBoxPath := filepath.Join("bin", "sing-box.exe") if _, err := os.Stat(singBoxPath); os.IsNotExist(err) { return false } return true } // runSingBox starts the sing-box process with the given config path func runSingBox(configPath string) error { singBoxPath := filepath.Join("bin", "sing-box.exe") if !checkSingBox() { return nil } cmd := exec.Command(singBoxPath, "run", "-c", configPath) // Make the process run as hidden cmd.SysProcAttr = &syscall.SysProcAttr{ HideWindow: true, } err := cmd.Start() if err != nil { return err } currentProcess = cmd return nil } // killCurrentProcess terminates the current sing-box process if running func killCurrentProcess() { if currentProcess != nil && currentProcess.Process != nil { currentProcess.Process.Kill() currentProcess = nil } } func main() { myApp := app.New() myWindow := myApp.NewWindow("Hamy VPN Client") myWindow.Resize(fyne.NewSize(200, 300)) var connectButton *widget.Button var disconnectButton *widget.Button disconnectButton = widget.NewButton("Отключить", func() { killCurrentProcess() statusLabel := widget.NewLabel("Отключено") myWindow.SetContent(container.NewVBox( connectButton, disconnectButton, statusLabel, )) }) connectButton = widget.NewButton("Подключить", func() { // Check if sing-box exists if !checkSingBox() { errorLabel := widget.NewLabel("Файл bin/sing-box.exe не найден") myWindow.SetContent(container.NewVBox( connectButton, disconnectButton, errorLabel, )) return } // Run sing-box with a sample config file err := runSingBox("config.json") // Replace with actual config path if err != nil { errorLabel := widget.NewLabel("Ошибка подключения: " + err.Error()) myWindow.SetContent(container.NewVBox( connectButton, disconnectButton, errorLabel, )) return } connectLabel := widget.NewLabel("Подключено") myWindow.SetContent(container.NewVBox( connectButton, disconnectButton, connectLabel, )) }) myWindow.SetContent(container.NewVBox( connectButton, disconnectButton, )) myWindow.ShowAndRun() }