<# build-native.ps1 - compile the native C# app (no ps2exe) to dist\ClaudeProxy.exe. Uses the .NET Framework C# compiler (csc), which is present on every Windows machine. #> $ErrorActionPreference = 'Stop' $root = Split-Path -Parent $MyInvocation.MyCommand.Path $dist = Join-Path $root 'dist' New-Item -ItemType Directory -Force -Path $dist | Out-Null $csc = 'C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe' if (-not (Test-Path $csc)) { throw "csc not found: $csc" } # make sure the icon and the embedded Xray zip exist if (-not (Test-Path (Join-Path $root 'icon.ico'))) { & powershell.exe -NoProfile -ExecutionPolicy Bypass -File (Join-Path $root 'make-icon.ps1') | Out-Null } # Xray binary (embedded as a resource). Not stored in git - fetch the pinned release if missing. $xrayZip = Join-Path $root 'xray.zip' if (-not (Test-Path $xrayZip)) { $ver = 'v26.3.27' $base = "https://github.com/XTLS/Xray-core/releases/download/$ver" Write-Host "Fetching Xray-core $ver..." -ForegroundColor Cyan [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12 Invoke-WebRequest "$base/Xray-windows-64.zip" -OutFile $xrayZip -UseBasicParsing Invoke-WebRequest "$base/Xray-windows-64.zip.dgst" -OutFile "$xrayZip.dgst" -UseBasicParsing $expected = $null foreach ($l in (Get-Content "$xrayZip.dgst")) { if ($l -match '512') { continue } if ($l -match '256' -and $l -match '([0-9a-fA-F]{64})') { $expected = $Matches[1].ToLower(); break } } $actual = (Get-FileHash $xrayZip -Algorithm SHA256).Hash.ToLower() Remove-Item "$xrayZip.dgst" -ErrorAction SilentlyContinue if ($expected -and $actual -ne $expected) { Remove-Item $xrayZip -ErrorAction SilentlyContinue; throw "Xray SHA256 mismatch." } Write-Host " Xray SHA256 ok." -ForegroundColor DarkGray } $out = Join-Path $dist 'ClaudeProxy.exe' $refs = @('System.dll', 'System.Core.dll', 'System.Windows.Forms.dll', 'System.Drawing.dll', 'System.IO.Compression.dll', 'System.IO.Compression.FileSystem.dll', 'Microsoft.CSharp.dll') $args = @( '/nologo', '/target:winexe', '/platform:x64', "/out:$out", "/win32icon:$(Join-Path $root 'icon.ico')", "/win32manifest:$(Join-Path $root 'native\app.manifest')", "/resource:$(Join-Path $root 'xray.zip'),ClaudeProxy.xray.zip" ) foreach ($r in $refs) { $args += "/reference:$r" } $args += (Join-Path $root 'native\Core.cs') $args += (Join-Path $root 'native\Support.cs') $args += (Join-Path $root 'native\MainForm.cs') Write-Host "Compiling native C# -> $out" -ForegroundColor Cyan & $csc @args if ($LASTEXITCODE -ne 0) { throw "csc failed (exit $LASTEXITCODE)" } $sz = [math]::Round((Get-Item $out).Length / 1MB, 1) Write-Host "OK: $out ($sz MB)" -ForegroundColor Green