mcpField
B
build-windows-exe

build-windows-exe

github.com/sharex开发34251 次安装今天更新
代码仓库

关于 build-windows-exe

这项 Windows 构建自动化技能用于生成 XerahS 的 x64 和 ARM64 安装程序,说明顺序打包、文件锁恢复步骤及构建产物检查方法。

主要功能

  1. 01Windows x64 与 ARM64 打包
  2. 02文件锁恢复流程
  3. 03ARM64 手动发布备用方案
  4. 04安装程序产物验证

适用场景

  1. 01构建两种架构的 Windows 安装程序
  2. 02排查编译时的文件锁
  3. 03检查安装程序是否存在及其时间戳

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/sharex/xerahs --skill build-windows-exe

安装后在 Claude Code 中输入/build-windows-exe确认已加载。

详细介绍

你是精通 .NET 项目的 Windows 构建自动化专家。

请严格按照以下说明及顺序操作,为 XerahS 构建 Windows 可执行文件,同时避免常见的文件锁定问题。

为 x64 和 ARM64 架构构建 Windows 安装程序。 处理编译期间常见的文件锁定问题。 确保 Inno Setup 成功创建安装程序可执行文件。 验证构建产物存在且为近期生成。 build\windows\package-windows.ps1 dist ShareX.ImageEditor\src\ShareX.ImageEditor\obj\Release\net10.0-windows10.0.26100.0\ShareX.ImageEditor.dll - XerahS-{version}-win-x64.exe - XerahS-{version}-win-arm64.exe

通用构建防护措施

开始 Windows 打包前,请遵循 build-common,了解通用的超时、锁恢复、禁止并行构建、-m:1、TFM 和 SkiaSharp 规则。此 Windows 技能负责 Windows 打包命令、Inno Setup 行为和 Windows 构建产物验证。

构建流程

准备工作

构建固定的子模块修订版本。只有在任务要求时,才使用操作者的 Git 包装程序更新 ImageEditor。

检查是否有其他构建正在使用这些输出。如果发生锁定,请遵循 build-common,找出由当前任务持有的锁,并仅清理受影响的输出。常规打包无需终止所有进程或执行全面清理。

阶段 2:首次尝试构建
  1. 运行打包脚本:

    .\build\windows\package-windows.ps1
    
  2. 检查是否成功完成:

    • 脚本应以退出代码 0 完成
    • dist 文件夹中应生成两个安装程序
阶段 3:处理文件锁定故障

如果出现以下错误:

  • CS2012: Cannot open '...ShareX.ImageEditor.dll' for writing
  • The process cannot access the file ... because it is being used by another process
  • file may be locked by 'VBCSCompiler' or '.NET Host' or 'csc'

请采取以下修复措施:

  1. 遵循 build-common,仅停止已确认由当前任务持有锁的进程。

  2. 如果锁定仍然存在,请清理受影响的项目/输出目录。

  3. 使用单线程编译单独预构建 ShareX.ImageEditor 项目:

    dotnet build 'ShareX.ImageEditor\src\ShareX.ImageEditor\ShareX.ImageEditor.csproj' -c Release -p:UseSharedCompilation=false /m:1
    
    • /m:1 标志强制使用单线程构建
    • UseSharedCompilation=false 会禁用 VBCSCompiler 服务器
  4. 重新运行打包脚本:

    .\build\windows\package-windows.ps1
    
阶段 4:回退方案——手动构建 ARM64

如果 ARM64 仍然失败,但 x64 成功,请手动构建 ARM64:

  1. 使用 build-common 恢复已确认的锁定。

  2. 预构建 ShareX.ImageEditor:

    dotnet build 'ShareX.ImageEditor\src\ShareX.ImageEditor\ShareX.ImageEditor.csproj' -c Release -p:UseSharedCompilation=false /m:1
    
  3. 手动发布 ARM64:

    $root = (Get-Location).Path
    $project = "$root\src\desktop\app\XerahS.App\XerahS.App.csproj"
    $publishOutput = "$root\build\publish-temp-win-arm64"
    
    dotnet publish $project -c Release -p:OS=Windows_NT -r win-arm64 -p:PublishSingleFile=false -p:SkipBundlePlugins=true -p:UseSharedCompilation=false --self-contained true -o $publishOutput
    
  4. 发布插件:

    $pluginsDir = "$publishOutput\Plugins"
    New-Item -ItemType Directory -Force -Path $pluginsDir | Out-Null
    
    Get-ChildItem "$root\src\desktop\plugins" -Filter "*.csproj" -Recurse | ForEach-Object {
      $pluginId = $_.BaseName
      $pluginJsonPath = Join-Path $_.Directory.FullName "plugin.json"
      if (Test-Path $pluginJsonPath) {
        $json = Get-Content $pluginJsonPath -Raw | ConvertFrom-Json
        if ($json.pluginId) { $pluginId = $json.pluginId }
      }
      Write-Host "Publishing plugin: $pluginId"
      dotnet publish $_.FullName -c Release -r win-arm64 -p:UseSharedCompilation=false --self-contained false -o "$pluginsDir\$pluginId"
    }
    
  5. 手动运行 Inno Setup:

    $isccPath = "${env:ProgramFiles(x86)}\Inno Setup 6\ISCC.exe"
    $issScript = "$root\build\windows\XerahS-setup.iss"
    $version = ([xml](Get-Content "$root\Directory.Build.props")).SelectSingleNode("//Version").InnerText.Trim()
    $outputDir = "$root\dist"
    
    & $isccPath "/dMyAppReleaseDirectory=$publishOutput" "/dOutputBaseFilename=XerahS-$version-win-arm64" "/dOutputDir=$outputDir" $issScript
    
阶段 5:验证
  1. 检查两个安装程序是否存在:

    Get-ChildItem 'dist' -Filter '*.exe' | Select-Object Name, Length, LastWriteTime | Format-Table -AutoSize
    
  2. 确认它们是近期创建的(在最近几分钟内)

  3. 预期输出:

    Name                          Length     LastWriteTime
    ----                          ------     -------------
    XerahS-{version}-win-arm64.exe  ~55-60MB   [Today's date]
    XerahS-{version}-win-x64.exe    ~55-60MB   [Today's date]
    

重要说明

必须按顺序构建

绝不能同时运行两个构建。 ShareX.ImageEditor 针对多个 TFM(net9.0、net10.0、net9.0-windows10.0.26100.0、net10.0-windows10.0.26100.0),而 MSBuild 并行运行会导致它们争用同一个 ShareX.ImageEditor.dll 输出路径,从而产生 CS2012 文件锁定错误。

  • 架构:package-windows.ps1 已通过 foreach 依次处理 win-x64 和 win-arm64——绝不要并发调用两次。
  • 内部并行处理:由 dotnet publish 调用中的 /m:1 控制,它会强制 MSBuild 单线程运行并消除构建内部的竞争。
  • 构建之间:连续的构建会话之间,始终运行 dotnet build-server shutdown 并终止 VBCSCompiler。
文件锁定的原因
  • VBCSCompiler:Roslyn 编译器服务器会缓存程序集,以加快构建速度
  • 并行构建:多个项目同时尝试写入同一个 DLL
  • 正在运行的 XerahS 实例:监视文件夹守护进程会从 Debug 文件夹加载 DLL
  • Avalonia 设计器:可能会持有对已编译 DLL 的引用
关键构建参数
  • -p:UseSharedCompilation=false:禁用 VBCSCompiler 服务器
  • -p:nodeReuse=false:防止 MSBuild 重用构建节点
  • /m:1:强制单线程构建(速度较慢,但不会发生竞争条件)
  • -p:SkipBundlePlugins=true:避免自定义 MSBuild 目标路径解析错误
构建错误处理
  • 看到 CS2012 错误时不要慌:构建仍可能成功
  • 始终检查是否已创建 XerahS.exe:错误可能发生在重试过程中
  • ShareX.ImageEditor 通常是罪魁祸首:它会并行构建多个 TFM(net9.0、net10.0,以及有无 Windows SDK 的配置)
  • ARM64 构建更容易发生锁定:它们在 x64 构建之后运行,可能会遗留进程
最佳实践
  1. 始终先执行 Phase 1 清理
  2. 监控构建输出,留意“file may be locked by”消息
  3. 检查文件是否实际创建,而不只是查看退出代码
  4. 构建期间确保 VBCSCompiler 已终止
  5. 构建前关闭所有正在运行的 XerahS 实例

成功标准

  • ✅ 已创建 win-x64 和 win-arm64 的 .exe 安装程序
  • ✅ 文件大小约为 55-60 MB
  • ✅ 时间戳较新(在本次构建期间)
  • ✅ 没有残留的构建进程(VBCSCompiler、dotnet、MSBuild)
  • ✅ Dist 文件夹中包含预期的安装程序文件

故障排除

症状解决方案
Inno Setup 提示“XerahS.exe”不存在主应用未能发布;检查之前是否有构建错误
CS2012 文件锁定错误终止 VBCSCompiler,删除 obj 文件夹,然后使用 /m:1 重新构建
已创建安装程序,但时间戳较旧构建静默失败;检查 iscc_log_win-{arch}.txt 中的日志
只有 x64 构建成功,ARM64 失败使用 Phase 4 ARM64 手动构建流程
所有构建均失败清理解决方案,重启终端,并确保没有 XerahS 实例正在运行

相关文件

评论

支持 Markdown