// vpnem-installer: Windows offline installer (GUI, no console window). // Bundles all binaries — no network download needed. // Installs to Program Files, creates Task Scheduler task for UAC-free launch. // Requires admin (one-time). Supports silent mode: vpnem-installer.exe /S // Cross-compiles from Linux with -ldflags "-H windowsgui" package main import ( "embed" "fmt" "log" "os" "os/exec" "path/filepath" "strings" "time" ) //go:embed files/* var bundledFiles embed.FS const ( installDir = `C:\Program Files\vpnem` dataDir = `C:\ProgramData\vpnem` taskName = "vpnem" baseURL = "https://vpn.em-sysadmin.xyz/releases" vpnemURL = baseURL + "/vpnem-windows-amd64.exe" ) var ( silent bool noShortcut bool launch bool logFile *os.File ) func main() { // Parse flags for _, arg := range os.Args[1:] { a := strings.ToLower(strings.TrimLeft(arg, "/-")) switch a { case "s", "silent": silent = true case "noshortcut": noShortcut = true case "launch": launch = true } } if !isElevated() { if err := relaunchElevated(); err != nil { fatal("request administrator privileges: %v", err) } return } // 1. Kill ALL running instances immediately step("stopping running instances") exec.Command("taskkill", "/F", "/IM", "vpnem.exe").Run() exec.Command("taskkill", "/F", "/IM", "sing-box.exe").Run() time.Sleep(2 * time.Second) // 2. Remove OLD installation directories completely (clean slate) step("removing old installation") if err := os.RemoveAll(installDir); err != nil { log.Printf("warning: could not remove old install dir: %v", err) } if err := os.RemoveAll(dataDir); err != nil { log.Printf("warning: could not remove old data dir: %v", err) } // Also remove old ProxySwitcher if exists os.RemoveAll(`C:\ProxySwitcher`) // 3. Create fresh directories if err := os.MkdirAll(installDir, 0o755); err != nil { fatal("create install dir: %v", err) } if err := os.MkdirAll(dataDir, 0o755); err != nil { fatal("create data dir: %v", err) } // Write bundled files instead of downloading step("extracting bundled vpnem.exe") if err := writeEmbedded("files/vpnem.exe", filepath.Join(installDir, "vpnem.exe")); err != nil { fatal("extract vpnem.exe: %v", err) } step("extracting bundled sing-box.exe") if err := writeEmbedded("files/sing-box.exe", filepath.Join(installDir, "sing-box.exe")); err != nil { fatal("extract sing-box.exe: %v", err) } step("extracting bundled wintun.dll") if err := writeEmbedded("files/wintun.dll", filepath.Join(installDir, "wintun.dll")); err != nil { fatal("extract wintun.dll: %v", err) } // Create Task Scheduler task — runs vpnem as admin WITHOUT UAC prompt. // This is the key: task created by admin runs with highest privileges silently. step("creating scheduled task (UAC-free launch)") createTask() // Desktop shortcut — launches via schtasks (no UAC popup) if !noShortcut { step("creating desktop shortcut") createShortcut() } step("installation complete") if launch { step("launching vpnem") exec.Command("schtasks", "/Run", "/TN", taskName).Run() } if !silent { showDoneMessage() } } // createTask sets up a scheduled task that: // 1. Runs vpnem.exe with highest privileges (no UAC) // 2. Starts at logon with 15s delay (autostart) // The same task is used for both manual launch and autostart. func createTask() { exec.Command("schtasks", "/Delete", "/TN", taskName, "/F").Run() // Create XML task definition for full control exePath := filepath.Join(installDir, "vpnem.exe") xml := fmt.Sprintf(` vpnem VPN client true PT15S InteractiveToken HighestAvailable IgnoreNew false false PT0S true true %s --data "%s" %s `, exePath, dataDir, installDir) xmlPath := filepath.Join(dataDir, "task.xml") os.WriteFile(xmlPath, []byte(xml), 0o644) cmd := exec.Command("schtasks", "/Create", "/TN", taskName, "/XML", xmlPath, "/F") out, err := cmd.CombinedOutput() if err != nil { log.Printf("task create failed: %v\n%s", err, string(out)) } else { log.Println("task created ok") } os.Remove(xmlPath) } // createShortcut makes a desktop shortcut that runs the scheduled task (no UAC) // IconLocation points to vpnem.exe so the shortcut has the app icon func createShortcut() { exePath := filepath.Join(installDir, "vpnem.exe") ps := ` $ws = New-Object -ComObject WScript.Shell $s = $ws.CreateShortcut("$env:USERPROFILE\Desktop\vpnem.lnk") $s.TargetPath = "schtasks.exe" $s.Arguments = "/Run /TN vpnem" $s.WorkingDirectory = "` + installDir + `" $s.IconLocation = "` + exePath + `,0" $s.Description = "vpnem VPN client" $s.Save() ` cmd := exec.Command("powershell", "-NoProfile", "-WindowStyle", "Hidden", "-Command", ps) if err := cmd.Run(); err != nil { log.Printf("shortcut failed: %v (non-critical)", err) } } func step(msg string) { log.Println(msg) } func writeEmbedded(name, dest string) error { data, err := bundledFiles.ReadFile(name) if err != nil { return fmt.Errorf("read embedded file %s: %w", name, err) } tmp := dest + ".tmp" if err := os.WriteFile(tmp, data, 0o755); err != nil { return fmt.Errorf("write %s: %w", dest, err) } info, _ := os.Stat(tmp) log.Printf(" %s (%.1f MB)", filepath.Base(dest), float64(info.Size())/1024/1024) return os.Rename(tmp, dest) } func fatal(format string, args ...any) { msg := fmt.Sprintf(format, args...) log.Printf("FATAL: %s", msg) if silent { os.Exit(1) } showError(msg) os.Exit(1) } func showDoneMessage() { msg := fmt.Sprintf("vpnem installed to %s\\n\\nDesktop shortcut created.\\nAutostart at logon enabled.\\n\\nNo admin prompts needed to launch.", installDir) exec.Command("powershell", "-NoProfile", "-WindowStyle", "Hidden", "-Command", fmt.Sprintf(`Add-Type -AssemblyName System.Windows.Forms; [System.Windows.Forms.MessageBox]::Show("%s", "vpnem installer", "OK", "Information")`, msg), ).Run() } func showError(msg string) { exec.Command("powershell", "-NoProfile", "-WindowStyle", "Hidden", "-Command", fmt.Sprintf(`Add-Type -AssemblyName System.Windows.Forms; [System.Windows.Forms.MessageBox]::Show("Installation failed:\n%s", "vpnem installer", "OK", "Error")`, msg), ).Run() }