Skip to content

Commit 75fe383

Browse files
committed
Release v1.9.9
1 parent 6ae6a15 commit 75fe383

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+551
-506
lines changed

bridge/bridge.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ var Env = &EnvResult{
2727
IsStartup: true,
2828
FromTaskSch: false,
2929
AppName: "",
30+
AppVersion: "v1.9.9",
3031
BasePath: "",
3132
OS: sysruntime.GOOS,
3233
ARCH: sysruntime.GOARCH,
@@ -92,11 +93,12 @@ func (a *App) RestartApp() FlagResult {
9293

9394
func (a *App) GetEnv() EnvResult {
9495
return EnvResult{
95-
AppName: Env.AppName,
96-
BasePath: Env.BasePath,
97-
OS: Env.OS,
98-
ARCH: Env.ARCH,
99-
X64Level: Env.X64Level,
96+
AppName: Env.AppName,
97+
AppVersion: Env.AppVersion,
98+
BasePath: Env.BasePath,
99+
OS: Env.OS,
100+
ARCH: Env.ARCH,
101+
X64Level: Env.X64Level,
100102
}
101103
}
102104

@@ -139,7 +141,7 @@ func createMacOSMenus(app *App) {
139141
})
140142
appMenu.AddSeparator()
141143
appMenu.AddText("Quit", keys.CmdOrCtrl("q"), func(_ *menu.CallbackData) {
142-
runtime.EventsEmit(app.Ctx, "exitApp")
144+
runtime.EventsEmit(app.Ctx, "onExitApp")
143145
})
144146

145147
// on macos platform, we should append EditMenu to enable Cmd+C,Cmd+V,Cmd+Z... shortcut

bridge/exec.go

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package bridge
22

33
import (
44
"bufio"
5-
"errors"
5+
"context"
66
"fmt"
77
"io"
88
"log"
@@ -142,23 +142,28 @@ func (a *App) KillProcess(pid int, timeout int) FlagResult {
142142
}
143143

144144
func waitForProcessExitWithTimeout(process *os.Process, timeoutSeconds int) error {
145-
done := make(chan error, 1)
146-
go func() {
147-
_, err := process.Wait()
148-
done <- err
149-
}()
150-
151-
timer := time.NewTimer(time.Duration(timeoutSeconds) * time.Second)
152-
defer timer.Stop()
153-
154-
select {
155-
case err := <-done:
156-
return err
157-
case <-timer.C:
158-
if killErr := process.Kill(); killErr != nil {
159-
return fmt.Errorf("timeout reached and failed to kill process: %w", killErr)
145+
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeoutSeconds)*time.Second)
146+
defer cancel()
147+
148+
ticker := time.NewTicker(500 * time.Millisecond)
149+
defer ticker.Stop()
150+
151+
for {
152+
select {
153+
case <-ctx.Done():
154+
if killErr := process.Kill(); killErr != nil {
155+
return fmt.Errorf("timed out after %d seconds waiting for process %d, and failed to kill it: %w", timeoutSeconds, process.Pid, killErr)
156+
}
157+
return nil
158+
159+
case <-ticker.C:
160+
alive, err := IsProcessAlive(process)
161+
if err != nil {
162+
return fmt.Errorf("failed to check status of process %d: %w", process.Pid, err)
163+
}
164+
if !alive {
165+
return nil
166+
}
160167
}
161-
<-done
162-
return errors.New("timeout waiting for process to exit")
163168
}
164169
}

bridge/exec_others.go

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
package bridge
44

55
import (
6+
"errors"
7+
"fmt"
68
"os"
79
"os/exec"
810
"syscall"
@@ -11,6 +13,25 @@ import (
1113
func SetCmdWindowHidden(cmd *exec.Cmd) {
1214
}
1315

14-
func SendExitSignal(process *os.Process) error {
15-
return process.Signal(syscall.SIGINT)
16+
func SendExitSignal(p *os.Process) error {
17+
return p.Signal(syscall.SIGINT)
18+
}
19+
20+
func IsProcessAlive(p *os.Process) (bool, error) {
21+
err := p.Signal(syscall.Signal(0))
22+
if err == nil {
23+
return true, nil
24+
}
25+
if errors.Is(err, os.ErrProcessDone) {
26+
return false, nil
27+
}
28+
if errno, ok := err.(syscall.Errno); ok {
29+
switch errno {
30+
case syscall.ESRCH:
31+
return false, nil
32+
case syscall.EPERM:
33+
return true, nil
34+
}
35+
}
36+
return false, fmt.Errorf("failed to check process %d: %w", p.Pid, err)
1637
}

bridge/exec_windows.go

Lines changed: 42 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,25 @@
33
package bridge
44

55
import (
6+
"fmt"
67
"os"
78
"os/exec"
89
"syscall"
910

1011
"golang.org/x/sys/windows"
1112
)
1213

14+
const ATTACH_PARENT_PROCESS uintptr = ^uintptr(0)
15+
16+
var (
17+
modKernel32 = windows.NewLazySystemDLL("kernel32.dll")
18+
19+
procFreeConsole = modKernel32.NewProc("FreeConsole")
20+
procAttachConsole = modKernel32.NewProc("AttachConsole")
21+
procSetConsoleCtrlHandler = modKernel32.NewProc("SetConsoleCtrlHandler")
22+
procGenerateConsoleCtrlEvent = modKernel32.NewProc("GenerateConsoleCtrlEvent")
23+
)
24+
1325
func SetCmdWindowHidden(cmd *exec.Cmd) {
1426
cmd.SysProcAttr = &syscall.SysProcAttr{
1527
CreationFlags: windows.CREATE_UNICODE_ENVIRONMENT | windows.CREATE_NEW_PROCESS_GROUP,
@@ -18,46 +30,49 @@ func SetCmdWindowHidden(cmd *exec.Cmd) {
1830
}
1931

2032
func SendExitSignal(p *os.Process) error {
21-
kernel32DLL, err := windows.LoadDLL("kernel32.dll")
22-
if err != nil {
33+
if ret, _, err := procFreeConsole.Call(); ret == 0 && err != windows.ERROR_INVALID_HANDLE {
2334
return err
2435
}
25-
defer kernel32DLL.Release()
2636

27-
freeConsoleProc, err := kernel32DLL.FindProc("FreeConsole")
28-
if err == nil {
29-
if result, _, err := freeConsoleProc.Call(); result == 0 {
30-
if err != windows.ERROR_INVALID_HANDLE {
31-
return err
32-
}
33-
}
34-
}
37+
defer func() {
38+
procAttachConsole.Call(ATTACH_PARENT_PROCESS)
39+
}()
3540

36-
attachConsoleProc, err := kernel32DLL.FindProc("AttachConsole")
37-
if err != nil {
41+
if ret, _, err := procAttachConsole.Call(uintptr(p.Pid)); ret == 0 && err != windows.ERROR_ACCESS_DENIED {
3842
return err
3943
}
40-
if result, _, err := attachConsoleProc.Call(uintptr(p.Pid)); result == 0 {
41-
if err != windows.ERROR_ACCESS_DENIED {
42-
return err
43-
}
44-
}
4544

46-
setConsoleCtrlHandlerProc, err := kernel32DLL.FindProc("SetConsoleCtrlHandler")
47-
if err != nil {
45+
if ret, _, err := procSetConsoleCtrlHandler.Call(0, 1); ret == 0 {
4846
return err
4947
}
50-
if result, _, err := setConsoleCtrlHandlerProc.Call(0, 1); result == 0 {
48+
49+
if ret, _, err := procGenerateConsoleCtrlEvent.Call(windows.CTRL_BREAK_EVENT, uintptr(p.Pid)); ret == 0 {
5150
return err
5251
}
5352

54-
generateConsoleCtrlEventProc, err := kernel32DLL.FindProc("GenerateConsoleCtrlEvent")
53+
return nil
54+
}
55+
56+
func IsProcessAlive(p *os.Process) (bool, error) {
57+
h, err := windows.OpenProcess(windows.SYNCHRONIZE, false, uint32(p.Pid))
5558
if err != nil {
56-
return err
57-
}
58-
if result, _, err := generateConsoleCtrlEventProc.Call(windows.CTRL_BREAK_EVENT, uintptr(p.Pid)); result == 0 {
59-
return err
59+
if err == windows.ERROR_INVALID_PARAMETER {
60+
return false, nil
61+
}
62+
return false, err
6063
}
64+
defer windows.CloseHandle(h)
6165

62-
return nil
66+
s, err := windows.WaitForSingleObject(h, 0)
67+
if err != nil {
68+
return false, err
69+
}
70+
switch s {
71+
case windows.WAIT_OBJECT_0:
72+
return false, nil
73+
case uint32(windows.WAIT_TIMEOUT):
74+
return true, nil
75+
default:
76+
return false, fmt.Errorf("unexpected WaitForSingleObject status: %d", s)
77+
}
6378
}

bridge/io.go

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ const (
1818
Text = "Text"
1919
)
2020

21-
func (a *App) Writefile(path string, content string, options IOOptions) FlagResult {
22-
log.Printf("Writefile [%s]: %s", options.Mode, path)
21+
func (a *App) WriteFile(path string, content string, options IOOptions) FlagResult {
22+
log.Printf("WriteFile [%s]: %s", options.Mode, path)
2323

2424
fullPath := GetPath(path)
2525

@@ -49,8 +49,8 @@ func (a *App) Writefile(path string, content string, options IOOptions) FlagResu
4949
return FlagResult{true, "Success"}
5050
}
5151

52-
func (a *App) Readfile(path string, options IOOptions) FlagResult {
53-
log.Printf("Readfile [%s]: %s", options.Mode, path)
52+
func (a *App) ReadFile(path string, options IOOptions) FlagResult {
53+
log.Printf("ReadFile [%s]: %s", options.Mode, path)
5454

5555
fullPath := GetPath(path)
5656

@@ -69,8 +69,8 @@ func (a *App) Readfile(path string, options IOOptions) FlagResult {
6969
}
7070
}
7171

72-
func (a *App) Movefile(source string, target string) FlagResult {
73-
log.Printf("Movefile: %s -> %s", source, target)
72+
func (a *App) MoveFile(source string, target string) FlagResult {
73+
log.Printf("MoveFile: %s -> %s", source, target)
7474

7575
fullSource := GetPath(source)
7676
fullTarget := GetPath(target)
@@ -86,7 +86,7 @@ func (a *App) Movefile(source string, target string) FlagResult {
8686
return FlagResult{true, "Success"}
8787
}
8888

89-
func (a *App) Removefile(path string) FlagResult {
89+
func (a *App) RemoveFile(path string) FlagResult {
9090
log.Printf("RemoveFile: %s", path)
9191

9292
fullPath := GetPath(path)
@@ -98,8 +98,8 @@ func (a *App) Removefile(path string) FlagResult {
9898
return FlagResult{true, "Success"}
9999
}
100100

101-
func (a *App) Copyfile(src string, dst string) FlagResult {
102-
log.Printf("Copyfile: %s -> %s", src, dst)
101+
func (a *App) CopyFile(src string, dst string) FlagResult {
102+
log.Printf("CopyFile: %s -> %s", src, dst)
103103

104104
srcPath := GetPath(src)
105105
dstPath := GetPath(dst)
@@ -127,8 +127,8 @@ func (a *App) Copyfile(src string, dst string) FlagResult {
127127
return FlagResult{true, "Success"}
128128
}
129129

130-
func (a *App) Makedir(path string) FlagResult {
131-
log.Printf("Makedir: %s", path)
130+
func (a *App) MakeDir(path string) FlagResult {
131+
log.Printf("MakeDir: %s", path)
132132

133133
fullPath := GetPath(path)
134134

@@ -139,8 +139,8 @@ func (a *App) Makedir(path string) FlagResult {
139139
return FlagResult{true, "Success"}
140140
}
141141

142-
func (a *App) Readdir(path string) FlagResult {
143-
log.Printf("Readdir: %s", path)
142+
func (a *App) ReadDir(path string) FlagResult {
143+
log.Printf("ReadDir: %s", path)
144144

145145
fullPath := GetPath(path)
146146

bridge/types.go

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ type EnvResult struct {
1717
IsStartup bool `json:"-"`
1818
FromTaskSch bool `json:"-"`
1919
AppName string `json:"appName"`
20+
AppVersion string `json:"appVersion"`
2021
BasePath string `json:"basePath"`
2122
OS string `json:"os"`
2223
ARCH string `json:"arch"`
@@ -33,9 +34,9 @@ type RequestOptions struct {
3334
}
3435

3536
type ExecOptions struct {
36-
StopOutputKeyword string `json:"stopOutputKeyword"`
37-
Convert bool `json:"convert"`
38-
Env map[string]string `json:"env"`
37+
StopOutputKeyword string
38+
Convert bool
39+
Env map[string]string
3940
}
4041

4142
type IOOptions struct {
@@ -48,18 +49,18 @@ type FlagResult struct {
4849
}
4950

5051
type ServerOptions struct {
51-
Cert string `json:"Cert"`
52-
Key string `json:"Key"`
53-
StaticPath string `json:"StaticPath"`
54-
StaticRoute string `json:"StaticRoute"`
55-
UploadPath string `json:"UploadPath"`
56-
UploadRoute string `json:"UploadRoute"`
57-
MaxUploadSize int64 `json:"MaxUploadSize"`
52+
Cert string
53+
Key string
54+
StaticPath string
55+
StaticRoute string
56+
UploadPath string
57+
UploadRoute string
58+
MaxUploadSize int64
5859
}
5960

6061
type NotifyOptions struct {
61-
AppName string `json:"AppName"`
62-
Beep bool `json:"Beep"`
62+
AppName string
63+
Beep bool
6364
}
6465

6566
type HTTPResult struct {

frontend/.env

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
VITE_APP_TITLE = GUI.for.Clash
2-
VITE_APP_VERSION = v1.9.8
2+
VITE_APP_VERSION = v1.9.9
33
VITE_APP_PROJECT_URL = https://github.com/GUI-for-Cores
44
VITE_APP_VERSION_API = https://api.github.com/repos/GUI-for-Cores/GUI.for.Clash/releases/latest
55
VITE_APP_TG_GROUP = https://t.me/GUI_for_Cores

0 commit comments

Comments
 (0)