How to Build PowerToys with Visual Studio and build.cmd Scripts
You can build Microsoft PowerToys from source using wrapper scripts located in tools/build/ that automatically configure the Visual Studio environment, detect your platform architecture, and invoke MSBuild with the correct parameters.
Microsoft PowerToys is a multi-module Windows utility suite compiled from the PowerToys.slnx solution and dozens of supporting projects. Whether you need a fast inner-loop build or a full installer package, the repository provides cmd wrapper scripts that streamline building PowerToys with Visual Studio by handling environment detection, NuGet restoration, and MSBuild invocation automatically.
Build Script Architecture Overview
The repository ships three primary cmd wrappers in tools/build/. Each is a thin shim that passes arguments to a corresponding PowerShell script, ensuring consistent behavior whether you launch from cmd.exe, PowerShell, or the Visual Studio Developer PowerShell.
Generic Build Entry Point (build.cmd)
The tools/build/build.cmd script serves as the generic entry point for compiling any .sln, .csproj, or .vcxproj in the current working directory. It forwards all arguments to tools/build/build.ps1, which:
- Detects the host platform (
x64orarm64) if not explicitly supplied. - Bootstraps the Visual Studio developer shell via
Enter-VsDevShellorVsDevCmd.bat. - Passes extra MSBuild arguments unchanged through the
$ExtraArgsarray.
Essential Components Build (build-essentials.cmd)
For rapid iteration, tools/build/build-essentials.cmd invokes build-essentials.ps1 to perform a minimal restore-and-build cycle. This script restores NuGet packages for the solution and compiles only the runner and settings projects—the minimum set required to run PowerToys—skipping the optional utility modules.
Full Installer Pipeline (build-installer.cmd)
When you need distributable artifacts, tools/build/build-installer.cmd orchestrates the complete packaging pipeline via build-installer.ps1. This wrapper performs NuGet restoration, compilation, code signing, and generates both MSI and MSIX installers in the installer/ directory. It accepts installer-specific switches such as -PerUser and -InstallerSuffix.
PowerShell Build Implementation
The cmd wrappers delegate all heavy lifting to PowerShell modules designed to be platform-agnostic and directory-agnostic.
Shared Helper Functions (build-common.ps1)
The tools/build/build-common.ps1 module defines reusable functions consumed by the other scripts:
Ensure-VsDevEnvironment– Locates the Visual Studio installation usingvswhere.exeand initializes the developer shell.Get-DefaultPlatform– Inspects the host CPU architecture to default tox64orarm64.BuildProjectsInDirectory– Locates the nearest solution or project file and invokes MSBuild with the resolved/p:Platform=and/p:Configuration=values.
Core Driver (build.ps1)
tools/build/build.ps1 parses explicit parameters including -Platform, -Configuration, -Path, -RestoreOnly, and -ExtraArgs. It automatically discovers the build target if invoked from a subdirectory (e.g., src/modules/fancyzones), then calls BuildProjectsInDirectory with the aggregated MSBuild property flags.
Step-by-Step Build Instructions
Prerequisites
Install Visual Studio 2022 (or later) with the following workloads:
- Desktop development with C++
- .NET desktop development
Ensure vswhere.exe is available on your PATH (installed by default with Visual Studio), as build-common.ps1 depends on it to locate the MSBuild toolchain.
Fast Essential Build
Run the essentials wrapper to restore packages and compile only the runner and settings UI. This is the fastest way to verify that the core application runs:
tools\build\build-essentials.cmd
By default, this produces a Debug build on the auto-detected platform.
Full Solution Build
From the repository root (or any project subdirectory), invoke the generic wrapper. Explicitly set the platform and configuration for release builds:
tools\build\build.cmd -Platform x64 -Configuration Release
If you omit the switches, the script defaults to a Debug build on the detected platform.
Building Individual Modules
Because build.ps1 searches upward for the nearest project file, you can rebuild a single module without loading the entire solution in the IDE:
cd src\modules\fancyzones
..\..\..\tools\build\build.cmd -Configuration Release
Passing Custom MSBuild Arguments
Append any valid MSBuild properties after the script name. The wrappers forward these to the $ExtraArgs array and concatenate them into the final MSBuild command line:
tools\build\build.cmd '/p:CIBuild=true' '/p:EnableTelemetry=false'
To perform only the NuGet restore step without compiling:
tools\build\build.cmd -RestoreOnly
Locating Build Logs
On failure, the scripts generate three diagnostic files alongside the solution with the pattern build.[Configuration].[Platform].*.log:
build.Release.x64.errors.log– Contains only compilation errors.build.Release.x64.all.log– Full console output from the build.build.Release.x64.trace.binlog– Binary log for analysis in the MSBuild Structured Log Viewer.
These locations are documented in tools/build/BUILD-GUIDELINES.md.
Summary
- The cmd wrappers in
tools/build/provide a consistent command-line interface acrosscmd.exe, PowerShell, and Visual Studio Developer PowerShell. build-essentials.cmdrestores NuGet packages and compiles only the runner and settings UI for rapid development cycles.build.cmdautomatically detects platform architecture and accepts standard MSBuild parameters such as-Platform,-Configuration, and custom/p:properties via the$ExtraArgsarray.build-installer.cmdorchestrates the full pipeline including signing and MSI/MSIX generation.- The underlying PowerShell modules (
build-common.ps1,build.ps1) handle Visual Studio environment initialization viaEnter-VsDevShelland locate projects from any subdirectory. - Build outputs include structured logs (error-only, full text, and binary) to diagnose failures quickly.
Frequently Asked Questions
What are the prerequisites for building PowerToys with Visual Studio?
Install Visual Studio 2022 or later with the "Desktop development with C++" and ".NET desktop development" workloads. The build scripts also require vswhere.exe to be on your PATH so they can locate the Visual Studio installation and initialize the developer environment automatically.
What is the difference between build.cmd and build-essentials.cmd?
build.cmd is a generic wrapper that builds any solution or project in the current directory, defaulting to a Debug configuration on the auto-detected platform. build-essentials.cmd specifically targets PowerToys.slnx to restore NuGet packages and compile only the runner and settings UI, skipping the optional utility modules for significantly faster build times during development.
How do I pass custom MSBuild properties to the PowerToys build scripts?
Append any standard MSBuild arguments after the script name. The cmd wrappers forward all trailing arguments to PowerShell, which collects them into the $ExtraArgs array and passes them directly to MSBuild. For example: tools\build\build.cmd '/p:CIBuild=true' disables code-signing steps suitable for CI pipelines.
Where can I find build logs if the compilation fails?
The scripts generate three log files in the solution directory: build.[Configuration].[Platform].errors.log containing only errors, .all.log with full console output, and .trace.binlog for detailed analysis in the MSBuild Structured Log Viewer. These files help diagnose missing dependencies or configuration mismatches.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →