blob: 5050112a8ed68cff4707160fa5967d90e797433a [file]
# Casbin Gateway one-step install for Windows.
#
# Usage (run only if you trust this script source):
# irm https://raw.githubusercontent.com/apache/casbin-gateway/master/scripts/install.ps1 | iex
#
# This downloads the nightly build, which is an automated build of master and
# not an official release. Use it for testing and development only.
#
# Optional environment variables:
# INSTALL_DIR where the executable and its data live
# (default: $env:LOCALAPPDATA\casbin-gateway)
# NO_START set to any value to install without starting Gateway
# NO_AUTOSTART set to any value to skip the login-time startup entry
# NO_SHORTCUT set to any value to skip the desktop and Start menu shortcuts
$ErrorActionPreference = 'Stop'
$Repo = 'apache/casbin-gateway'
$Tag = 'nightly'
$BaseName = 'casbin-gateway-nightly'
$InstallDir = if ($env:INSTALL_DIR) { $env:INSTALL_DIR } else { "$env:LOCALAPPDATA\casbin-gateway" }
$BinDir = Join-Path $InstallDir 'bin'
# Windows PowerShell 5.1 still negotiates TLS 1.0 by default, which GitHub
# refuses. The progress bar makes Invoke-WebRequest many times slower on a
# download this size.
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$ProgressPreference = 'SilentlyContinue'
function Write-Info { param([string]$Message) Write-Host $Message }
# ── pick the archive for this machine ─────────────────────────────────────────
# Only the x86_64 archive is published; Windows on ARM runs it under the
# built-in x64 emulation.
$ArchName = switch ($env:PROCESSOR_ARCHITECTURE) {
'AMD64' { 'x86_64' }
'ARM64' {
Write-Host 'No arm64 build is published, installing the x86_64 one to run under emulation'
'x86_64'
}
default { throw "unsupported architecture `"$env:PROCESSOR_ARCHITECTURE`", build from source instead: https://github.com/$Repo" }
}
$Archive = "$BaseName-windows-$ArchName.zip"
$Url = "https://github.com/$Repo/releases/download/$Tag/$Archive"
$TmpDir = Join-Path $env:TEMP "casbin-gateway-install-$(Get-Random)"
New-Item -ItemType Directory -Path $TmpDir | Out-Null
try {
# ── download ──────────────────────────────────────────────────────────────
$ArchivePath = Join-Path $TmpDir $Archive
Write-Info "Downloading $Url"
Invoke-WebRequest -Uri $Url -OutFile $ArchivePath -UseBasicParsing
Expand-Archive -Path $ArchivePath -DestinationPath $TmpDir -Force
$Unpacked = Join-Path $TmpDir "$BaseName-windows-$ArchName"
# ── install ───────────────────────────────────────────────────────────────
Write-Info "Installing to $InstallDir"
New-Item -ItemType Directory -Path $InstallDir -Force | Out-Null
$ExePath = Join-Path $InstallDir 'casbin-gateway.exe'
$DesktopExePath = Join-Path $InstallDir 'casbin-gateway-desktop.exe'
foreach ($executable in @('casbin-gateway.exe', 'casbin-gateway-desktop.exe')) {
try {
Copy-Item -Path (Join-Path $Unpacked $executable) -Destination (Join-Path $InstallDir $executable) -Force
}
catch {
# Windows locks a running executable, so this is what an upgrade over
# a started Gateway looks like.
throw "cannot replace $executable in $InstallDir, quit Casbin Gateway from its tray icon and try again ($_)"
}
}
foreach ($legalFile in @('LICENSE', 'NOTICE', 'DISCLAIMER')) {
Copy-Item -Path (Join-Path $Unpacked $legalFile) -Destination (Join-Path $InstallDir $legalFile) -Force
}
}
finally {
Remove-Item -Recurse -Force $TmpDir -ErrorAction SilentlyContinue
}
# ── put a "casbin-gateway" command on PATH ────────────────────────────────────
# Gateway keeps its database, logs and temporary files in the working
# directory, so the command is a wrapper that always starts it in $InstallDir.
# Without it, running "casbin-gateway" from somewhere else would quietly start
# a second, empty installation. The wrapper lives in its own directory because
# cmd resolves .exe before .cmd, so a wrapper next to the executable would
# never be the one that runs.
New-Item -ItemType Directory -Path $BinDir -Force | Out-Null
@"
@echo off
rem Written by the Casbin Gateway installer. Gateway reads and writes .\data,
rem .\logs and .\tmp, so it always has to start in its own directory.
cd /d "%~dp0.." || exit /b 1
"%~dp0..\casbin-gateway.exe" %*
"@ | Set-Content -Path (Join-Path $BinDir 'casbin-gateway.cmd') -Encoding ascii
$UserPath = [System.Environment]::GetEnvironmentVariable('PATH', 'User')
if ($UserPath -notlike "*$BinDir*") {
[System.Environment]::SetEnvironmentVariable('PATH', "$UserPath;$BinDir", 'User')
$env:PATH = "$env:PATH;$BinDir"
Write-Info "Added $BinDir to your PATH, which takes effect in your next terminal"
}
# ── desktop and Start menu shortcuts ──────────────────────────────────────────
# Both point at the desktop launcher, not at the server: it is what shows the
# window, and it starts the server itself if nothing is serving yet.
$IconPath = & $DesktopExePath icon
$ShortcutName = 'Casbin Gateway.lnk'
function New-GatewayShortcut {
param([string]$Path)
$shell = New-Object -ComObject WScript.Shell
$shortcut = $shell.CreateShortcut($Path)
$shortcut.TargetPath = $DesktopExePath
$shortcut.WorkingDirectory = $InstallDir
$shortcut.IconLocation = $IconPath
$shortcut.Description = 'Casbin Gateway'
$shortcut.Save()
}
if (-not $env:NO_SHORTCUT) {
foreach ($dir in @([System.Environment]::GetFolderPath('Desktop'), [System.Environment]::GetFolderPath('Programs'))) {
try {
New-GatewayShortcut -Path (Join-Path $dir $ShortcutName)
}
catch {
Write-Info "Could not create the shortcut in ${dir}: $_"
}
}
}
# ── start with Windows ────────────────────────────────────────────────────────
# The launcher owns this entry so that the tray's "Start at Login" checkbox and
# the installer are never out of step. An older install put a shortcut in the
# Startup folder instead, which would now start a second copy.
Remove-Item -Path (Join-Path ([System.Environment]::GetFolderPath('Startup')) $ShortcutName) -Force -ErrorAction SilentlyContinue
if (-not $env:NO_AUTOSTART) {
try {
& $DesktopExePath autostart on
Write-Info 'Casbin Gateway will start with Windows.'
}
catch {
Write-Info "Could not add the startup entry: $_"
}
}
Write-Info ''
Write-Info "Casbin Gateway is installed in $InstallDir"
Write-Info 'Its database, logs and temporary files stay in that directory.'
Write-Info 'It serves this machine only, and signs you in there as admin without a password.'
Write-Info 'Closing its window leaves it running in the tray; quit it from there.'
Write-Info 'Without the window: "casbin-gateway start", "casbin-gateway stop", "casbin-gateway status".'
Write-Info ''
if ($env:NO_START) {
Write-Info 'Start it from the "Casbin Gateway" shortcut, or with: casbin-gateway start'
return
}
# The launcher detaches on its own, so installing does not occupy this terminal.
Start-Process -FilePath $DesktopExePath -WorkingDirectory $InstallDir