$ErrorActionPreference = "Stop" $InstallDir = Join-Path $env:ProgramData "cs2clip-worker" $BaseUrl = "https://cli.n1cetry.com" function Read-InstallPassword { $secure = Read-Host "Install password" -AsSecureString $ptr = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($secure) try { return [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR($ptr) } finally { if ($ptr -ne [IntPtr]::Zero) { [System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($ptr) } } } function Get-StatusCode { param($ErrorRecord) try { return [int]$ErrorRecord.Exception.Response.StatusCode } catch { return $null } } function Invoke-InstallApi { param( [string]$Path, [string]$Password, [string]$Method = "GET", [string]$OutFile ) $headers = @{ "X-Install-Password" = $Password "User-Agent" = "cs2clip-worker-installer" } try { if ($OutFile) { Invoke-WebRequest -Method $Method -Headers $headers -Uri ($BaseUrl + $Path) -OutFile $OutFile | Out-Null return } return Invoke-RestMethod -Method $Method -Headers $headers -Uri ($BaseUrl + $Path) } catch { $status = Get-StatusCode $_ if ($status -eq 401) { throw "Install password rejected." } throw } } $password = Read-InstallPassword $meta = Invoke-InstallApi -Path "/api/latest" -Password $password Write-Host ("Installing " + $meta.assetName + " (" + $meta.tagName + ") to " + $InstallDir) New-Item -ItemType Directory -Path $InstallDir -Force | Out-Null $existing = Get-Process -Name "cs2clip-worker" -ErrorAction SilentlyContinue if ($existing) { Write-Host "Stopping existing cs2clip-worker process" $existing | Stop-Process -Force Start-Sleep -Seconds 1 } $tmpPath = Join-Path $InstallDir "cs2clip-worker.exe.download" $exePath = Join-Path $InstallDir "cs2clip-worker.exe" Invoke-InstallApi -Path $meta.downloadPath -Password $password -OutFile $tmpPath if ($meta.sha256) { $actualHash = (Get-FileHash -Path $tmpPath -Algorithm SHA256).Hash.ToLowerInvariant() $expectedHash = [string]$meta.sha256 if ($actualHash -ne $expectedHash.ToLowerInvariant()) { Remove-Item -Path $tmpPath -Force -ErrorAction SilentlyContinue throw ("Downloaded worker checksum mismatch. Expected " + $expectedHash + ", got " + $actualHash) } } Move-Item -Path $tmpPath -Destination $exePath -Force Write-Host "Starting worker" Start-Process -FilePath $exePath -WorkingDirectory $InstallDir -WindowStyle Hidden Write-Host ("Worker installed: " + $exePath) Write-Host ("Logs directory: " + (Join-Path $InstallDir "out\observability"))