diff --git a/README.md b/README.md index ad37630..1e97148 100644 --- a/README.md +++ b/README.md @@ -44,19 +44,21 @@ > 如果 Windows 提示“Windows 已保护你的电脑”,请点击“更多信息” → “仍要运行”。 -#### 方法 B:右键在 PowerShell 中运行 +#### 方法 B:右键在终端中运行 如果双击运行被系统拦截,可以按以下步骤: 1. 打开解压后的 `pptopic` 文件夹 2. 在文件夹**空白处**按住 `Shift` 键,同时点击**鼠标右键** 3. 选择“在此处打开 PowerShell 窗口”(Windows 11 可能显示为“在终端中打开”) -4. 在弹出的蓝色窗口中输入以下命令,然后按回车: +4. 在弹出的窗口中输入以下命令,然后按回车: ```powershell .\setup.bat ``` +> 打开的终端可能是 PowerShell(蓝色窗口)或命令提示符 cmd(黑色窗口),两种情况下 `.\setup.bat` 都能正常运行。如果是 cmd,也可以省略前面的 `.\` 直接输入 `setup.bat`。 + 等待安装完成即可。 #### 安装完成后 @@ -71,9 +73,15 @@ uv 0.11.20 2.17.0 --- pptopic 版本 --- -pptopic 0.3.2 +pptopic version: 0.3.2 +Under the MIT License. + +--- PowerPoint 检测 --- +PowerPoint 已安装(检测到 PowerPoint.Application 注册项)。 ``` +> 如果你没有安装 PowerPoint,最后一行会显示警告,提示你先安装 PowerPoint,否则 `pptopic export` 命令无法运行。 + 然后你可以直接在当前窗口使用 pptopic: ```powershell @@ -254,11 +262,12 @@ pptopic optimize image.png pptopic optimize --help ``` -## 图片优化 +## 图片优化引擎 为了获得最佳的图片压缩效果,推荐使用 [pngquant](https://pngquant.org/) 进行图片压缩。 +当然也可以使用其他图片压缩工具,如 [libvips](https://www.libvips.org/) 等,不过需要自己设置引擎的优化参数。 -### 安装脚本 +### PngQuant安装脚本 可以使用提供的 PowerShell 脚本安装 pngquant: @@ -321,6 +330,12 @@ powershell -ExecutionPolicy Bypass -File .\setup.ps1 -SkipPngquant 但强烈建议安装,否则导出的长图文件会比较大。 +### 安装时报“未检测到 PowerPoint” + +安装脚本会在最后一步检测 PowerPoint 是否安装。如果看到这个警告,说明系统里没有 PowerPoint,`pptopic export` 命令将无法运行(它需要通过 PowerPoint 导出幻灯片)。 + +请安装 Microsoft PowerPoint(Office 2016 或更新版本)后重试。PowerPoint 不在一键安装脚本的自动安装范围内,需要自行安装。 + ## License MIT License diff --git a/setup.ps1 b/setup.ps1 index e9de12e..f896d8a 100644 --- a/setup.ps1 +++ b/setup.ps1 @@ -108,6 +108,60 @@ function Get-UvInstallDir { return Join-Path $HOME ".local\bin" } +function Invoke-NativeCommand { + # 安全地调用原生程序(uv/pngquant 等)。 + # 这些程序的进度/提示信息常写到 stderr(例如 "Python 3.13 is already installed"), + # 而本脚本 $ErrorActionPreference="Stop" 会把 stderr 当作终止错误抛出,导致重跑误失败。 + # 此函数临时关闭 Stop,合并 stdout/stderr,并按退出码判断成败。 + param( + [Parameter(Mandatory)][string]$LiteralCommand, + [string]$FailureMessage + ) + + $prevEAP = $ErrorActionPreference + $ErrorActionPreference = 'Continue' + try { + $output = Invoke-Expression "$LiteralCommand 2>&1" + } finally { + $ErrorActionPreference = $prevEAP + } + + if ($LASTEXITCODE -ne 0) { + $msg = if ($FailureMessage) { $FailureMessage } else { "命令失败" } + throw "$msg(退出码 $LASTEXITCODE):$($output -join "`n")" + } + + return $output +} + +function Test-PowerPointInstalled { + # 通过注册表 ProgID 检测,不启动 PowerPoint 进程 + try { + $null = Get-Item "Registry::HKEY_CLASSES_ROOT\PowerPoint.Application" -ErrorAction Stop + return $true + } catch { + return $false + } +} + +function Get-PngquantInstallDir { + # pngquant 可能的安装位置:默认 %APPDATA%\pngquant,或 scoop 的 shims 目录 + $candidates = @("$env:APPDATA\pngquant") + if ($env:SCOOP) { + $candidates += (Join-Path $env:SCOOP "shims") + } + $candidates += (Join-Path $HOME "scoop\shims") + + foreach ($candidate in $candidates) { + if (Test-Path $candidate) { + return $candidate + } + } + + # 找不到就返回默认(即便不存在,Add-ToCurrentPath 内部会跳过) + return "$env:APPDATA\pngquant" +} + function Invoke-Step { param( [Parameter(Mandatory)][string]$Title, @@ -178,7 +232,10 @@ Invoke-Step -Title "步骤 1/5:安装 uv" -Action { # 第二步:安装 Python 3.13 Invoke-Step -Title "步骤 2/5:安装 Python 3.13" -Action { Write-Information "正在使用 uv 安装 Python 3.13..." - uv python install 3.13 + # uv 在 Python 已安装时会向 stderr 输出 "Python 3.13 is already installed"(退出码仍为 0), + # 通过 Invoke-NativeCommand 绕过 Stop 模式对 stderr 的误判。 + $output = Invoke-NativeCommand -LiteralCommand "uv python install 3.13" -FailureMessage "uv python install 失败" + Write-Information ($output -join "`n") Write-Information "Python 安装完成。" } @@ -205,7 +262,8 @@ if (-not $SkipPngquant) { } # install-pngquant.ps1 内部已刷新当前会话 PATH,这里再做一次保险 - Add-ToCurrentPath -LiteralPath "$env:APPDATA\pngquant" + # 覆盖默认安装位置和 scoop 安装位置两种情况 + Add-ToCurrentPath -LiteralPath (Get-PngquantInstallDir) $pngquantPath = Test-CommandExists -Name "pngquant" if (-not $pngquantPath) { @@ -230,7 +288,9 @@ if (-not $SkipPptopicInstall) { } Write-Information "正在使用 uv tool install -e $ProjectRoot 安装 pptopic..." - uv tool install -e $ProjectRoot + # uv 的进度/解析信息会写 stderr,通过 Invoke-NativeCommand 绕过 Stop 模式误判。 + $output = Invoke-NativeCommand -LiteralCommand "uv tool install -e `"$ProjectRoot`"" -FailureMessage "uv tool install 失败" + Write-Information ($output -join "`n") Write-Information "pptopic 安装完成。" } } else { @@ -242,20 +302,38 @@ if (-not $SkipPptopicInstall) { # 第五步:验证 Invoke-Step -Title "步骤 5/5:验证安装" -Action { + # 版本命令可能写到 stderr(部分 CLI 行为不一致), + # 在 Stop 模式下会误报失败,统一通过 Invoke-NativeCommand 安全调用。 + Write-Information "" Write-Information "--- uv 版本 ---" - uv --version + $v = Invoke-NativeCommand -LiteralCommand "uv --version" -FailureMessage "uv 版本查询失败" + Write-Information ($v -join "`n") if (-not $SkipPngquant) { Write-Information "" Write-Information "--- pngquant 版本 ---" - pngquant --version + $v = Invoke-NativeCommand -LiteralCommand "pngquant --version" -FailureMessage "pngquant 版本查询失败" + Write-Information ($v -join "`n") } if (-not $SkipPptopicInstall) { Write-Information "" Write-Information "--- pptopic 版本 ---" - pptopic version + $v = Invoke-NativeCommand -LiteralCommand "pptopic version" -FailureMessage "pptopic 版本查询失败" + Write-Information ($v -join "`n") + } + + # PowerPoint 是运行时必需依赖(win32com 调用),但安装阶段无法自动安装, + # 这里只做检测并给出明确提示,把缺失问题前置,避免用户装完后才发现用不了。 + Write-Information "" + Write-Information "--- PowerPoint 检测 ---" + if (Test-PowerPointInstalled) { + Write-Information "PowerPoint 已安装(检测到 PowerPoint.Application 注册项)。" + } else { + Write-Information "警告:未检测到 PowerPoint。" + Write-Information "pptopic 导出 PPTX 时需要调用 PowerPoint(Office 2016 或更新版本)。" + Write-Information "请先安装 PowerPoint,否则 'pptopic export' 命令将无法运行。" } }