краш фикс (vibe-kanban fd9bb887)
Сейчас реализовано подключение к vpn через конфиг. В папке bin лежит sing-box.exe. При нажатии подключить - включается прокси в windows как положено и происходит краш программы: PS C:\\Users\\hamy\\HamyDev\\HamyVPNClient\\HamyVPNClient> go run . 2026/01/16 19:53:28 Sing-box configuration written to config.json Exception 0xc0000005 0x1 0x1 0x7ffbb351b5d5 PC=0x7ffbb351b5d5 signal arrived during external code execution
This commit is contained in:
22
config.json
Normal file
22
config.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"log": {
|
||||
"level": "info"
|
||||
},
|
||||
"inbounds": [
|
||||
{
|
||||
"type": "mixed",
|
||||
"listen": "127.0.0.1",
|
||||
"listen_port": 1080,
|
||||
"set_system_proxy": true
|
||||
}
|
||||
],
|
||||
"outbounds": [
|
||||
{
|
||||
"type": "vless",
|
||||
"server": "193.124.93.179",
|
||||
"server_port": 39590,
|
||||
"uuid": "3da694cb-cca3-4849-81c3-9ff60c4dc399",
|
||||
"network": "tcp"
|
||||
}
|
||||
]
|
||||
}
|
||||
Binary file not shown.
75
main.go
75
main.go
@@ -13,6 +13,7 @@ import (
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
@@ -36,6 +37,7 @@ type Config struct {
|
||||
|
||||
var (
|
||||
currentProcess *exec.Cmd
|
||||
processMutex sync.Mutex // Mutex to protect process operations
|
||||
configs []Config // Store all configurations
|
||||
activeConfig int // Index of the active config (-1 if none)
|
||||
configFilePath string = "configs.json" // Path to save/load configs
|
||||
@@ -164,6 +166,18 @@ func runSingBox(configPath string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Acquire lock to prevent concurrent process operations
|
||||
processMutex.Lock()
|
||||
defer processMutex.Unlock()
|
||||
|
||||
// Kill any existing process before starting a new one
|
||||
if currentProcess != nil && currentProcess.Process != nil {
|
||||
// Attempt to terminate gracefully first
|
||||
currentProcess.Process.Kill()
|
||||
currentProcess.Wait() // Wait for graceful termination
|
||||
currentProcess = nil
|
||||
}
|
||||
|
||||
cmd := exec.Command(singBoxPath, "run", "-c", configPath)
|
||||
|
||||
// Make the process run as hidden
|
||||
@@ -177,13 +191,45 @@ func runSingBox(configPath string) error {
|
||||
}
|
||||
|
||||
currentProcess = cmd
|
||||
|
||||
// Start a goroutine to wait for the process to finish
|
||||
go func() {
|
||||
cmd.Wait()
|
||||
// Clear the process reference when it finishes
|
||||
processMutex.Lock()
|
||||
if currentProcess == cmd {
|
||||
currentProcess = nil
|
||||
}
|
||||
processMutex.Unlock()
|
||||
}()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// isProcessRunning checks if the process is still running
|
||||
func isProcessRunning(cmd *exec.Cmd) bool {
|
||||
if cmd == nil || cmd.Process == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
// On Windows, check if the process is still alive by getting its state
|
||||
err := cmd.Process.Signal(syscall.Signal(0))
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// killCurrentProcess terminates the current sing-box process if running
|
||||
func killCurrentProcess() {
|
||||
processMutex.Lock()
|
||||
defer processMutex.Unlock()
|
||||
|
||||
if currentProcess != nil && currentProcess.Process != nil {
|
||||
currentProcess.Process.Kill()
|
||||
// Check if the process is still running before attempting to kill it
|
||||
if isProcessRunning(currentProcess) {
|
||||
// Use TerminateProcess syscall for more reliable termination on Windows
|
||||
currentProcess.Process.Kill()
|
||||
// Wait for the process to actually terminate
|
||||
currentProcess.Wait()
|
||||
}
|
||||
currentProcess = nil
|
||||
}
|
||||
}
|
||||
@@ -452,8 +498,13 @@ func generateConfigFromVLESSURL(vlessURL, outputPath string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
var proxyMutex sync.Mutex // Mutex to protect proxy operations
|
||||
|
||||
// setSystemProxy enables the system proxy with the specified server and port
|
||||
func setSystemProxy(proxyServer string) error {
|
||||
proxyMutex.Lock()
|
||||
defer proxyMutex.Unlock()
|
||||
|
||||
key, err := registry.OpenKey(registry.CURRENT_USER, `Software\Microsoft\Windows\CurrentVersion\Internet Settings`, registry.SET_VALUE)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open registry key: %v", err)
|
||||
@@ -486,6 +537,9 @@ func setSystemProxy(proxyServer string) error {
|
||||
|
||||
// disableSystemProxy disables the system proxy
|
||||
func disableSystemProxy() error {
|
||||
proxyMutex.Lock()
|
||||
defer proxyMutex.Unlock()
|
||||
|
||||
key, err := registry.OpenKey(registry.CURRENT_USER, `Software\Microsoft\Windows\CurrentVersion\Internet Settings`, registry.SET_VALUE)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open registry key: %v", err)
|
||||
@@ -594,12 +648,18 @@ func main() {
|
||||
return
|
||||
}
|
||||
|
||||
// Prevent multiple simultaneous connection attempts
|
||||
connectButton.Disable()
|
||||
defer connectButton.Enable() // Re-enable the button after the operation completes
|
||||
|
||||
// Toggle connection state
|
||||
if !isConnected {
|
||||
// Connect - generate config and run sing-box
|
||||
err := generateAndRunSingBox(configs[activeConfig].URL)
|
||||
if err != nil {
|
||||
log.Printf("Failed to start connection: %v", err)
|
||||
dialog.ShowError(fmt.Errorf("failed to start connection: %v", err), myWindow)
|
||||
|
||||
// Revert connection state on failure
|
||||
isConnected = false
|
||||
updateConnectionButtonText(connectButton)
|
||||
@@ -614,6 +674,15 @@ func main() {
|
||||
if err != nil {
|
||||
log.Printf("Failed to set system proxy: %v", err)
|
||||
dialog.ShowError(fmt.Errorf("failed to set system proxy: %v", err), myWindow)
|
||||
|
||||
// If proxy failed to set, kill the sing-box process and revert connection
|
||||
killCurrentProcess()
|
||||
isConnected = false
|
||||
updateConnectionButtonText(connectButton)
|
||||
statusLabel.Text = "Отключено"
|
||||
statusLabel.Color = color.RGBA{R: 128, G: 128, B: 128, A: 255}
|
||||
statusLabel.Refresh()
|
||||
return
|
||||
}
|
||||
|
||||
// Update connection state after successful connection
|
||||
@@ -808,9 +877,7 @@ func main() {
|
||||
// Register an app lifecycle listener to handle cleanup when the app exits
|
||||
myApp.Lifecycle().SetOnStopped(func() {
|
||||
// Kill the current process if running
|
||||
if currentProcess != nil && currentProcess.Process != nil {
|
||||
currentProcess.Process.Kill()
|
||||
}
|
||||
killCurrentProcess()
|
||||
|
||||
// Disable proxy when the application exits
|
||||
err := disableSystemProxy()
|
||||
|
||||
Reference in New Issue
Block a user