sciencemate/install.ps1

113 lines
5.6 KiB
PowerShell
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Agent for Science —— 内网安装Windows不经浏览器不弹 SmartScreen
#
# irm <发布目录>/install.ps1 | iex
#
# ## 为什么这条路不弹「Windows 已保护你的电脑」
#
# SmartScreen 拦的是带「网络来源标记」Zone.Identifier 这条 ADS俗称 MOTW
# 文件,而那个标记是浏览器 / 邮件客户端在保存文件时打上去的PowerShell 的
# Invoke-WebRequest 不打。所以经这条路装的应用,系统根本不会去问它签没签名 ——
# 这不是绕过,是 Windows 自己划的线:文件从哪来由谁负责。内网发布目录由我们自己
# 负责就像从共享盘拷过来一样。macOS 那边同一个道理,只是标记叫 quarantine。
#
# 我们在装之前仍然会 Unblock-File 一次。理由:万一有人先用浏览器下了 Setup.exe
# 再手动跑这个脚本,那个文件是带标记的 —— 那时用户看到的就是 SmartScreen 拦截页。
#
# ## 它做什么
#
# 下载 Setup.exe → 用发布目录里的 SHA256SUMS 核对 → 去掉网络来源标记 → 运行安装器
# (自解压到 %LOCALAPPDATA%\Programs\AgentForScience 并启动)。每一步失败就停,
# 不留半个应用。
#
# 环境变量AFS_RELEASE_URL发布目录、AFS_AUTH私有仓库"user:token",只读
# token 即可、AFS_DRY_RUN=1只打印要做什么不做、AFS_NO_LAUNCH=1只装不起
$ErrorActionPreference = 'Stop'
# 控制台默认代码页cp936/cp1252打不出这个脚本里的中文会变成一片 `?`。装东西时
# 第一眼看到乱码,人会以为装坏了 —— 所以先把输出编码扳成 UTF-8。
# (同打包器 #873 那处 `sys.stdout.reconfigure(encoding="utf-8")`,一个道理。)
# 这个脚本本身必须存成 **带 BOM 的 UTF-8**Windows PowerShell 5.1 没 BOM 就按系统
# ANSI 代码页读 .ps1中文会被读坏、连语法都能崩真机实测过就是这么发现的
try { [Console]::OutputEncoding = [Text.Encoding]::UTF8 } catch {}
# 下面两行由打包器整行替换(占位符只能出现在这里,别处不许提它 —— macOS 那版第一次
# 就栽在把占位符也写进了判断的模式里,替换后要么语法错、要么把正确地址当成"没填"拒掉)。
$DefaultUrl = 'https://desktop-9el2944.taile9f15e.ts.net/wangd/sciencemate/releases/download/v0.4.0'
$DefaultExe = 'AgentForScience-Setup.exe'
$Base = if ($env:AFS_RELEASE_URL) { $env:AFS_RELEASE_URL } else { $DefaultUrl }
$Exe = $DefaultExe
$Dry = [bool]$env:AFS_DRY_RUN
$Auth = $env:AFS_AUTH
function Say([string]$m) { Write-Host $m }
function Die([string]$m) { Write-Host "$m" -ForegroundColor Red; exit 1 }
if (-not $Base) {
Die "没有发布目录地址。打包时传 --release-url或运行前设 `$env:AFS_RELEASE_URL='https://<内网主机>/...'"
}
if ($env:OS -ne 'Windows_NT') { Die "这个脚本只装 WindowsmacOS 用 install.sh" }
$Base = $Base.TrimEnd('/')
$Work = Join-Path ([IO.Path]::GetTempPath()) ("afs-install-" + [Guid]::NewGuid().ToString('N').Substring(0,8))
New-Item -ItemType Directory -Path $Work -Force | Out-Null
$Target = Join-Path $Work $Exe
$Sums = Join-Path $Work 'SHA256SUMS'
# 私有 Forgejo 的 release 资产要登录才下得到AFS_AUTH="user:token"(对应 curl -u
$Headers = @{}
if ($Auth) {
$Headers['Authorization'] = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes($Auth))
}
try {
Say "① 下载 $ExeInvoke-WebRequest不会打网络来源标记"
if ($Dry) {
Say " `$ Invoke-WebRequest $Base/$Exe -OutFile $Target"
Say " `$ Invoke-WebRequest $Base/SHA256SUMS -OutFile $Sums"
} else {
Invoke-WebRequest -Uri "$Base/$Exe" -OutFile $Target -Headers $Headers -UseBasicParsing
Invoke-WebRequest -Uri "$Base/SHA256SUMS" -OutFile $Sums -Headers $Headers -UseBasicParsing
}
Say "② 核对 SHA-256"
if ($Dry) {
Say " `$ Get-FileHash -Algorithm SHA256对 SHA256SUMS 里 $Exe 那一行)"
} else {
# SHA256SUMS 是 sha256sum 的格式:<hash> <filename>
$line = Get-Content $Sums | Where-Object { $_ -match ("\s+" + [regex]::Escape($Exe) + "\s*$") } | Select-Object -First 1
if (-not $line) { Die "SHA256SUMS 里没有 $Exe 这一行" }
$expected = ($line -split '\s+')[0].ToLower()
$actual = (Get-FileHash -Algorithm SHA256 -Path $Target).Hash.ToLower()
if ($expected -ne $actual) {
Die "校验和不对:发布目录说 $expected,下载到的是 $actual —— 不装"
}
Say "$actual"
}
Say "③ 去掉网络来源标记(若有)"
if ($Dry) { Say " `$ Unblock-File $Target" }
else { Unblock-File -Path $Target -ErrorAction SilentlyContinue }
Say "④ 运行安装器(自解压到 %LOCALAPPDATA%\Programs\AgentForScience"
# 注意:不能叫 $args —— 那是 PowerShell 的自动变量,赋值行为不由我们说了算。
$exeArgs = @()
if ($env:AFS_NO_LAUNCH) { $exeArgs += '--no-launch' }
if ($Dry) {
Say (" `$ " + $Target + " " + ($exeArgs -join ' '))
} else {
$p = if ($exeArgs.Count) { Start-Process -FilePath $Target -ArgumentList $exeArgs -Wait -PassThru }
else { Start-Process -FilePath $Target -Wait -PassThru }
if ($p.ExitCode -ne 0) { Die "安装器退出码 $($p.ExitCode) —— 没装成" }
}
$Installed = Join-Path $env:LOCALAPPDATA 'Programs\AgentForScience'
Say ""
Say "✅ 装好了:$Installed"
Say " 以后直接双击 $Installed\AfsShell.exe 即可(那个控制台窗口别关,关了后端就一起收摊)。"
}
finally {
Remove-Item -Recurse -Force $Work -ErrorAction SilentlyContinue
}