Files
chromebox-fan-control-win/build.ps1
2026-03-22 12:33:04 +08:00

159 lines
7.6 KiB
PowerShell

#Requires -Version 5.0
$ErrorActionPreference = "Stop"
$root = $PSScriptRoot
Set-Location $root
$exe = $null
if (Get-Command dotnet -ErrorAction SilentlyContinue) {
$exe = "dotnet"
} else {
foreach ($c in @(
"$env:ProgramFiles\dotnet\dotnet.exe",
"${env:ProgramFiles(x86)}\dotnet\dotnet.exe"
)) {
if (Test-Path $c) {
$exe = $c
break
}
}
}
if (-not $exe) {
Write-Error "dotnet SDK not found. Install .NET 8 SDK: https://dotnet.microsoft.com/download"
}
# -frameworkDependent: no bundled runtime (fewer files, needs .NET 8 on target)
# -multiFile: disable single-file (default is single exe to reduce DLL count)
$frameworkDependent = $args -contains "-frameworkDependent" -or $args -contains "--frameworkDependent"
$multiFile = $args -contains "-multiFile" -or $args -contains "--multiFile"
$selfContained = if ($frameworkDependent) { "false" } else { "true" }
$singleFile = -not $multiFile
function Invoke-Dotnet {
if ($exe -eq "dotnet") {
dotnet @args
} else {
& $exe @args
}
}
$doPublish = $args -contains "-publish" -or $args -contains "--publish"
$doPublishGui = $args -contains "-publishGui" -or $args -contains "--publishGui"
$doPublishSvc = $args -contains "-publishService" -or $args -contains "--publishService"
# -publish without split = GUI + Service both
if ($doPublish -and -not $doPublishGui -and -not $doPublishSvc) {
$doPublishGui = $true
$doPublishSvc = $true
}
$doPublishAny = $doPublishGui -or $doPublishSvc
# -msi requires WiX; -publish only generates dist, MSI optional
$doMsi = $args -contains "-msi" -or $args -contains "--msi"
Write-Host ">> dotnet restore"
if ($doPublishAny -or $doMsi) {
Invoke-Dotnet restore "$root\ChromeboxFanControl.sln" -r win-x64
} else {
Invoke-Dotnet restore "$root\ChromeboxFanControl.sln"
}
Write-Host ">> dotnet build Release"
Invoke-Dotnet build "$root\ChromeboxFanControl.sln" -c Release --no-restore
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
if ($doPublishAny) {
$out = Join-Path $root "dist"
if ($doPublishGui -and $doPublishSvc) {
if (Test-Path $out) { Remove-Item $out -Recurse -Force }
New-Item -ItemType Directory -Path $out | Out-Null
} elseif ($doPublishGui -and -not (Test-Path $out)) {
New-Item -ItemType Directory -Path $out | Out-Null
}
if ($doPublishGui) {
Write-Host ">> dotnet publish GUI -> $out"
$guiArgs = @("-c", "Release", "-o", $out, "-r", "win-x64", "--self-contained", "false", "--no-restore")
if ($singleFile) { $guiArgs += "-p:PublishSingleFile=true", "-p:IncludeNativeLibrariesForSelfExtract=true" }
Invoke-Dotnet publish "$root\ChromeboxFanControl\ChromeboxFanControl.csproj" @guiArgs
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
}
if ($doPublishSvc) {
Write-Host ">> dotnet publish Service -> dist-svc"
$svcOut = Join-Path $root "dist-svc"
$svcArgs = @("-c", "Release", "-o", $svcOut, "-r", "win-x64", "--self-contained", $selfContained, "--no-restore")
if ($singleFile) { $svcArgs += "-p:PublishSingleFile=true", "-p:IncludeNativeLibrariesForSelfExtract=true" }
Invoke-Dotnet publish "$root\ChromeboxFanControlService\ChromeboxFanControlService.csproj" @svcArgs
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
if (-not (Test-Path $out)) { New-Item -ItemType Directory -Path $out | Out-Null }
Copy-Item "$svcOut\*" $out -Recurse -Force -Exclude "appsettings.json"
if (-not $doMsi) { Remove-Item $svcOut -Recurse -Force }
}
if ($doPublishGui -and $doPublishSvc) {
Write-Host "Done: $out\ChromeboxFanControl.exe (GUI), $out\ChromeboxFanControlService.exe (Service)"
} elseif ($doPublishGui) {
Write-Host "Done (GUI only): $out\ChromeboxFanControl.exe"
} else {
Write-Host "Done (Service only): $out\ChromeboxFanControlService.exe (merged into dist\)"
}
}
if ($doMsi) {
$dist = Join-Path $root "dist"
$distSvc = Join-Path $root "dist-svc"
if (-not (Test-Path $dist)) {
Write-Error "dist\ not found. Run .\build.ps1 -publish first."
}
if (-not (Test-Path $distSvc)) {
Write-Host ">> dist-svc missing, publishing Service for service MSI"
$svcArgs = @("-c", "Release", "-o", $distSvc, "-r", "win-x64", "--self-contained", $selfContained, "--no-restore")
if ($singleFile) { $svcArgs += "-p:PublishSingleFile=true", "-p:IncludeNativeLibrariesForSelfExtract=true" }
Invoke-Dotnet publish "$root\ChromeboxFanControlService\ChromeboxFanControlService.csproj" @svcArgs
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
}
$wixBin = $null
foreach ($v in @("3.11", "3.14", "3.10")) {
$p = "${env:ProgramFiles(x86)}\WiX Toolset v$v\bin"
if (Test-Path "$p\candle.exe") { $wixBin = $p; break }
}
if (-not $wixBin) {
Write-Warning "WiX Toolset not found. Skipping MSI. Install from https://wixtoolset.org/docs/wix3/ to build installers."
} else {
$wixDir = Join-Path $root "wix"
$outMsi = Join-Path $root "dist-installer"
if (-not (Test-Path $outMsi)) { New-Item -ItemType Directory -Path $outMsi | Out-Null }
$objDir = Join-Path $root "wix\obj"
if (-not (Test-Path $objDir)) { New-Item -ItemType Directory -Path $objDir | Out-Null }
$ext = "-ext", "$wixBin\WixUtilExtension.dll", "-ext", "$wixBin\WixUIExtension.dll"
Write-Host ">> WiX: Desktop MSI"
$harvested = Join-Path $root "wix\Harvested.wxs"
& "$wixBin\heat.exe" dir $dist -cg AppFiles -gg -sf -srd -sreg -scom -dr INSTALLFOLDER -out $harvested -t "$wixDir\exclude-service.xsl" -sw5151
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
& "$wixBin\candle.exe" -arch x64 -out "$objDir\\" @ext "$wixDir\Product.wxs" $harvested
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
& "$wixBin\light.exe" -out "$outMsi\ChromeboxFanControl-Setup.msi" -b $dist @ext "$objDir\Product.wixobj" "$objDir\Harvested.wixobj"
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
Remove-Item $harvested -Force -ErrorAction SilentlyContinue
Write-Host ">> WiX: Service MSI"
$harvestedSvc = Join-Path $root "wix\Harvested-Service.wxs"
& "$wixBin\heat.exe" dir $distSvc -cg ServiceFiles -gg -sf -srd -sreg -scom -dr INSTALLFOLDER -out $harvestedSvc -t "$wixDir\exclude-service.xsl" -sw5151
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
& "$wixBin\candle.exe" -arch x64 -out "$objDir\\" @ext "$wixDir\Product-Service.wxs" $harvestedSvc
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
& "$wixBin\light.exe" -out "$outMsi\ChromeboxFanControlService-Setup.msi" -b $distSvc @ext "$objDir\Product-Service.wixobj" "$objDir\Harvested-Service.wixobj"
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
Remove-Item $harvestedSvc -Force -ErrorAction SilentlyContinue
if (Test-Path $distSvc) { Remove-Item $distSvc -Recurse -Force }
Write-Host "Done: $outMsi\ChromeboxFanControl-Setup.msi (Desktop), $outMsi\ChromeboxFanControlService-Setup.msi (Service)"
}
}
if (-not $doPublishAny -and -not $doMsi) {
Write-Host "Done: $root\ChromeboxFanControl\bin\Release\net8.0-windows\ChromeboxFanControl.exe"
Write-Host " .\build.ps1 -publish -> dist\ GUI + Service (self-contained)"
Write-Host " .\build.ps1 -publishGui -> GUI only"
Write-Host " .\build.ps1 -publishService -> Service only (merge into dist\)"
Write-Host " .\build.ps1 -publish -msi -> dist + two MSI (needs WiX)"
Write-Host " .\build.ps1 -publish -frameworkDependent -> no bundled runtime (needs .NET 8)"
Write-Host " .\build.ps1 -publish -multiFile -> keep multiple DLLs (default: single exe)"
}