Files
jiangchen 8e4a648465 feat: DSH 悬浮窗 v0.1.0 — 原生置顶小窗 + 会话镜像 + 抓屏隐身
- shell: WinForms + WebView2 原生壳(无边框/置顶/固定位置/锁定尺寸/全屏/自适应缩放/截图排除)
- shell/ui.html: 自适应界面(工具栏、会话镜像区、底部聊天框、轮/步/tok/s/MTOK/缓存命中/上下文状态条、外观设置)
- lib/host.js: DSH 插件 Host 半(endpoint 写入、SSE 会话与指标快照、float_window Agent 工具)
- tools: WebView2 SDK 拉取、BOM 修复、Host 冒烟测试
- README: 架构、实测结论(WDA_EXCLUDEFROMCAPTURE、玻璃模式、DPI、WebView2 加载)
2026-09-27 14:02:58 +08:00

88 lines
4.0 KiB
PowerShell
Raw Permalink 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.
<#
setup-webview2.ps1 — 拉取 WebView2 SDK(托管 DLL + Loader),供 shell/float-window.ps1 内嵌 Chromium 使用。
为什么要这么绕:本机 PowerShell 的 schannel 凭据在当前沙箱里不可用
(SEC_E_NO_CREDENTIALS),Invoke-WebRequest/curl 走不通;Node 自带 OpenSSL,网络正常。
所以优先用 node 下载,并保留 Invoke-WebRequest 作为通用回退。
#>
[CmdletBinding()]
param(
[string]$Dest,
[string]$Cache
)
$ErrorActionPreference = 'Stop'
# 在无控制台的宿主(被 harness / 计划任务拉起)里 Write-Progress 会抛 Win32 "Access is denied"
$ProgressPreference = 'SilentlyContinue'
$root = Split-Path -Parent $MyInvocation.MyCommand.Path | Split-Path -Parent
if (-not $Dest) { $Dest = Join-Path $root 'shell\lib' }
if (-not $Cache) { $Cache = Join-Path $root '.cache' }
New-Item -ItemType Directory -Force -Path $Dest, $Cache | Out-Null
if (Test-Path (Join-Path $Dest 'Microsoft.Web.WebView2.WinForms.dll')) {
Write-Host "[setup] WebView2 SDK 已存在:$Dest"
exit 0
}
$nupkg = Join-Path $Cache 'webview2.nupkg'
$needDownload = $true
if (Test-Path $nupkg) { $needDownload = $false }
if ($needDownload) {
$nodeScript = @'
const fs = require('node:fs')
const idx = 'https://api.nuget.org/v3-flatcontainer/microsoft.web.webview2/index.json'
async function main() {
const j = await (await fetch(idx, { signal: AbortSignal.timeout(30000) })).json()
const stable = j.versions.filter((v) => !v.includes('-'))
const v = stable[stable.length - 1]
const url = `https://api.nuget.org/v3-flatcontainer/microsoft.web.webview2/${v}/microsoft.web.webview2.${v}.nupkg`
const buf = Buffer.from(await (await fetch(url, { signal: AbortSignal.timeout(120000) })).arrayBuffer())
fs.writeFileSync(process.argv[2], buf)
console.log(v)
}
main().catch((e) => { console.error('download failed: ' + e.message); process.exit(1) })
'@
$nodeFile = Join-Path $Cache 'download-webview2.cjs'
Set-Content -Path $nodeFile -Value $nodeScript -Encoding UTF8
$version = $null
if (Get-Command node -ErrorAction SilentlyContinue) {
$version = (& node $nodeFile $nupkg | Select-Object -Last 1)
}
if (-not (Test-Path $nupkg)) {
# 回退:本机 PowerShell 的 TLS 可用时走这里
$v = (Invoke-RestMethod 'https://api.nuget.org/v3-flatcontainer/microsoft.web.webview2/index.json').versions |
Where-Object { $_ -notmatch '-' } | Select-Object -Last 1
Invoke-WebRequest "https://api.nuget.org/v3-flatcontainer/microsoft.web.webview2/$v/microsoft.web.webview2.$v.nupkg" -OutFile $nupkg
$version = $v
}
Write-Host "[setup] 下载 WebView2 SDK $version"
}
$extract = Join-Path $Cache 'extract'
Remove-Item -Recurse -Force $extract -ErrorAction SilentlyContinue
# Expand-Archive (PS 5.1) 只认 .zip 扩展名,nupkg 本质就是 zip,复制一份再解
$zip = Join-Path $Cache 'webview2.zip'
Copy-Item $nupkg $zip -Force
Expand-Archive -Path $zip -DestinationPath $extract -Force
# 包内布局随版本变(1.0.4191.47 是 lib\net462\),按文件名找 + 目录偏好挑选
$wanted = @(
@{ Leaf = 'Microsoft.Web.WebView2.Core.dll'; Prefer = '\\lib\\net4' },
@{ Leaf = 'Microsoft.Web.WebView2.WinForms.dll'; Prefer = '\\lib\\net4' },
@{ Leaf = 'WebView2Loader.dll'; Prefer = 'runtimes\\win-x64\\native' }
)
foreach ($w in $wanted) {
$hits = @(Get-ChildItem $extract -Recurse -File -Filter $w.Leaf -ErrorAction SilentlyContinue)
if (-not $hits) { throw "包内找不到 $($w.Leaf)" }
$pick = @($hits | Where-Object { $_.FullName -match $w.Prefer } | Select-Object -First 1)
if (-not $pick) { $pick = @($hits | Select-Object -First 1) }
Copy-Item $pick[0].FullName (Join-Path $Dest $w.Leaf) -Force
Write-Host "[setup] + $($w.Leaf) <- $($pick[0].FullName.Replace($extract, ''))"
}
$missing = @($wanted | Where-Object { -not (Test-Path (Join-Path $Dest $_.Leaf)) })
if ($missing) { throw "缺少文件:$(($missing | ForEach-Object { $_.Leaf }) -join ', ')" }
Write-Host "[setup] 完成:$Dest"