1. Подготовка ядра Sing-box (vibe-kanban 79e12836)
1. Создай папку `bin` в корне проекта. 2. Напиши логику на Go, которая проверяет наличие `bin/sing-box.exe`. 3. Напиши функцию `runSingBox(configPath string)`, которая запускает `sing-box.exe` как скрытый фоновый процесс (`os/exec`). 4. Реализуй корректное завершение процесса (Kill) при нажатии кнопки "Отключить".
This commit is contained in:
90
main.go
90
main.go
@@ -1,28 +1,114 @@
|
||||
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
|
||||
connectButton = widget.NewButton("Подключить", func() {
|
||||
connectLabel := widget.NewLabel("Подключение...")
|
||||
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()
|
||||
|
||||
Reference in New Issue
Block a user