diff options
| author | sergei <sergei@em-sysadmin.xyz> | 2026-04-14 06:23:55 +0400 |
|---|---|---|
| committer | sergei <sergei@em-sysadmin.xyz> | 2026-04-14 06:23:55 +0400 |
| commit | 3d51aa455006903345f554a2dd90034993796114 (patch) | |
| tree | 62a7be2faf047f5eb7886feebc3b815556f03d7f /cmd/installer/elevate_windows.go | |
| download | vpnem-main.tar.gz vpnem-main.tar.bz2 vpnem-main.zip | |
- Multi-protocol VPS nodes (VLESS-REALITY + Hysteria2 + SOCKS5)
- Smart load balancing via recommendation API
- Windows/Linux client (Go + Wails + sing-box)
- Server API with RealIP detection and connection tracking
- Auto-deployment via vpnui control plane
- Silent Windows installer with UAC elevation
- Load-based server recommendation (no sticky sessions)
- Best Server one-click connection workflow
Diffstat (limited to 'cmd/installer/elevate_windows.go')
| -rw-r--r-- | cmd/installer/elevate_windows.go | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/cmd/installer/elevate_windows.go b/cmd/installer/elevate_windows.go new file mode 100644 index 0000000..f174390 --- /dev/null +++ b/cmd/installer/elevate_windows.go @@ -0,0 +1,74 @@ +//go:build windows + +package main + +import ( + "fmt" + "os" + "strings" + "syscall" + "unsafe" +) + +var ( + shell32 = syscall.NewLazyDLL("shell32.dll") + shellExecuteW = shell32.NewProc("ShellExecuteW") + isUserAnAdminProc = shell32.NewProc("IsUserAnAdmin") + errCancelledByUser = uintptr(1223) +) + +func isElevated() bool { + ret, _, _ := isUserAnAdminProc.Call() + return ret != 0 +} + +func relaunchElevated() error { + exePath, err := os.Executable() + if err != nil { + return err + } + + verb, err := syscall.UTF16PtrFromString("runas") + if err != nil { + return err + } + file, err := syscall.UTF16PtrFromString(exePath) + if err != nil { + return err + } + args, err := syscall.UTF16PtrFromString(joinWindowsArgs(os.Args[1:])) + if err != nil { + return err + } + + ret, _, callErr := shellExecuteW.Call( + 0, + uintptr(unsafe.Pointer(verb)), + uintptr(unsafe.Pointer(file)), + uintptr(unsafe.Pointer(args)), + 0, + 1, + ) + if ret <= 32 { + if ret == errCancelledByUser { + return fmt.Errorf("administrator privileges were not granted") + } + if callErr != syscall.Errno(0) { + return fmt.Errorf("ShellExecuteW failed: %w", callErr) + } + return fmt.Errorf("ShellExecuteW failed with code %d", ret) + } + return nil +} + +func joinWindowsArgs(args []string) string { + if len(args) == 0 { + return "" + } + quoted := make([]string, 0, len(args)) + for _, arg := range args { + escaped := strings.ReplaceAll(arg, `"`, `\"`) + quoted = append(quoted, `"`+escaped+`"`) + } + return strings.Join(quoted, " ") +} |
