Remove MSI installer support and related scripts
Some checks reported errors
farmcontrol/farmcontrol-ui/pipeline/head Something is wrong with the build of this commit

- Deleted the `msiWrapped` configuration from `package.json` and removed the associated `msi-wrapped.wxs` file to streamline the packaging process.
- Eliminated the `build-windows-msi.ps1` script, which was previously used for generating MSI installers, as part of the transition to a simpler installation method.
- Updated the `finalize-desktop-artifacts.mjs` script to remove references to the MSI build process, ensuring a cleaner artifact finalization workflow.
This commit is contained in:
Tom Butcher 2026-08-04 01:15:29 +01:00
parent cfd0849cba
commit 3c4dc329d0
4 changed files with 4 additions and 342 deletions

View File

@ -226,8 +226,7 @@
},
"win": {
"target": [
"nsis",
"msiWrapped"
"nsis"
],
"protocols": [
{
@ -246,12 +245,6 @@
"allowToChangeInstallationDirectory": true,
"include": "scripts/installer.nsh",
"perMachine": false
},
"msiWrapped": {
"upgradeCode": "{735812DB-E33B-57A0-8FBC-5FC3155925AA}",
"perMachine": false,
"impersonate": true,
"wrappedInstallerArgs": "/S"
}
}
}

View File

@ -1,159 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<!--
Dual-purpose wrapper around the NSIS setup.exe.
ALLUSERS=2 + MSIINSTALLPERUSER=1 defaults to per-user (matching NSIS
RequestExecutionLevel user / $LOCALAPPDATA install) and is not blocked by
DisableMsi=1 / error 1625 the way a pure InstallScope=perUser package is.
-->
<Product
Id="*"
Name="Farm Control"
Language="1033"
Version="__VERSION__"
Manufacturer="Tom Butcher"
UpgradeCode="__UPGRADE_CODE__">
<Package
InstallerVersion="500"
Compressed="yes"
InstallPrivileges="limited"
Platform="x64" />
<Condition Message="Windows 7 and above is required"><![CDATA[Installed OR VersionNT >= 601]]></Condition>
<MajorUpgrade
AllowSameVersionUpgrades="yes"
DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate EmbedCab="yes" CompressionLevel="high" />
<Icon Id="InstallerIcon" SourceFile="__INSTALLER_ICON__" />
<Property Id="ARPPRODUCTICON" Value="InstallerIcon" />
<Property Id="DISABLEADVTSHORTCUTS" Value="1" />
<Property Id="ALLUSERS" Secure="yes" Value="2" />
<Property Id="MSIINSTALLPERUSER" Secure="yes" Value="1" />
<Property Id="REBOOT" Value="ReallySuppress" />
<!-- Prefer current per-user NSIS install; fall back to legacy per-machine. -->
<Property Id="PREVIOUS_UNINSTALL_CMD">
<RegistrySearch
Id="PreviousUninstallCmdHkcuSearch"
Root="HKCU"
Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\Farm Control"
Name="UninstallString"
Type="raw" />
</Property>
<Property Id="PREVIOUS_UNINSTALL_CMD_LEGACY">
<RegistrySearch
Id="PreviousUninstallCmdHklmSearch"
Root="HKLM"
Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\Farm Control"
Name="UninstallString"
Type="raw"
Win64="yes" />
</Property>
<Property Id="PREVIOUS_INSTALL_DIR">
<RegistrySearch
Id="PreviousInstallDirHkcuSearch"
Root="HKCU"
Key="Software\Tom Butcher\Farm Control"
Name="InstallDir"
Type="directory" />
</Property>
<Property Id="PREVIOUS_INSTALL_DIR_LEGACY">
<RegistrySearch
Id="PreviousInstallDirHklmSearch"
Root="HKLM"
Key="Software\Tom Butcher\Farm Control"
Name="InstallDir"
Type="directory"
Win64="yes" />
</Property>
<Binary Id="WrappedExe" SourceFile="__SETUP_EXE__" />
<CustomAction
Id="KillFarmControl"
BinaryKey="WixCA"
DllEntry="WixQuietExec"
Execute="immediate"
Impersonate="yes"
Return="ignore" />
<CustomAction
Id="UninstallPrevious"
BinaryKey="WixCA"
DllEntry="WixQuietExec"
Execute="immediate"
Impersonate="yes"
Return="ignore" />
<CustomAction
Id="RunInstaller"
BinaryKey="WrappedExe"
ExeCommand="/S"
Execute="immediate"
Impersonate="yes"
Return="check" />
<Directory Id="TARGETDIR" Name="SourceDir">
<Component Id="PerUserMarker" Guid="8A3F2E1D-9C4B-4A7E-B6D5-1F0E3C2B4A59">
<RegistryValue
Root="HKCU"
Key="Software\Tom Butcher\Farm Control"
Name="MsiWrapper"
Type="integer"
Value="1"
KeyPath="yes" />
</Component>
</Directory>
<Feature Id="MainFeature" Title="Farm Control" Level="1">
<ComponentRef Id="PerUserMarker" />
</Feature>
<CustomAction
Id="SetKillFarmControl"
Property="QtExecCmdLine"
Value="taskkill.exe /F /IM launcher.exe /T"
Execute="immediate" />
<CustomAction
Id="SetUninstallPreviousFromRegistry"
Property="QtExecCmdLine"
Value="&quot;[PREVIOUS_UNINSTALL_CMD]&quot; /S"
Execute="immediate" />
<CustomAction
Id="SetUninstallPreviousFromRegistryLegacy"
Property="QtExecCmdLine"
Value="&quot;[PREVIOUS_UNINSTALL_CMD_LEGACY]&quot; /S"
Execute="immediate" />
<CustomAction
Id="SetUninstallPreviousFromInstallDir"
Property="QtExecCmdLine"
Value="&quot;[PREVIOUS_INSTALL_DIR]Uninstall.exe&quot; /S"
Execute="immediate" />
<CustomAction
Id="SetUninstallPreviousFromInstallDirLegacy"
Property="QtExecCmdLine"
Value="&quot;[PREVIOUS_INSTALL_DIR_LEGACY]Uninstall.exe&quot; /S"
Execute="immediate" />
<InstallExecuteSequence>
<Custom Action="SetKillFarmControl" Before="KillFarmControl">NOT Installed</Custom>
<Custom Action="KillFarmControl" After="InstallInitialize">NOT Installed</Custom>
<Custom Action="SetUninstallPreviousFromRegistry" Before="UninstallPrevious">NOT Installed AND PREVIOUS_UNINSTALL_CMD</Custom>
<Custom Action="SetUninstallPreviousFromRegistryLegacy" Before="UninstallPrevious">NOT Installed AND NOT PREVIOUS_UNINSTALL_CMD AND PREVIOUS_UNINSTALL_CMD_LEGACY</Custom>
<Custom Action="SetUninstallPreviousFromInstallDir" Before="UninstallPrevious">NOT Installed AND NOT PREVIOUS_UNINSTALL_CMD AND NOT PREVIOUS_UNINSTALL_CMD_LEGACY AND PREVIOUS_INSTALL_DIR</Custom>
<Custom Action="SetUninstallPreviousFromInstallDirLegacy" Before="UninstallPrevious">NOT Installed AND NOT PREVIOUS_UNINSTALL_CMD AND NOT PREVIOUS_UNINSTALL_CMD_LEGACY AND NOT PREVIOUS_INSTALL_DIR AND PREVIOUS_INSTALL_DIR_LEGACY</Custom>
<Custom Action="UninstallPrevious" Before="RunInstaller">NOT Installed AND (PREVIOUS_UNINSTALL_CMD OR PREVIOUS_UNINSTALL_CMD_LEGACY OR PREVIOUS_INSTALL_DIR OR PREVIOUS_INSTALL_DIR_LEGACY)</Custom>
<Custom Action="RunInstaller" After="KillFarmControl">NOT Installed</Custom>
</InstallExecuteSequence>
</Product>
</Wix>

View File

@ -1,130 +0,0 @@
param(
[Parameter(Mandatory = $true)]
[string]$SetupExe,
[Parameter(Mandatory = $true)]
[string]$OutputMsi,
[Parameter(Mandatory = $true)]
[string]$Version,
[string]$UpgradeCode = "735812DB-E33B-57A0-8FBC-5FC3155925AA"
)
$ErrorActionPreference = "Stop"
function Get-MsiVersion {
param([string]$InputVersion)
$parts = $InputVersion.Split(".")
while ($parts.Count -lt 4) {
$parts += "0"
}
return ($parts[0..3] -join ".")
}
function Find-WixToolset {
$searchRoots = @(
$env:WIX,
$env:WIX_TOOLSET_PATH,
"${env:ProgramFiles(x86)}\WiX Toolset v3.14\bin",
"${env:ProgramFiles}\WiX Toolset v3.14\bin",
"${env:ProgramFiles(x86)}\WiX Toolset v3.11\bin",
"${env:ProgramFiles}\WiX Toolset v3.11\bin"
)
foreach ($root in $searchRoots) {
if (-not $root) {
continue
}
$candle = Join-Path $root "candle.exe"
$light = Join-Path $root "light.exe"
if ((Test-Path $candle) -and (Test-Path $light)) {
return @{
Candle = $candle
Light = $light
}
}
}
$candleCommand = Get-Command candle.exe -ErrorAction SilentlyContinue
$lightCommand = Get-Command light.exe -ErrorAction SilentlyContinue
if ($candleCommand -and $lightCommand) {
return @{
Candle = $candleCommand.Source
Light = $lightCommand.Source
}
}
throw @"
WiX Toolset not found. Install WiX Toolset 3.11+ on the Windows build agent and ensure candle.exe and light.exe are on PATH.
Example: choco install wixtoolset --version=3.14.0.4118
"@
}
function Escape-WixSourcePath {
param([string]$Path)
return $Path.Replace("\", "\\")
}
$rootDir = Split-Path -Parent $PSScriptRoot
$templatePath = Join-Path $rootDir "packaging/windows/msi-wrapped.wxs"
$workDir = Join-Path $env:TEMP "farmcontrol-wix"
$wix = Find-WixToolset
if (Test-Path $workDir) {
Remove-Item $workDir -Recurse -Force
}
New-Item -ItemType Directory -Path $workDir | Out-Null
$setupExePath = (Resolve-Path -LiteralPath $SetupExe).Path
$outputMsiPath = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($OutputMsi)
$outputDir = Split-Path $outputMsiPath -Parent
if ($outputDir -and -not (Test-Path $outputDir)) {
New-Item -ItemType Directory -Path $outputDir -Force | Out-Null
}
$installerIconPath = Join-Path $rootDir "assets\installer.ico"
if (-not (Test-Path $installerIconPath)) {
throw "Installer icon not found at $installerIconPath. Run 'bun run generate-app-icons' first."
}
$installerIconWorkPath = Join-Path $workDir "installer.ico"
Copy-Item -LiteralPath $installerIconPath -Destination $installerIconWorkPath -Force
$msiVersion = Get-MsiVersion $Version
$wxsContent = Get-Content -LiteralPath $templatePath -Raw
$wxsContent = $wxsContent.Replace("__UPGRADE_CODE__", $UpgradeCode)
$wxsContent = $wxsContent.Replace("__VERSION__", $msiVersion)
$wxsContent = $wxsContent.Replace("__SETUP_EXE__", (Escape-WixSourcePath $setupExePath))
$wxsContent = $wxsContent.Replace("__INSTALLER_ICON__", (Escape-WixSourcePath $installerIconWorkPath))
$projectWxs = Join-Path $workDir "project.wxs"
Set-Content -LiteralPath $projectWxs -Value $wxsContent -Encoding UTF8
$wixObj = Join-Path $workDir "project.wixobj"
Push-Location $workDir
try {
& $wix.Candle "-arch" "x64" "-ext" "WixUtilExtension" $projectWxs
if ($LASTEXITCODE -ne 0) {
throw "candle.exe failed with exit code $LASTEXITCODE"
}
& $wix.Light "-out" $outputMsiPath "-spdb" "-sw1076" "-ext" "WixUtilExtension" $wixObj
if ($LASTEXITCODE -ne 0) {
throw "light.exe failed with exit code $LASTEXITCODE"
}
} finally {
Pop-Location
Remove-Item $workDir -Recurse -Force
}
if (-not (Test-Path $outputMsiPath)) {
throw "MSI installer was not created at $outputMsiPath"
}
Write-Host "Created MSI installer at $outputMsiPath"

View File

@ -20,6 +20,7 @@ import {
expandWindowsAppFromArchive
} from './expand-windows-installer.mjs'
import { stageWindowsDeeplink } from './build-windows-deeplink.mjs'
import { patchWindowsBinaries } from './patch-windows-binaries.mjs'
import { codesignMacAppBundle } from './codesign-macos-app.mjs'
const rootDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..')
@ -572,50 +573,6 @@ function buildWindowsNsis(appDir, arch) {
return exePath
}
function buildWindowsMsi(setupExePath, arch) {
const scriptPath = path.join(rootDir, 'scripts/build-windows-msi.ps1')
const msiPath = path.join(
artifactDir,
getReleaseArtifactName(version, arch, 'msi')
)
const powershell = process.env.SystemRoot
? path.join(
process.env.SystemRoot,
'System32',
'WindowsPowerShell',
'v1.0',
'powershell.exe'
)
: 'powershell.exe'
const result = spawnSync(
powershell,
[
'-NoProfile',
'-ExecutionPolicy',
'Bypass',
'-File',
scriptPath,
'-SetupExe',
setupExePath,
'-OutputMsi',
msiPath,
'-Version',
version
],
{ stdio: 'inherit' }
)
if (result.status !== 0) {
throw new Error(
`build-windows-msi.ps1 failed with exit code ${result.status ?? 1}`
)
}
console.log(`Published ${msiPath}`)
return msiPath
}
if (buildEnv === 'dev') {
console.log('finalize-desktop-artifacts: skipping dev build')
process.exit(0)
@ -662,11 +619,12 @@ async function main() {
platformDir
)
stageWindowsDeeplinkScript(appDir)
await patchWindowsBinaries(appDir)
let published
try {
const setupExe = buildWindowsNsis(appDir, arch)
published = [setupExe, buildWindowsMsi(setupExe, arch)]
published = [setupExe]
if (installerFiles.setupZip) {
published.push(publishArtifact(installerFiles.setupZip, arch, 'zip'))