mcpField
B
build-windows-exe

build-windows-exe

github.com/sharexDevelopment34251 installsUpdated today
Repository

About build-windows-exe

A Windows build automation skill for producing XerahS installers for x64 and ARM64. It documents sequential packaging, recovery steps for file locks, and checks for recent installer artifacts.

Key features

  1. 01Windows x64 and ARM64 packaging
  2. 02File-lock recovery procedures
  3. 03Manual ARM64 publishing fallback
  4. 04Installer artifact validation

Use cases

  1. 01Building both Windows installer architectures
  2. 02Troubleshooting compilation file locks
  3. 03Checking installer existence and timestamps

Install

Copy the command and run it in a terminal.

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

After installing, type/build-windows-exein Claude Code to confirm it loaded.

Details

From the project README

You are an expert Windows build automation specialist for .NET projects.

Follow these instructions exactly and in order to build Windows executables for XerahS while avoiding common file locking issues.

Build Windows installers for both x64 and ARM64 architectures. Handle file locking issues that commonly occur during compilation. Ensure Inno Setup successfully creates installer executables. Validate that the build artifacts exist and are recent. 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

Shared Build Guardrails

Before Windows packaging work, follow build-common for shared timeout, lock recovery, no-concurrent-build, -m:1, TFM, and SkiaSharp rules. This Windows skill owns Windows packaging commands, Inno Setup behavior, and Windows artifact validation.

Build Process

Preparation

Build the pinned submodule revision. Update ImageEditor only when the task requests it, using the operator's Git wrapper.

Check for another build sharing these outputs. If locks occur, follow build-common to identify task-owned lock holders and clean only the affected outputs. Routine packaging does not require blanket process termination or cleanup.

Phase 2: Initial Build Attempt
  1. Run the packaging script:

    .\build\windows\package-windows.ps1
    
  2. Check for successful completion:

    • Script should complete with exit code 0
    • Both installers should be created in the dist folder
Phase 3: Handle File Lock Failures

If you see errors like:

  • 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'

Then apply these fixes:

  1. Follow build-common to stop only verified task-owned lock holders.

  2. Clean the affected project/output directory if the lock persists.

  3. Pre-build the ShareX.ImageEditor project separately with single-threaded compilation:

    dotnet build 'ShareX.ImageEditor\src\ShareX.ImageEditor\ShareX.ImageEditor.csproj' -c Release -p:UseSharedCompilation=false /m:1
    
    • The /m:1 flag forces single-threaded build
    • UseSharedCompilation=false disables the VBCSCompiler server
  4. Re-run the packaging script:

    .\build\windows\package-windows.ps1
    
Phase 4: Fallback - Manual ARM64 Build

If ARM64 continues to fail but x64 succeeds, build ARM64 manually:

  1. Recover confirmed locks using build-common.

  2. Pre-build ShareX.ImageEditor:

    dotnet build 'ShareX.ImageEditor\src\ShareX.ImageEditor\ShareX.ImageEditor.csproj' -c Release -p:UseSharedCompilation=false /m:1
    
  3. Publish ARM64 manually:

    $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. Publish plugins:

    $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. Run Inno Setup manually:

    $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
    
Phase 5: Validation
  1. Check that both installers exist:

    Get-ChildItem 'dist' -Filter '*.exe' | Select-Object Name, Length, LastWriteTime | Format-Table -AutoSize
    
  2. Verify they were created recently (within the last few minutes)

  3. Expected output:

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

Important Notes

Sequential Builds Are Mandatory

NEVER run two builds at the same time. ShareX.ImageEditor targets multiple TFMs (net9.0, net10.0, net9.0-windows10.0.26100.0, net10.0-windows10.0.26100.0) and MSBuild parallelism causes all of them to race on the same ShareX.ImageEditor.dll output path, producing CS2012 file lock errors.

  • Architectures: package-windows.ps1 already iterates win-x64 then win-arm64 sequentially via foreach — never invoke it twice concurrently.
  • Internal parallelism: Controlled by /m:1 on the dotnet publish call, which forces single-threaded MSBuild and eliminates the intra-build race.
  • Between builds: Always run dotnet build-server shutdown and kill VBCSCompiler between consecutive build sessions.
Why File Locking Happens
  • VBCSCompiler: Roslyn compiler server caches assemblies for faster builds
  • Parallel builds: Multiple projects trying to write the same DLL simultaneously
  • Running XerahS instances: The Watch Folder daemon loads DLLs from Debug folder
  • Avalonia designer: May hold references to compiled DLLs
Key Build Parameters
  • -p:UseSharedCompilation=false: Disables VBCSCompiler server
  • -p:nodeReuse=false: Prevents MSBuild from reusing build nodes
  • /m:1: Forces single-threaded build (slower but no race conditions)
  • -p:SkipBundlePlugins=true: Avoids custom MSBuild target path resolution bugs
Build Error Handling
  • Don't panic if you see CS2012 errors: The build may still succeed
  • Always check if XerahS.exe was created: The error might be during a retry
  • ShareX.ImageEditor is the usual culprit: It has parallel TFM builds (net9.0, net10.0, with/without Windows SDK)
  • ARM64 builds are more prone to locking: They run after x64 which may leave processes
Best Practices
  1. Always run Phase 1 cleanup first
  2. Monitor the build output for "file may be locked by" messages
  3. Check actual file creation, not just exit codes
  4. Keep VBCSCompiler killed during builds
  5. Close any running XerahS instances before building

Success Criteria

  • ✅ Both win-x64 and win-arm64 .exe installers created
  • ✅ Files are ~55-60 MB in size
  • ✅ Timestamps are recent (within build session)
  • ✅ No lingering build processes (VBCSCompiler, dotnet, MSBuild)
  • ✅ Dist folder contains the expected installer files

Troubleshooting

SymptomSolution
"XerahS.exe" does not exist (Inno Setup)The main app didn't publish; check for earlier build errors
CS2012 file lock errorKill VBCSCompiler, delete obj folder, rebuild with /m:1
Installer created but old timestampBuild failed silently; check logs in iscc_log_win-{arch}.txt
Only x64 succeeds, ARM64 failsUse Phase 4 manual ARM64 build process
All builds failClean solution, restart terminal, ensure no XerahS instances running

Related Files

Comments

Markdown supported