[CmdletBinding()] param() $ErrorActionPreference = "Stop" $ProjectRoot = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path $ToolVersion = "6.7.3" $ToolRoot = Join-Path $ProjectRoot ".build-tools\inno-setup-$ToolVersion" $Compiler = Join-Path $ToolRoot "ISCC.exe" $DownloadRoot = Join-Path $ProjectRoot ".build-tools\downloads" $Installer = Join-Path $DownloadRoot "innosetup-$ToolVersion.exe" $InstallerUrl = ( "https://github.com/jrsoftware/issrc/releases/download/" + "is-6_7_3/innosetup-$ToolVersion.exe" ) $InstallerSha256 = "9C73C3BAE7ED48D44112A0F48E66742C00090BDB5BEF71D9D3C056C66E97B732" $LanguageRoot = Join-Path $ProjectRoot ".build-tools\inno-languages" $ChineseMessages = Join-Path $LanguageRoot "ChineseSimplified.isl" $ChineseMessagesUrl = ( "https://raw.githubusercontent.com/jrsoftware/issrc/" + "6ef32198ef1f7b7b375cd4b6b90896c2a58eb4c2/Files/Languages/ChineseSimplified.isl" ) $ChineseMessagesSha256 = "E0B0B350E2245F3C5E65586DFE43D574F6E7F06F2261149ABA284954B3FC9A8D" function Test-Compiler { param([Parameter(Mandatory = $true)][string]$Candidate) if (-not (Test-Path -LiteralPath $Candidate -PathType Leaf)) { return $false } $ReleaseNotes = Join-Path (Split-Path -Parent $Candidate) "whatsnew.htm" if (-not (Test-Path -LiteralPath $ReleaseNotes -PathType Leaf)) { return $false } $ReleaseText = [System.IO.File]::ReadAllText($ReleaseNotes) $VersionMatch = [regex]::Match($ReleaseText, '([0-9.]+)') return $VersionMatch.Success -and $VersionMatch.Groups[1].Value -eq $ToolVersion } New-Item -ItemType Directory -Path $LanguageRoot -Force | Out-Null if (Test-Path -LiteralPath $ChineseMessages -PathType Leaf) { $ExistingLanguageHash = (Get-FileHash -LiteralPath $ChineseMessages -Algorithm SHA256).Hash if ($ExistingLanguageHash -ne $ChineseMessagesSha256) { Remove-Item -LiteralPath $ChineseMessages -Force } } if (-not (Test-Path -LiteralPath $ChineseMessages -PathType Leaf)) { Write-Host "Downloading the pinned Simplified Chinese installer messages..." Invoke-WebRequest -Uri $ChineseMessagesUrl -OutFile $ChineseMessages -UseBasicParsing } $ActualLanguageHash = (Get-FileHash -LiteralPath $ChineseMessages -Algorithm SHA256).Hash if ($ActualLanguageHash -ne $ChineseMessagesSha256) { throw "Inno Setup language checksum mismatch. Expected $ChineseMessagesSha256; found $ActualLanguageHash" } foreach ($Candidate in @( $Compiler, (Join-Path ${env:ProgramFiles(x86)} "Inno Setup 6\ISCC.exe"), (Join-Path $env:LOCALAPPDATA "Programs\Inno Setup 6\ISCC.exe") )) { if ($Candidate -and (Test-Compiler -Candidate $Candidate)) { Write-Output (Resolve-Path -LiteralPath $Candidate).Path exit 0 } } New-Item -ItemType Directory -Path $DownloadRoot -Force | Out-Null if (Test-Path -LiteralPath $Installer -PathType Leaf) { $ExistingHash = (Get-FileHash -LiteralPath $Installer -Algorithm SHA256).Hash if ($ExistingHash -ne $InstallerSha256) { Remove-Item -LiteralPath $Installer -Force } } if (-not (Test-Path -LiteralPath $Installer -PathType Leaf)) { Write-Host "Downloading pinned Inno Setup $ToolVersion compiler..." Invoke-WebRequest -Uri $InstallerUrl -OutFile $Installer -UseBasicParsing } $ActualHash = (Get-FileHash -LiteralPath $Installer -Algorithm SHA256).Hash if ($ActualHash -ne $InstallerSha256) { throw "Inno Setup download checksum mismatch. Expected $InstallerSha256; found $ActualHash" } $Signature = Get-AuthenticodeSignature -LiteralPath $Installer if ($Signature.Status -ne [System.Management.Automation.SignatureStatus]::Valid) { throw "Inno Setup download does not have a valid Authenticode signature: $($Signature.Status)" } if (-not $Signature.SignerCertificate -or $Signature.SignerCertificate.Subject -notmatch "O=Pyrsys B\.V\.") { throw "Inno Setup download has an unexpected signer" } New-Item -ItemType Directory -Path $ToolRoot -Force | Out-Null Write-Host "Installing the pinned Inno Setup compiler into $ToolRoot ..." & $Installer /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /CURRENTUSER "/DIR=$ToolRoot" if ($LASTEXITCODE -ne 0) { throw "Inno Setup compiler installation failed with exit code $LASTEXITCODE" } if (-not (Test-Compiler -Candidate $Compiler)) { throw "Inno Setup installation completed without ISCC.exe: $Compiler" } Write-Output $Compiler