Fix Windows installer

This commit is contained in:
Zoltán Papp
2025-10-14 17:15:22 +02:00
parent 18f884f769
commit 9313b49625
3 changed files with 53 additions and 36 deletions

View File

@@ -7,7 +7,6 @@ import (
"net/http"
"os"
"path/filepath"
"runtime"
"strings"
"sync"
"time"
@@ -381,9 +380,3 @@ func downloadFileToTemporaryDir(ctx context.Context, fileURL string) (string, er
success = true // Mark success to prevent cleanup
return out.Name(), nil
}
func urlWithVersionArch(url, version string) string { //nolint:unused
url = strings.ReplaceAll(url, "%version", version)
url = strings.ReplaceAll(url, "%arch", runtime.GOARCH)
return url
}

View File

@@ -8,6 +8,7 @@ import (
"os"
"os/exec"
"os/user"
"runtime"
"strings"
"syscall"
)
@@ -25,7 +26,7 @@ func (u *UpdateManager) triggerUpdate(ctx context.Context, targetVersion string)
return updateHomeBrew(ctx)
}
// Installed using pkg file
path, err := downloadFileToTemporaryDir(ctx, urlWithVersionArch(pkgDownloadURL, targetVersion))
path, err := downloadFileToTemporaryDir(ctx, urlWithVersionArch(targetVersion))
if err != nil {
return fmt.Errorf("error downloading update file: %w", err)
}
@@ -110,3 +111,8 @@ func updateHomeBrew(ctx context.Context) error {
return nil
}
func urlWithVersionArch(version string) string {
url := strings.ReplaceAll(pkgDownloadURL, "%version", version)
return strings.ReplaceAll(url, "%arch", runtime.GOARCH)
}

View File

@@ -4,12 +4,13 @@ package updatemanager
import (
"context"
"fmt"
"os/exec"
"golang.org/x/sys/windows/registry"
"runtime"
"strings"
"syscall"
log "github.com/sirupsen/logrus"
"golang.org/x/sys/windows/registry"
)
const (
@@ -17,26 +18,24 @@ const (
exeDownloadURL = "https://github.com/netbirdio/netbird/releases/download/v%version/netbird_installer_%version_windows_%arch.exe"
uninstallKeyPath64 = `SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Netbird`
uninstallKeyPath32 = `SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Netbird`
installerEXE installerType = "EXE"
installerMSI installerType = "MSI"
)
type installerType string
func (u *UpdateManager) triggerUpdate(ctx context.Context, targetVersion string) error {
method := installation()
switch method {
case "EXE":
return updateEXE(ctx, targetVersion)
case "MSI":
return updateMSI(ctx, targetVersion)
default:
return fmt.Errorf("unsupported installation method: %s", method)
}
return install(ctx, method, targetVersion)
}
func installation() string {
func installation() installerType {
k, err := registry.OpenKey(registry.LOCAL_MACHINE, uninstallKeyPath64, registry.QUERY_VALUE)
if err != nil {
k, err = registry.OpenKey(registry.LOCAL_MACHINE, uninstallKeyPath32, registry.QUERY_VALUE)
if err != nil {
return "MSI"
return installerMSI
} else {
err = k.Close()
if err != nil {
@@ -49,30 +48,49 @@ func installation() string {
log.Warnf("Error closing registry key: %v", err)
}
}
return "EXE"
return installerEXE
}
func updateMSI(ctx context.Context, targetVersion string) error {
path, err := downloadFileToTemporaryDir(ctx, urlWithVersionArch(msiDownloadURL, targetVersion))
func install(ctx context.Context, installerType installerType, targetVersion string) error {
path, err := downloadFileToTemporaryDir(ctx, urlWithVersionArch(installerType, targetVersion))
if err != nil {
return err
}
cmd := exec.CommandContext(ctx, "msiexec", "/quiet", "/i", path)
err = cmd.Run()
return err
}
log.Infof("start installation %s", path)
func updateEXE(ctx context.Context, targetVersion string) error {
path, err := downloadFileToTemporaryDir(ctx, urlWithVersionArch(exeDownloadURL, targetVersion))
if err != nil {
var cmd *exec.Cmd
if installerType == installerEXE {
cmd = exec.CommandContext(ctx, path, "/S")
} else {
cmd = exec.CommandContext(ctx, "msiexec", "/quiet", "/i", path)
}
// Detach the process from the parent
cmd.SysProcAttr = &syscall.SysProcAttr{
CreationFlags: syscall.CREATE_NEW_PROCESS_GROUP | 0x00000008, // 0x00000008 is DETACHED_PROCESS
}
if err := cmd.Start(); err != nil {
log.Errorf("error starting installer: %v", err)
return err
}
cmd := exec.CommandContext(ctx, path, "/S")
err = cmd.Start()
if err != nil {
if err := cmd.Process.Release(); err != nil {
log.Errorf("error releasing installer process: %v", err)
return err
}
err = cmd.Process.Release()
return err
log.Infof("installer started successfully: %s", path)
return nil
}
func urlWithVersionArch(it installerType, version string) string {
var url string
if it == installerEXE {
url = exeDownloadURL
} else {
url = msiDownloadURL
}
url = strings.ReplaceAll(url, "%version", version)
return strings.ReplaceAll(url, "%arch", runtime.GOARCH)
}