фикс краша при отключении vpn (vibe-kanban 4dcd8b1b)

У нас реализовано подключение к vpn и оно отлично работает. Но при нажатии на кнопку отключить происходит краш:
PS C:\\Users\\hamy\\HamyDev\\HamyVPNClient\\HamyVPNClient> go run .

2026/01/16 20:01:32 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:
Vibe Kanban
2026-01-16 20:12:04 +03:00
parent 1f54670e3e
commit a0d76586a9
3 changed files with 54 additions and 24 deletions

6
configs.json Normal file
View File

@@ -0,0 +1,6 @@
[
{
"Title": "Конфиг 1",
"URL": "vless://3da694cb-cca3-4849-81c3-9ff60c4dc399@193.124.93.179:39590?type=tcp\u0026encryption=none\u0026security=none#TCP%20HamyVPN-TEST2"
}
]

Binary file not shown.

48
main.go
View File

@@ -174,7 +174,10 @@ func runSingBox(configPath string) error {
if currentProcess != nil && currentProcess.Process != nil {
// Attempt to terminate gracefully first
currentProcess.Process.Kill()
currentProcess.Wait() // Wait for graceful termination
// Wait for the process to finish in a separate goroutine to avoid blocking
go func(p *exec.Cmd) {
p.Wait() // Wait for graceful termination
}(currentProcess)
currentProcess = nil
}
@@ -213,6 +216,7 @@ func isProcessRunning(cmd *exec.Cmd) bool {
}
// On Windows, check if the process is still alive by getting its state
// Using syscall.Signal(0) just checks if we can send a signal (process exists)
err := cmd.Process.Signal(syscall.Signal(0))
return err == nil
}
@@ -220,17 +224,27 @@ func isProcessRunning(cmd *exec.Cmd) bool {
// killCurrentProcess terminates the current sing-box process if running
func killCurrentProcess() {
processMutex.Lock()
defer processMutex.Unlock()
if currentProcess != nil && currentProcess.Process != nil {
// 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()
}
// Create a local copy of the current process to avoid race conditions
cmd := currentProcess
currentProcess = nil
processMutex.Unlock()
if cmd != nil && cmd.Process != nil {
// Check if the process is still running before attempting to kill it
if isProcessRunning(cmd) {
// Use TerminateProcess syscall for more reliable termination on Windows
err := cmd.Process.Kill()
if err != nil {
log.Printf("Error killing process: %v", err)
}
// Wait for the process to actually terminate in a separate goroutine to avoid blocking
go func(p *exec.Cmd) {
p.Wait() // Wait for the process to finish
}(cmd)
}
}
}
@@ -562,16 +576,24 @@ func disableSystemProxy() error {
func notifyProxyChange() {
// Use Windows API to notify about proxy change
// Call InternetSetOption to refresh proxy settings
procInternetSetOption := syscall.NewLazyDLL("wininet.dll").NewProc("InternetSetOptionW")
wininetDLL := syscall.NewLazyDLL("wininet.dll")
if wininetDLL != nil {
procInternetSetOption := wininetDLL.NewProc("InternetSetOptionW")
if procInternetSetOption != nil {
procInternetSetOption.Call(
0, // hInternet = NULL
39, // INTERNET_OPTION_SETTINGS_CHANGED
0, // lpBuffer = NULL
0, // dwBufferLength = 0
)
}
}
// Also send WM_SETTINGCHANGE to broadcast the change
procSendMessageTimeout := syscall.NewLazyDLL("user32.dll").NewProc("SendMessageTimeoutW")
user32DLL := syscall.NewLazyDLL("user32.dll")
if user32DLL != nil {
procSendMessageTimeout := user32DLL.NewProc("SendMessageTimeoutW")
if procSendMessageTimeout != nil {
procSendMessageTimeout.Call(
0xFFFF, // HWND_BROADCAST
0x001A, // WM_SETTINGCHANGE
@@ -580,6 +602,8 @@ func notifyProxyChange() {
0x0002, // SMTO_ABORTIFHUNG
5000, // timeout
)
}
}
}
func main() {