фикс краша при отключении 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:
6
configs.json
Normal file
6
configs.json
Normal 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.
72
main.go
72
main.go
@@ -174,7 +174,10 @@ func runSingBox(configPath string) error {
|
|||||||
if currentProcess != nil && currentProcess.Process != nil {
|
if currentProcess != nil && currentProcess.Process != nil {
|
||||||
// Attempt to terminate gracefully first
|
// Attempt to terminate gracefully first
|
||||||
currentProcess.Process.Kill()
|
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
|
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
|
// 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))
|
err := cmd.Process.Signal(syscall.Signal(0))
|
||||||
return err == nil
|
return err == nil
|
||||||
}
|
}
|
||||||
@@ -220,17 +224,27 @@ func isProcessRunning(cmd *exec.Cmd) bool {
|
|||||||
// killCurrentProcess terminates the current sing-box process if running
|
// killCurrentProcess terminates the current sing-box process if running
|
||||||
func killCurrentProcess() {
|
func killCurrentProcess() {
|
||||||
processMutex.Lock()
|
processMutex.Lock()
|
||||||
defer processMutex.Unlock()
|
|
||||||
|
|
||||||
if currentProcess != nil && currentProcess.Process != nil {
|
// 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
|
// Check if the process is still running before attempting to kill it
|
||||||
if isProcessRunning(currentProcess) {
|
if isProcessRunning(cmd) {
|
||||||
// Use TerminateProcess syscall for more reliable termination on Windows
|
// Use TerminateProcess syscall for more reliable termination on Windows
|
||||||
currentProcess.Process.Kill()
|
err := cmd.Process.Kill()
|
||||||
// Wait for the process to actually terminate
|
if err != nil {
|
||||||
currentProcess.Wait()
|
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)
|
||||||
}
|
}
|
||||||
currentProcess = nil
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -562,24 +576,34 @@ func disableSystemProxy() error {
|
|||||||
func notifyProxyChange() {
|
func notifyProxyChange() {
|
||||||
// Use Windows API to notify about proxy change
|
// Use Windows API to notify about proxy change
|
||||||
// Call InternetSetOption to refresh proxy settings
|
// Call InternetSetOption to refresh proxy settings
|
||||||
procInternetSetOption := syscall.NewLazyDLL("wininet.dll").NewProc("InternetSetOptionW")
|
wininetDLL := syscall.NewLazyDLL("wininet.dll")
|
||||||
procInternetSetOption.Call(
|
if wininetDLL != nil {
|
||||||
0, // hInternet = NULL
|
procInternetSetOption := wininetDLL.NewProc("InternetSetOptionW")
|
||||||
39, // INTERNET_OPTION_SETTINGS_CHANGED
|
if procInternetSetOption != nil {
|
||||||
0, // lpBuffer = NULL
|
procInternetSetOption.Call(
|
||||||
0, // dwBufferLength = 0
|
0, // hInternet = NULL
|
||||||
)
|
39, // INTERNET_OPTION_SETTINGS_CHANGED
|
||||||
|
0, // lpBuffer = NULL
|
||||||
|
0, // dwBufferLength = 0
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Also send WM_SETTINGCHANGE to broadcast the change
|
// Also send WM_SETTINGCHANGE to broadcast the change
|
||||||
procSendMessageTimeout := syscall.NewLazyDLL("user32.dll").NewProc("SendMessageTimeoutW")
|
user32DLL := syscall.NewLazyDLL("user32.dll")
|
||||||
procSendMessageTimeout.Call(
|
if user32DLL != nil {
|
||||||
0xFFFF, // HWND_BROADCAST
|
procSendMessageTimeout := user32DLL.NewProc("SendMessageTimeoutW")
|
||||||
0x001A, // WM_SETTINGCHANGE
|
if procSendMessageTimeout != nil {
|
||||||
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr("Proxy"))),
|
procSendMessageTimeout.Call(
|
||||||
0,
|
0xFFFF, // HWND_BROADCAST
|
||||||
0x0002, // SMTO_ABORTIFHUNG
|
0x001A, // WM_SETTINGCHANGE
|
||||||
5000, // timeout
|
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr("Proxy"))),
|
||||||
)
|
0,
|
||||||
|
0x0002, // SMTO_ABORTIFHUNG
|
||||||
|
5000, // timeout
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|||||||
Reference in New Issue
Block a user