feat: splitting platforms and maybe fixing shortcut installations as well as admin privileges

This commit is contained in:
2026-09-27 15:52:55 +02:00
parent 061cf03277
commit 231ce0767d
7 changed files with 663 additions and 330 deletions
+130
View File
@@ -0,0 +1,130 @@
//go:build windows
package main
import (
"errors"
"fmt"
"os"
"os/exec"
"path/filepath"
"syscall"
"unsafe"
)
var (
shell32 = syscall.NewLazyDLL("shell32.dll")
shellExecuteExW = shell32.NewProc("ShellExecuteExW")
)
const (
seeMaskNocloseprocess = 0x00000040
)
type shellExecuteInfo struct {
cbSize uint32
fMask uint32
hwnd uintptr
lpVerb *uint16
lpFile *uint16
lpParameters *uint16
lpDirectory *uint16
nShow int32
hInstApp uintptr
lpIDList uintptr
lpClass *uint16
hkeyClass uintptr
dwHotKey uint32
hIcon uintptr
hProcess uintptr
}
func getInstallDir() (string, error) {
programFiles := os.Getenv("ProgramFiles")
if programFiles == "" {
return "", errors.New("ProgramFiles ist nicht gesetzt")
}
return filepath.Join(programFiles, "logofclient"), nil
}
func platformRunPrivileged(config Config, action string) error {
if isWindowsAdmin() {
return runAction(config, action)
}
return runElevated(action)
}
func isWindowsAdmin() bool {
// Ein einfacher und robuster Test:
// Versuch, in das Windows-Systemverzeichnis zu schreiben.
//
// Da wir dort natürlich nichts verändern wollen, verwenden wir
// stattdessen "net session". Der Befehl funktioniert nur mit
// Administratorrechten.
cmd := exec.Command("net", "session")
cmd.Stdout = nil
cmd.Stderr = nil
return cmd.Run() == nil
}
func runElevated(action string) error {
exe, err := os.Executable()
if err != nil {
return fmt.Errorf("Pfad des Installers konnte nicht ermittelt werden: %w", err)
}
verb, err := syscall.UTF16PtrFromString("runas")
if err != nil {
return err
}
file, err := syscall.UTF16PtrFromString(exe)
if err != nil {
return err
}
parameters, err := syscall.UTF16PtrFromString(action)
if err != nil {
return err
}
info := shellExecuteInfo{
cbSize: uint32(unsafe.Sizeof(shellExecuteInfo{})),
fMask: seeMaskNocloseprocess,
lpVerb: verb,
lpFile: file,
lpParameters: parameters,
nShow: 1, // SW_SHOWNORMAL
}
ret, _, callErr := shellExecuteExW.Call(uintptr(unsafe.Pointer(&info)))
if ret == 0 {
// ERROR_CANCELLED = 1223:
// Benutzer hat den UAC-Dialog abgebrochen.
if errno, ok := callErr.(syscall.Errno); ok && errno == 1223 {
fmt.Println("Administratorrechte wurden nicht erteilt.")
return nil
}
return fmt.Errorf("Administratorrechte konnten nicht angefordert werden: %w", callErr)
}
// Auf die erhöhte Instanz warten.
if info.hProcess != 0 {
handle := syscall.Handle(info.hProcess)
defer syscall.CloseHandle(handle)
_, err := syscall.WaitForSingleObject(handle, syscall.INFINITE)
if err != nil {
return fmt.Errorf("auf erhöhte Instanz konnte nicht gewartet werden: %w", err)
}
}
return nil
}