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
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"path/filepath"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
"fyne.io/fyne/v2/app"
|
"fyne.io/fyne/v2/app"
|
||||||
"fyne.io/fyne/v2/container"
|
"fyne.io/fyne/v2/container"
|
||||||
"fyne.io/fyne/v2/widget"
|
"fyne.io/fyne/v2/widget"
|
||||||
"fyne.io/fyne/v2"
|
"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() {
|
func main() {
|
||||||
myApp := app.New()
|
myApp := app.New()
|
||||||
myWindow := myApp.NewWindow("Hamy VPN Client")
|
myWindow := myApp.NewWindow("Hamy VPN Client")
|
||||||
myWindow.Resize(fyne.NewSize(200, 300))
|
myWindow.Resize(fyne.NewSize(200, 300))
|
||||||
|
|
||||||
var connectButton *widget.Button
|
var connectButton *widget.Button
|
||||||
connectButton = widget.NewButton("Подключить", func() {
|
var disconnectButton *widget.Button
|
||||||
connectLabel := widget.NewLabel("Подключение...")
|
|
||||||
|
disconnectButton = widget.NewButton("Отключить", func() {
|
||||||
|
killCurrentProcess()
|
||||||
|
|
||||||
|
statusLabel := widget.NewLabel("Отключено")
|
||||||
myWindow.SetContent(container.NewVBox(
|
myWindow.SetContent(container.NewVBox(
|
||||||
connectButton,
|
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,
|
connectLabel,
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
|
|
||||||
myWindow.SetContent(container.NewVBox(
|
myWindow.SetContent(container.NewVBox(
|
||||||
connectButton,
|
connectButton,
|
||||||
|
disconnectButton,
|
||||||
))
|
))
|
||||||
|
|
||||||
myWindow.ShowAndRun()
|
myWindow.ShowAndRun()
|
||||||
|
|||||||
Reference in New Issue
Block a user