#Requires -Version 5.1 <# .SYNOPSIS pptopic 一键安装脚本 .DESCRIPTION 自动完成以下安装步骤: 1. 安装 uv(Python 包管理器) 2. 安装 Python 3.13 3. 安装 pngquant(可选但推荐) 4. 安装 pptopic 5. 验证安装结果 本脚本会自动处理 PowerShell 执行策略和当前会话 PATH 刷新, 安装完成后无需手动重启 PowerShell。 .PARAMETER SkipPngquant 跳过 pngquant 安装。 .PARAMETER Force 强制重新安装 uv 和 pngquant。 .PARAMETER SkipPptopicInstall 只安装环境,不安装 pptopic(调试用)。 .EXAMPLE .\setup.ps1 .EXAMPLE .\setup.ps1 -SkipPngquant #> param( [switch]$SkipPngquant, [switch]$Force, [switch]$SkipPptopicInstall ) $ErrorActionPreference = "Stop" $InformationPreference = "Continue" $ProjectRoot = $PSScriptRoot if ([string]::IsNullOrWhiteSpace($ProjectRoot)) { $ProjectRoot = (Get-Location).Path } # ============================================================ # 工具函数 # ============================================================ function Test-CommandExists { param([string]$Name) try { $cmd = Get-Command $Name -ErrorAction Stop return $cmd.Source } catch { return $null } } function Add-ToCurrentPath { param([string]$LiteralPath) if ([string]::IsNullOrWhiteSpace($LiteralPath)) { return } $currentPaths = $env:Path -split ';' | ForEach-Object { $_.TrimEnd('\') } $normalizedPath = $LiteralPath.TrimEnd('\') if ($normalizedPath -in $currentPaths) { return } if (-not (Test-Path $LiteralPath)) { return } $env:Path = "$LiteralPath;$env:Path" Write-Information "已临时将 $LiteralPath 加入当前会话 PATH" } function Get-UvInstallDir { # uv-installer.ps1 的安装位置优先级 $candidates = @() if ($env:XDG_BIN_HOME) { $candidates += $env:XDG_BIN_HOME } if ($env:XDG_DATA_HOME) { $candidates += (Join-Path $env:XDG_DATA_HOME "../bin") } $candidates += (Join-Path $HOME ".local\bin") foreach ($candidate in $candidates) { $resolved = $null try { $resolved = (Resolve-Path $candidate -ErrorAction SilentlyContinue).Path } catch { $resolved = $candidate } if ($resolved -and (Test-Path $resolved)) { return $resolved } } # 默认返回最后一个候选 return Join-Path $HOME ".local\bin" } function Invoke-Step { param( [Parameter(Mandatory)][string]$Title, [Parameter(Mandatory)][scriptblock]$Action ) Write-Information "" Write-Information "========================================" Write-Information " $Title" Write-Information "========================================" try { & $Action } catch { Write-Information "" Write-Information "失败:$_" throw } } # ============================================================ # 主流程 # ============================================================ Write-Information "" Write-Information "========================================" Write-Information " pptopic 一键安装程序" Write-Information "========================================" Write-Information "" Write-Information "项目目录:$ProjectRoot" if ($SkipPngquant) { Write-Information "已指定 -SkipPngquant,将跳过 pngquant 安装。" } if ($Force) { Write-Information "已指定 -Force,将强制重新安装 uv / pngquant。" } # 第一步:安装 uv Invoke-Step -Title "步骤 1/5:安装 uv" -Action { $uvPath = Test-CommandExists -Name "uv" if ($uvPath -and -not $Force) { Write-Information "uv 已存在:$uvPath" } else { $installer = Join-Path $ProjectRoot "uv-installer.ps1" if (-not (Test-Path $installer)) { throw "找不到 uv 安装脚本:$installer" } Write-Information "正在运行 uv-installer.ps1..." & $installer } # uv-installer.ps1 会修改注册表 PATH,但当前会话不会立即生效,需要手动加入 $uvInstallDir = Get-UvInstallDir Add-ToCurrentPath -LiteralPath $uvInstallDir # 再次验证 $uvPath = Test-CommandExists -Name "uv" if (-not $uvPath) { throw "uv 安装后仍无法在当前会话中找到,请尝试重启终端后重试。" } Write-Information "uv 路径:$uvPath" } # 第二步:安装 Python 3.13 Invoke-Step -Title "步骤 2/5:安装 Python 3.13" -Action { Write-Information "正在使用 uv 安装 Python 3.13..." uv python install 3.13 Write-Information "Python 安装完成。" } # 第三步:安装 pngquant if (-not $SkipPngquant) { Invoke-Step -Title "步骤 3/5:安装 pngquant" -Action { $pngquantPath = Test-CommandExists -Name "pngquant" if ($pngquantPath -and -not $Force) { Write-Information "pngquant 已存在:$pngquantPath" } else { $installer = Join-Path $ProjectRoot "install-pngquant.ps1" if (-not (Test-Path $installer)) { throw "找不到 pngquant 安装脚本:$installer" } if ($Force) { Write-Information "正在运行 install-pngquant.ps1 -Force..." & $installer -Force } else { Write-Information "正在运行 install-pngquant.ps1..." & $installer } } # install-pngquant.ps1 内部已刷新当前会话 PATH,这里再做一次保险 Add-ToCurrentPath -LiteralPath "$env:APPDATA\pngquant" $pngquantPath = Test-CommandExists -Name "pngquant" if (-not $pngquantPath) { throw "pngquant 安装后仍无法在当前会话中找到,请尝试重启终端后重试。" } Write-Information "pngquant 路径:$pngquantPath" } } else { Write-Information "" Write-Information "========================================" Write-Information " 步骤 3/5:跳过 pngquant 安装" Write-Information "========================================" } # 第四步:安装 pptopic if (-not $SkipPptopicInstall) { Invoke-Step -Title "步骤 4/5:安装 pptopic" -Action { $pyproject = Join-Path $ProjectRoot "pyproject.toml" if (-not (Test-Path $pyproject)) { throw "找不到 pyproject.toml:$pyproject" } Write-Information "正在使用 uv tool install -e $ProjectRoot 安装 pptopic..." uv tool install -e $ProjectRoot Write-Information "pptopic 安装完成。" } } else { Write-Information "" Write-Information "========================================" Write-Information " 步骤 4/5:跳过 pptopic 安装" Write-Information "========================================" } # 第五步:验证 Invoke-Step -Title "步骤 5/5:验证安装" -Action { Write-Information "" Write-Information "--- uv 版本 ---" uv --version if (-not $SkipPngquant) { Write-Information "" Write-Information "--- pngquant 版本 ---" pngquant --version } if (-not $SkipPptopicInstall) { Write-Information "" Write-Information "--- pptopic 版本 ---" pptopic version } } # ============================================================ # 完成 # ============================================================ Write-Information "" Write-Information "========================================" Write-Information " pptopic 一键安装完成!" Write-Information "========================================" Write-Information "" if (-not $SkipPptopicInstall) { Write-Information "你可以立即在当前窗口使用以下命令:" Write-Information " pptopic export 你的文件.pptx" Write-Information " pptopic export 你的文件.pptx --optimize --max-height 29999 -o result.png" } Write-Information "" Write-Information "提示:本脚本已自动刷新当前 PowerShell 会话的 PATH,无需重启终端。" Write-Information "如果关闭此窗口后在新窗口中找不到命令,请重新运行一次 setup.bat。" Write-Information ""