# Installer for the `neo` CLI on Windows. # # powershell -c "irm https://get.neosource.dev/install.ps1 | iex" # # Published verbatim at https://get.neosource.dev/install.ps1. Mirrors dev/install.sh: # resolve the build from latest.json, verify sha256, install to a per-user # directory, never require admin. # # NOTE: this script has NOT been executed on a real Windows host — we have no # Windows machine and no Windows CI runner. The artifact it installs IS tested # (the PE is built and packaged by dev/release-neo.sh on every release), but # treat the script itself as unverified until someone runs it. $ErrorActionPreference = 'Stop' $Base = if ($env:NEO_INSTALL_BASE) { $env:NEO_INSTALL_BASE } else { 'https://get.neosource.dev/dl' } # Windows on ARM runs x64 binaries under emulation, so x86_64 is the correct # (and only) answer for both until an aarch64-pc-windows build exists. $target = 'x86_64-pc-windows-gnu' Write-Host "neo installer - target $target" $manifest = Invoke-RestMethod -Uri "$Base/latest.json" $artifact = $manifest.artifacts.$target if (-not $artifact) { throw "no build published for $target" } Write-Host "installing neo $($manifest.version)" $tmp = Join-Path ([System.IO.Path]::GetTempPath()) ("neo-" + [System.Guid]::NewGuid()) New-Item -ItemType Directory -Path $tmp | Out-Null try { $zip = Join-Path $tmp 'neo.zip' Invoke-WebRequest -Uri "$Base/$($artifact.url)" -OutFile $zip $got = (Get-FileHash -Path $zip -Algorithm SHA256).Hash.ToLower() if ($got -ne $artifact.sha256.ToLower()) { throw "checksum mismatch`n expected $($artifact.sha256)`n got $got" } Expand-Archive -Path $zip -DestinationPath $tmp -Force $exe = Get-ChildItem -Path $tmp -Recurse -Filter 'neo.exe' | Select-Object -First 1 if (-not $exe) { throw 'archive did not contain neo.exe' } $binDir = if ($env:NEO_INSTALL_DIR) { $env:NEO_INSTALL_DIR } else { Join-Path $env:LOCALAPPDATA 'Programs\neo' } New-Item -ItemType Directory -Path $binDir -Force | Out-Null Copy-Item -Path $exe.FullName -Destination (Join-Path $binDir 'neo.exe') -Force Write-Host "installed $binDir\neo.exe" $receiptDir = Join-Path $env:LOCALAPPDATA 'neosource' New-Item -ItemType Directory -Path $receiptDir -Force | Out-Null @{ version = $manifest.version target = $target binary = (Join-Path $binDir 'neo.exe') source = $Base } | ConvertTo-Json | Set-Content -Path (Join-Path $receiptDir 'neo-receipt.json') # PATH via the registry, not [Environment]::SetEnvironmentVariable with a # naive read/write: this preserves REG_EXPAND_SZ so entries like %JAVA_HOME% # elsewhere in PATH are not flattened into their current values. $key = 'HKCU:\Environment' $current = (Get-ItemProperty -Path $key -Name Path -ErrorAction SilentlyContinue).Path if ($null -eq $current) { $current = '' } if (($current -split ';') -notcontains $binDir) { $updated = if ([string]::IsNullOrEmpty($current)) { $binDir } else { "$binDir;$current" } Set-ItemProperty -Path $key -Name Path -Value $updated -Type ExpandString # Broadcast so already-open shells pick it up without a reboot; without # this the user is told to "restart your terminal", which they will not. if (-not ('Win32.NativeMethods' -as [type])) { Add-Type -Namespace Win32 -Name NativeMethods -MemberDefinition @' [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] public static extern IntPtr SendMessageTimeout(IntPtr hWnd, uint Msg, UIntPtr wParam, string lParam, uint fuFlags, uint uTimeout, out UIntPtr lpdwResult); '@ } $HWND_BROADCAST = [IntPtr]0xffff; $WM_SETTINGCHANGE = 0x1a [UIntPtr]$result = [UIntPtr]::Zero [void][Win32.NativeMethods]::SendMessageTimeout( $HWND_BROADCAST, $WM_SETTINGCHANGE, [UIntPtr]::Zero, 'Environment', 2, 5000, [ref]$result) Write-Host "added $binDir to your PATH" } Write-Host '' Write-Host 'Done. Try: neo auth login' } finally { Remove-Item -Recurse -Force $tmp -ErrorAction SilentlyContinue }