param( [Parameter(Mandatory = $true)] [string]$SetupExe, [Parameter(Mandatory = $true)] [string]$OutputMsi, [Parameter(Mandatory = $true)] [string]$Version, [string]$UpgradeCode = "735812DB-E33B-57A0-8FBC-5FC3155925AA", [string]$ProductId = "A1B2C3D4-E5F6-7890-ABCD-EF1234567890" ) $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 } $msiVersion = Get-MsiVersion $Version $wxsContent = Get-Content -LiteralPath $templatePath -Raw $wxsContent = $wxsContent.Replace("__PRODUCT_ID__", $ProductId) $wxsContent = $wxsContent.Replace("__UPGRADE_CODE__", $UpgradeCode) $wxsContent = $wxsContent.Replace("__VERSION__", $msiVersion) $wxsContent = $wxsContent.Replace("__SETUP_EXE__", (Escape-WixSourcePath $setupExePath)) $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" $projectWxs if ($LASTEXITCODE -ne 0) { throw "candle.exe failed with exit code $LASTEXITCODE" } & $wix.Light "-out" $outputMsiPath "-spdb" "-sw1076" $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"