2020-12-14 15:20:45 +03:00
<?xml version="1.0" encoding="utf-8"?>
2021-07-12 13:35:57 +03:00
<Project ToolsVersion="4.0"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2020-12-14 15:20:45 +03:00
Build: Fix release pipeline and local build failure (#45211)
## Summary of the Pull Request
Release pipeline is keeping failed, and local build failed at ut.
This pull request introduces changes to improve how test projects are
handled during release builds, ensuring that test code is not compiled
or analyzed when not needed - in doing release build, to - succeed the
execution and reduce built time.
And, to upgrade from VS17 to VS18 in cmdpal sdk build, this is to keep
consistency with all other build step
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [ ] Closes: #xxx
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [ ] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [ ] **Tests:** Added/updated and all pass
- [ ] **Localization:** All end-user-facing strings can be localized
- [ ] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places
- [ ] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [ ] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [ ] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [ ] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [ ] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: #xxx
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Local build & release pipeline build should all pass:
Local build:
<img width="1815" height="281" alt="image"
src="https://github.com/user-attachments/assets/f350cf3f-b856-432d-97f3-e392d38ef7fa"
/>
Release pipeline is working too:
<img width="1195" height="163" alt="image"
src="https://github.com/user-attachments/assets/ce58de38-f0fb-45ad-9d70-2b8eb1c4db60"
/>
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-02-02 09:15:53 +08:00
<!-- Skip building C++ test projects when BuildTests=false -->
<PropertyGroup Condition="'$(_IsSkippedTestProject)' == 'true'">
<UsePrecompiledHeaders>false</UsePrecompiledHeaders>
<RunCodeAnalysis>false</RunCodeAnalysis>
</PropertyGroup>
2020-12-14 15:20:45 +03:00
<!-- Project configurations -->
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
2022-08-27 02:17:20 +03:00
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
2020-12-14 15:20:45 +03:00
</ItemGroup>
2021-07-12 13:35:57 +03:00
2022-12-10 00:09:26 +00:00
<!-- Run code analysis locally and in PR CI, but not on release CI -->
<PropertyGroup Condition="'$(SkipCppCodeAnalysis)' == ''">
<RunCodeAnalysis>true</RunCodeAnalysis>
<CodeAnalysisRuleSet>$(MsbuildThisFileDirectory)\CppRuleSet.ruleset</CodeAnalysisRuleSet>
2025-11-13 17:59:21 -06:00
<CAExcludePath>$(MSBuildThisFileDirectory)deps;$(MSBuildThisFileDirectory)packages;$(CAExcludePath)</CAExcludePath>
2022-12-10 00:09:26 +00:00
</PropertyGroup>
2020-12-14 15:20:45 +03:00
<!-- C++ source compile-specific things for all configurations -->
2021-07-12 13:35:57 +03:00
<PropertyGroup>
2022-09-05 15:39:56 +03:00
<PreferredToolArchitecture>x64</PreferredToolArchitecture>
2022-12-15 18:40:29 -05:00
<PreferredToolArchitecture Condition="'$(PROCESSOR_ARCHITECTURE)' == 'ARM64' or '$(PROCESSOR_ARCHITEW6432)' == 'ARM64'">arm64</PreferredToolArchitecture>
Migrate spdlog from submodule to vcpkg (#48039)
## Summary
Migrate `deps/spdlog` from a git submodule to **vcpkg manifest mode**
with an overlay port pinned to the **exact same commit**
(`gabime/spdlog@616866fc`). Replaces the polyfill shim added in #47910
with a proper port-level patch.
This is the follow-up to PR #47928, which I closed after @zadjii-msft /
@DHowett clarified that the intended direction was a single combined
"move to vcpkg **and** apply a patch file" (one change, not two stepping
stones).
## Guidance honored
Per @zadjii-msft (offline):
- ✅ Convert each submodule to vcpkg **one at a time** — this PR is
**spdlog only**. `deps/expected-lite` stays a submodule (separate PR
next).
- ✅ Atomic commit per dep (multiple commits on the branch for review
traceability; squash on merge gives the requested single commit).
- ✅ **Don't bump the version.** Only variable changed: submodule →
vcpkg. Same commit (`616866fc`, v1.8.5 + 38) the submodule pointed at.
Per @DHowett
([review](https://github.com/microsoft/PowerToys/pull/48039#pullrequestreview-4338835150)):
- ✅ No vcpkg submodule — vswhere-first detection via a Terminal-style
`steps-install-vcpkg.yml` template; three-tier `VcpkgRoot` fallback (env
var → VS-shipped → runtime clone pinned to manifest baseline).
## Design
- **Repo-root manifest**: `vcpkg.json` declares only `spdlog`, with
`builtin-baseline` pinned. `vcpkg-configuration.json` registers
`deps/vcpkg-overlays/` as overlay-ports.
- **Overlay port** `deps/vcpkg-overlays/spdlog/`: `vcpkg_from_github(REF
616866fc...)` with bundled fmt preserved (`-DSPDLOG_FMT_EXTERNAL=OFF`);
the MSVC 14.51 fix from #47910 carried as a proper vcpkg patch on
`include/spdlog/fmt/bundled/format.h`.
- **vcpkg integration is global** (set in `Cpp.Build.props`, imported
via `ForceImportBeforeCppProps` for every `.vcxproj`). An earlier
attempt to make vcpkg per-project-opt-in via `deps/spdlog.props` failed
because ~85 PowerToys `.vcxproj` files import `spdlog.props` AFTER
`Microsoft.Cpp.targets`, by which point `vcpkg.props`' `ClCompile` hook
is dead-on-arrival. The trade-off (every C++ project invokes `vcpkg
install` once at build time, ~0.5 s on cache hits, manifest declares
only spdlog so install set is fixed) is documented in the expanded
`Cpp.Build.props` comment.
- **`deps/spdlog.props`** is now a thin shim that only sets the
historical `SPDLOG_*` preprocessor defines for source-compat.
- **`Cpp.Build.targets`** is a new file imported via
`ForceImportAfterCppTargets` to load `vcpkg.targets` after
`Microsoft.Cpp.targets`. A fail-fast `<Target>` errors with a clear
message if `vcpkg.props` can't be found at the resolved `VcpkgRoot`.
- **Removes** `deps/spdlog-msvc-fix/` polyfill, in-tree wrapper
`src/logging/`, spdlog submodule, the single `<ProjectReference>` in
`logger.vcxproj`, plus 3 `.slnf` refs and 2 `.slnx` refs
(`PowerToys.slnx` + `installer/PowerToysSetup.slnx`), plus 3 hard-coded
`..\deps\spdlog\include` entries in `<AdditionalIncludeDirectories>`.
- **CI**: new reusable `.pipelines/v2/templates/steps-install-vcpkg.yml`
(vswhere-first, manifest-baseline-pinned fallback clone, respects
`useVSPreview`). Gated `Cache@2` for `%LOCALAPPDATA%\vcpkg\archives`
keyed on overlay-port contents. Same vcpkg detection added to
`tools\build\build-essentials.ps1` for local devs.
## Verification
Local build matrix (all 4 configs of `logger.vcxproj` and a
representative late-import consumer):
| Config | Result | Notes |
|--------|--------|-------|
| Release \| x64 | ✅ | vcpkg install ~21 s, `logger.lib` produced |
| Debug \| x64 | ✅ | **Validates patch fixes the actual MSVC 14.51 bug**
(`_ITERATOR_DEBUG_LEVEL > 0` → `_SECURE_SCL`) |
| Release \| ARM64 | ✅ | vcpkg cross-installs `arm64-windows-static`
spdlog in ~16 s |
| Debug \| ARM64 | ✅ | **Previously DISABLED for the in-tree spdlog**
(per `<Build Solution="Debug\|ARM64" Project="false" />` in
`PowerToysSetup.slnx`); this migration FIXES that latent gap |
| FancyZonesLib (Release \| x64) | ✅ | Late-import-pattern consumer;
previously broke in v2 |
Full PowerToys CI (x64 + arm64 + CmdPal SDK + all GitHub Actions checks)
green.
**Consumer audit**: 72 `.vcxproj` files reference `logger.vcxproj`; all
72 also import `deps/spdlog.props`. No transitive-link breakage.
## Out of scope (intentional)
- `deps/expected-lite` migration — next PR per "one-at-a-time" rule.
- Remote vcpkg binary cache (Azure Artifacts NuGet feed). Local pipeline
`Cache@2` works for now, but a remote feed survives across pipelines and
is the long-term answer. Happy to split this into a follow-up.
## Notes for review
- Patch in the overlay port is identical content to PR #47928's patch
but regenerated with LF line endings (vcpkg's `vcpkg_apply_patches` is
strict; no `--ignore-whitespace`).
- Once PowerToys eventually bumps spdlog past v1.14 (which ships fmt
10.2 and drops the affected code path), the overlay port can be deleted
and we can use upstream vcpkg's `spdlog` directly.
- Re. official-release pipelines and terrapin / less-restricted network
isolation: VS-shipped vcpkg is the primary path (no network); the
fallback clone is only exercised when VS doesn't ship vcpkg. Happy to
wire terrapin into the fallback as a follow-up if the official build
template needs it.
Closes the work tracked in #47928 (which was closed unmerged).
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Dustin L. Howett <dustin@howett.net>
2026-05-27 15:45:24 +08:00
<!-- vcpkg.targets is imported via Cpp.Build.targets after Microsoft.Cpp.targets. -->
<ForceImportAfterCppTargets>$(MSBuildThisFileDirectory)Cpp.Build.targets</ForceImportAfterCppTargets>
2024-07-18 15:48:46 +02:00
<ReplaceWildcardsInProjectItems>true</ReplaceWildcardsInProjectItems>
2025-11-13 17:59:21 -06:00
<ExternalIncludePath>$(MSBuildThisFileDirectory)deps;$(MSBuildThisFileDirectory)packages;$(ExternalIncludePath)</ExternalIncludePath>
2023-10-04 09:40:01 -05:00
<!-- Enable control flow guard for C++ projects that don't consume any C++ files -->
<!-- This covers the case where a .dll exports a .lib, but doesn't have any ClCompile entries. -->
<LinkControlFlowGuard>Guard</LinkControlFlowGuard>
2021-07-12 13:35:57 +03:00
</PropertyGroup>
2020-12-14 15:20:45 +03:00
<ItemDefinitionGroup>
<ClCompile>
2025-12-16 10:46:39 +08:00
<!-- Make angle-bracket includes external and turn off code analysis for them -->
<TreatAngleIncludeAsExternal>true</TreatAngleIncludeAsExternal>
<ExternalWarningLevel>TurnOffAllWarnings</ExternalWarningLevel>
<DisableAnalyzeExternal>true</DisableAnalyzeExternal>
2024-03-22 03:29:14 -07:00
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<PrecompiledHeader Condition="'$(UsePrecompiledHeaders)' != 'false'">Use</PrecompiledHeader>
2022-11-09 14:41:14 +00:00
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
2022-11-08 16:27:24 +00:00
<WarningLevel>Level4</WarningLevel>
[Dev][Build] VS 2026 Support (#44304)
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request
This PR updates the PowerToys solution to support **Visual Studio 2026
(PlatformToolset v145)**. It centralizes the build configuration,
updates the C++ language standards, and fixes an issue with a MouseJump
unit test that appears while using the VS 2026 supported build agent.
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [ ] Closes: #xxx
- [x] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [x] **Tests:** Added/updated and all pass
- [ ] **Localization:** All end-user-facing strings can be localized
- [x] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places
- [ ] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [ ] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [ ] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [ ] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [ ] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: #xxx
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
**Build System & Configuration:**
- Updated `Cpp.Build.props` to use `v145` (VS 2026) as the default
`PlatformToolset`, with fall back to `v143` for VS 2022.
- Configured C++ Language Standard:
- `stdcpplatest` for production projects.
- Removed explicit `<PlatformToolset>` definitions from individual
project files (approx. 37 modules) to inherit correctly from the central
`Cpp.Build.props`.
**Code Refactoring & Fixes:**
- Updated `DrawingHelperTests.cs` in MouseJump Unit Test to ease the
pixel difference tolerance. This became an issue after switching to the
new VS2026 build agent.
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
- Validated successful compilation of the entire solution. Similar
updates have been made to the .NET 10 branch, but these are much cleaner
and will be merged into that branch once fully confirmed working.
---------
Co-authored-by: Kai Tao (from Dev Box) <kaitao@microsoft.com>
Co-authored-by: Gordon Lam (SH) <yeelam@microsoft.com>
2026-01-28 18:46:34 -05:00
<DisableSpecificWarnings>4679;4706;4874;5271;%(DisableSpecificWarnings)</DisableSpecificWarnings>
2021-07-12 13:35:57 +03:00
<DisableAnalyzeExternal >true</DisableAnalyzeExternal>
<ExternalWarningLevel>TurnOffAllWarnings</ExternalWarningLevel>
2020-12-14 15:20:45 +03:00
<ConformanceMode>false</ConformanceMode>
2020-12-21 18:51:48 +03:00
<TreatWarningAsError>true</TreatWarningAsError>
2020-12-14 15:20:45 +03:00
<LanguageStandard>stdcpplatest</LanguageStandard>
2023-10-04 09:40:01 -05:00
<BuildStlModules>false</BuildStlModules>
[Build] Fix UTF-8 and output paths for local C++ builds (#49575)
## Summary of the Pull Request
Fixes two local C++ build reliability problems:
- Compiles all PowerToys C++ projects as UTF-8 through
`Cpp.Build.props`, so builds do not depend on the active Windows code
page. On code page 936, UTF-8 punctuation in BOM-less source files
otherwise triggers C4819 and fails the build because warnings are
treated as errors.
- Uses `$(RepoRoot)` for Keyboard Manager repository paths and
standardizes native/test output directories. This makes direct project
builds find the resource conversion script and headers, places the
Editor wrapper beside the WinUI app, and keeps the Engine test DLL under
the repository test output directory.
No runtime logic, end-user strings, dependencies, or binaries are added.
## PR Checklist
- [x] Closes: #49573
- [x] Closes: #49574
- [x] **Communication:** Discussed the shared UTF-8 policy with a
PowerToys collaborator in this PR
- [x] **Tests:** Existing Keyboard Manager Engine tests pass; no new
tests are needed for project-only changes
- [x] **Localization:** No end-user-facing strings are changed
- [x] **Dev docs:** No documentation changes are required for project
configuration fixes
- [x] **New binaries:** No new binaries are added
- [x] **Documentation updated:** No user documentation changes are
required
## Detailed Description of the Pull Request / Additional comments
`Directory.Build.props` imports `Cpp.Build.props` for C++ projects.
Defining `/utf-8 %(AdditionalOptions)` in its shared `ClCompile`
settings makes source decoding deterministic across the native codebase
and prevents future BOM-less UTF-8 source files from reintroducing the
same locale-dependent failure. `/utf-8` explicitly sets both the source
and execution character sets instead of suppressing C4819 or replacing
valid Unicode text.
`$(SolutionDir)` is only reliable when MSBuild is invoked through a
solution. The repository's local build script builds `.vcxproj` files
directly from their project directories, where `$(RepoRoot)` is the
stable repository root property. The wrapper output now follows the
existing `$(RepoRoot)$(Platform)\$(Configuration)\WinUI3Apps\` pattern
used by other native WinUI dependencies.
## Validation Steps Performed
All successful builds used the repository build scripts with `-Platform
x64 -Configuration Debug`.
- Ran `tools/build/build-essentials.cmd`: solution restore, Runner, and
Settings all succeeded with empty errors logs.
- Built `FancyZonesLib` successfully after it had failed with a
resource-related CL exit during a full parallel build.
- Built `WorkspacesModuleInterface` successfully, validating that
existing UTF-16 BOM headers remain compatible with the shared option.
- Built `ZoomItBreak` and `ZoomIt` successfully.
- Built `KeyboardManagerEngineTest` successfully.
- Built `KeyboardManagerEditor` and `KeyboardManagerEditorUI`
successfully after the documented essentials prerequisite.
- Confirmed the successful native build logs contain `/utf-8` compiler
invocations and all corresponding `build.debug.x64.errors.log` files are
empty.
- Ran `vstest.console.exe` against the Keyboard Manager Engine test
assembly: 103/103 passed.
- Confirmed `PowerToys.KeyboardManagerEditorLibraryWrapper.dll` is
emitted to `x64/Debug/WinUI3Apps`.
- Confirmed `KeyboardManager.Engine.UnitTests.dll` is emitted to
`x64/Debug/tests/KeyboardManagerEngine`.
- Previously manually verified the x64 Debug PowerToys build can open
Keyboard Manager Editor without 0x8007007E.
A full `PowerToys.slnx` x64 Debug build was attempted twice. The first
attempt exhausted the remaining 62 MB of disk space. After clearing
52.46 GB of ignored build outputs, the second attempt still exceeded the
machine's temporary disk/commit limits (`CL.exe` exit `0xC000012D` and
an out-of-space cppwinrt write). Before that resource failure, the log
contained 4,642 `/utf-8` command entries and no character-set
diagnostics. The full configuration matrix is left to PR CI rather than
bypassing normal build settings locally.
---------
Co-authored-by: Yu Leng (from Dev Box) <yuleng@microsoft.com>
2026-08-05 04:10:36 -04:00
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
2023-10-19 15:04:09 +01:00
<!-- TODO: _SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING for compatibility with VS 17.8. Check if we can remove. -->
[UITests] New framework around WinApp CLI, no WinAppDriver or Selenium. (#48467)
# Add winappcli-based UI test harness (no WinAppDriver / Selenium)
## Summary
Introduces a new UI test harness — `Microsoft.PowerToys.UITest.Next` —
that drives PowerToys
modules through Microsoft's
[winappcli](https://github.com/microsoft/WinAppCli) (UI Automation
CLI) instead of WinAppDriver + Selenium. Engine is a single executable
shelled out from
C#; no third-party NuGet packages, no driver process, no Appium server.
Adds two real consumers:
a full ColorPicker end-to-end scenario and a Settings shell navigation
smoke test.
This is opt-in and additive — the existing `UITestAutomation` library
and the
WinAppDriver-based test projects are untouched. Both can coexist while
we evaluate the new
harness.
Inspired in part by
[#48414](https://github.com/microsoft/PowerToys/pull/48414), which lands
the same architectural bet (winappcli, AutomationId selectors, no
WinAppDriver) at a smaller
scope. This PR generalizes it into a reusable library.
## Why
WinAppDriver + Selenium is a legacy pre-agentic solution that is no
longer actively maintained. It's unreliable, heavyweight, and slow. To
achieve 100% UI test coverage, we should leverage modern, reliable
solutions, and WinApp CLI is a strong candidate.
## What's in this PR
### Harness library —
[`src/common/UITestAutomation.Next/`](src/common/UITestAutomation.Next/)
| File | Purpose |
|---|---|
| [`WinappCli.cs`](src/common/UITestAutomation.Next/WinappCli.cs) |
Process wrapper around `winapp.exe`. `Invoke` / `InvokeAssertSuccess` /
`InvokeJson` / `IsAvailable` / `TryResolveExecutable`. `Result` carries
the args and emits `DescribeFailure()` like `winapp ui invoke X -w 12345
-> exit 1; stderr: ...` |
| [`Session.cs`](src/common/UITestAutomation.Next/Session.cs) | Test
session, scoped by either HWND (`-w`) or process (`-a`) via
`TargetScope`. `Find<T>` / `FindAll<T>` / `Inspect` / `Screenshot` /
`SendKeys`. `Session.FromProcess(...)` factory for the
single-window-per-process case |
|
[`SessionHelper.cs`](src/common/UITestAutomation.Next/SessionHelper.cs)
| Owns the launch + window-readiness flow. Static `EnsureRunning(scope,
timeout)` returns whether the call had to launch (so cleanup only kills
what we started). Uses `UseShellExecute=true` so child handles don't
keep MSTest hanging |
| [`UITestBase.cs`](src/common/UITestAutomation.Next/UITestBase.cs) |
MSTest base class. Pre-flights `WinappCli.IsAvailable()` once per
process and fails fast with the install hint if `winapp.exe` isn't on
PATH |
| [`Element/*.cs`](src/common/UITestAutomation.Next/Element/) |
`Element`, `Button`, `ToggleSwitch`, `TextBox`, `NavigationViewItem`,
`Window`. `Click` / `MouseClick` / `Focus` / `GetProperty` / `GetValue`
/ `HelpText` / `WaitForProperty` / `WaitForGone` plus coords
(`X`/`Y`/`Width`/`Height`) |
| [`By.cs`](src/common/UITestAutomation.Next/By.cs) | `By.Name` /
`By.AccessibilityId` / `By.Id` / `By.Slug` |
| [`Windows.cs`](src/common/UITestAutomation.Next/Windows.cs) |
`WindowsFinder.ListAll` / `ListByApp` / `WaitForWindowByApp` /
`WaitForWindowByProcess`. Notes the winappcli bug where unfiltered
`list-windows` drops untitled windows |
|
[`WindowControl.cs`](src/common/UITestAutomation.Next/WindowControl.cs)
| Tolerant Win32 helpers — `TryCloseByApp` / `TryFocusByApp` /
`SafeCloseAndFocus` / `TryKillProcess` — for `finally` blocks |
|
[`KeyboardHelper.cs`](src/common/UITestAutomation.Next/KeyboardHelper.cs)
| Hybrid `keybd_event` + `SendKeys.SendWait` chord sender — required for
global PowerToys hotkeys |
| [`MouseHelper.cs`](src/common/UITestAutomation.Next/MouseHelper.cs) |
`MoveTo` / `LeftClick` / `RightClick` / `LeftClickAt` Win32 wrappers |
|
[`ClipboardHelper.cs`](src/common/UITestAutomation.Next/ClipboardHelper.cs)
| STA-thread `Clipboard` access with `WaitForText` |
|
[`ModuleConfigData.cs`](src/common/UITestAutomation.Next/ModuleConfigData.cs)
| `PowerToysModule` enum + path/process-name resolution |
### Tests
**[`src/modules/colorPicker/ColorPicker.UITests/`](src/modules/colorPicker/ColorPicker.UITests/)**
— replaces the previous empty `UITest-ColorPicker` stub. One test,
[`ColorPickerEndToEndTests.NavigateReadShortcutActivateAndCapture`](src/modules/colorPicker/ColorPicker.UITests/ColorPickerEndToEndTests.cs),
drives the full E2E:
1. Navigate to the Color Picker page via the dashboard utilities stack
2. Toggle the module OFF, verify `PowerToys.ColorPickerUI` exits; toggle
ON, verify it respawns
3. Read the activation shortcut from the page's `ShortcutControl`
(`EditButton.HelpText`)
4. Clear clipboard, park cursor, send the chord
5. Wait for the picker overlay window
6. Read the displayed HEX from a hidden XAML automation peer (see below)
7. Left-click to capture; assert the clipboard value matches the peer's
HEX
8. Wait for the editor window and assert the captured color appears in
its tree
**[`src/settings-ui/Settings.UITests/`](src/settings-ui/Settings.UITests/)**
— `SettingsNavigationSmokeTests.NavigationItem_NavigatesWithoutCrashing`
is one `[TestMethod]` parameterized with `[DynamicData]`, producing 31
discrete results — one per `NavigationViewItem` in
[`ShellPage.xaml`](src/settings-ui/Settings.UI/SettingsXAML/Views/ShellPage.xaml).
For each item: navigate, settle 250ms, assert `PowerToys.Settings` is
still alive. Catches FailFast regressions in
`ShellViewModel.Frame_NavigationFailed` that pure-logic unit tests can't
reach (the failure path needs a `NavigationFailedEventArgs` which is a
sealed WinRT projection).
### Product change
**[`src/modules/colorPicker/ColorPickerUI/Views/MainView.xaml`](src/modules/colorPicker/ColorPickerUI/Views/MainView.xaml)**
— adds a hidden `TextBlock` automation peer:
```xml
<TextBlock
x:Name="ColorHexAutomationPeer"
AutomationProperties.AutomationId="ColorHexAutomationPeer"
IsHitTestVisible="False"
Opacity="0"
Text="{Binding ColorText}" />
```
The visible `ColorTextBlock` has `AutomationProperties.Name="{Binding
ColorName}"`, which masks the HEX value in the UIA tree (you see "White"
instead of `#FFFFFF`). This zero-impact peer mirrors `ColorText` so
tests can read the actually-displayed HEX. `Opacity=0` +
`IsHitTestVisible=False` keep it out of the visual layout and out of
accessibility focus.
### Project wiring
- [`PowerToys.slnx`](PowerToys.slnx) — registers `UITestAutomation.Next`
under `/common/`, `ColorPicker.UITests` under
`/modules/colorpicker/Tests/`, and `Settings.UITests` under
`/settings-ui/Tests/`. Original `UITest-ColorPicker` stub csproj
removed.
-
[`.github/actions/spell-check/expect.txt`](.github/actions/spell-check/expect.txt)
— adds `winapp` / `winappcli`.
### Not in this PR
- No pipeline changes. `winapp.exe` is expected to be pre-staged on the
test agent image. If it's missing, `UITestBase` fails the first test
with the install hint (`winget install Microsoft.winappcli`) rather than
producing 30 opaque per-test errors.
- No changes to the legacy `UITestAutomation` library or any of the
existing `*.UITests` projects.
## Validation
- All three projects build clean on `x64|Debug` (empty
`build.<config>.<plat>.errors.log`):
- `src/common/UITestAutomation.Next/`
- `src/modules/colorPicker/ColorPicker.UITests/`
- `src/settings-ui/Settings.UITests/`
- Both tests run in Test Explorer / `dotnet test` via
Microsoft.Testing.Platform (already enabled repo-wide in
`Directory.Build.props`).
- Local runs: ColorPicker E2E green; Settings smoke green across all 31
nav items.
- `winapp 0.3.2` from `winget install Microsoft.winappcli`.
## Notes for reviewers
- **`UseShellExecute = true`** in `SessionHelper.EnsureRunning` is
intentional — `false` makes child processes inherit the test host's
stdin/stdout/stderr handles, which keeps MTP/Test Explorer marking the
run as "in progress" until the spawned PowerToys exits.
- **Process-scope (`-a`) targeting** in the Settings smoke test handles
single-instance handoff: the EXE you launch may exit with code 0
immediately after signalling an existing owner, so the alive check uses
`Process.GetProcessesByName` rather than the launcher PID.
- **AutomationId-only selectors** in the Settings smoke list keep the
test localization-independent. Parent groups have
`SelectsOnInvoked="False"` and only expand on click — `Element.Click`
tries `InvokePattern → TogglePattern → SelectionItemPattern →
ExpandCollapsePattern` so the same call works for both leaves and
groups.
- **Untitled-window discovery**: filtered `winapp ui list-windows -a
<name>` returns windows that the unfiltered call drops (e.g. ColorPicker
editor). `WindowsFinder.ListByApp` uses the filtered form. Reported
upstream.
## Before Merge
- Add the `winappcli` install step to the UI-test pipeline.
2026-07-07 22:58:08 -07:00
<!-- TODO: _SILENCE_EXPERIMENTAL_COROUTINE_DEPRECATION_WARNINGS for VS 2026 (MSVC 14.51+). The STL turned
<experimental/coroutine> into a hard error (STL1011), and C++/WinRT's base.h still falls back to it when
__cpp_lib_coroutine isn't defined at include time. Remove once C++/WinRT no longer references the experimental header. -->
<PreprocessorDefinitions>_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;_SILENCE_EXPERIMENTAL_COROUTINE_DEPRECATION_WARNINGS;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
2023-10-04 09:40:01 -05:00
<!-- CLR + CFG are not compatible >:{ -->
<ControlFlowGuard Condition="'$(CLRSupport)' == ''">Guard</ControlFlowGuard>
<DebugInformationFormat Condition="'%(ControlFlowGuard)' == 'Guard'">ProgramDatabase</DebugInformationFormat>
2023-11-22 09:52:32 -08:00
<SDLCheck>true</SDLCheck>
2020-12-14 15:20:45 +03:00
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
2021-07-12 13:35:57 +03:00
</Link>
2020-12-21 18:51:48 +03:00
<Lib>
<TreatLibWarningAsErrors>true</TreatLibWarningAsErrors>
2021-07-12 13:35:57 +03:00
</Lib>
2020-12-14 15:20:45 +03:00
</ItemDefinitionGroup>
<!-- C++ source compile-specific things for Debug/Release configurations -->
2022-04-19 18:24:58 -04:00
<ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
2020-12-14 15:20:45 +03:00
<ClCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Optimization>Disabled</Optimization>
2025-11-12 10:39:21 +08:00
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
2020-12-14 15:20:45 +03:00
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
2021-07-12 13:35:57 +03:00
</Link>
2020-12-14 15:20:45 +03:00
</ItemDefinitionGroup>
2022-04-19 18:24:58 -04:00
<ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
2020-12-14 15:20:45 +03:00
<ClCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Optimization>MaxSpeed</Optimization>
2025-11-12 10:39:21 +08:00
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
2020-12-14 15:20:45 +03:00
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
2021-07-12 13:35:57 +03:00
</ClCompile>
2020-12-14 15:20:45 +03:00
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
2021-07-12 13:35:57 +03:00
</Link>
2020-12-14 15:20:45 +03:00
</ItemDefinitionGroup>
2024-09-12 09:30:44 -07:00
<!-- Global props OverrideWindowsTargetPlatformVersion-->
<PropertyGroup Label="Globals">
2025-06-18 01:34:26 -07:00
<WindowsTargetPlatformVersion>10.0.26100.0</WindowsTargetPlatformVersion>
<TargetPlatformVersion>10.0.26100.0</TargetPlatformVersion>
2023-07-20 00:12:46 +01:00
<WindowsTargetPlatformMinVersion>10.0.19041.0</WindowsTargetPlatformMinVersion>
2020-12-14 15:20:45 +03:00
</PropertyGroup>
<!-- Props that are constant for both Debug and Release configurations -->
<PropertyGroup Label="Configuration">
2024-09-12 09:30:44 -07:00
<PlatformToolset>v143</PlatformToolset>
[Dev][Build] VS 2026 Support (#44304)
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request
This PR updates the PowerToys solution to support **Visual Studio 2026
(PlatformToolset v145)**. It centralizes the build configuration,
updates the C++ language standards, and fixes an issue with a MouseJump
unit test that appears while using the VS 2026 supported build agent.
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist
- [ ] Closes: #xxx
- [x] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [x] **Tests:** Added/updated and all pass
- [ ] **Localization:** All end-user-facing strings can be localized
- [x] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places
- [ ] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [ ] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [ ] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [ ] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [ ] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: #xxx
<!-- Provide a more detailed description of the PR, other things fixed,
or any additional comments/features here -->
## Detailed Description of the Pull Request / Additional comments
**Build System & Configuration:**
- Updated `Cpp.Build.props` to use `v145` (VS 2026) as the default
`PlatformToolset`, with fall back to `v143` for VS 2022.
- Configured C++ Language Standard:
- `stdcpplatest` for production projects.
- Removed explicit `<PlatformToolset>` definitions from individual
project files (approx. 37 modules) to inherit correctly from the central
`Cpp.Build.props`.
**Code Refactoring & Fixes:**
- Updated `DrawingHelperTests.cs` in MouseJump Unit Test to ease the
pixel difference tolerance. This became an issue after switching to the
new VS2026 build agent.
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
- Validated successful compilation of the entire solution. Similar
updates have been made to the .NET 10 branch, but these are much cleaner
and will be merged into that branch once fully confirmed working.
---------
Co-authored-by: Kai Tao (from Dev Box) <kaitao@microsoft.com>
Co-authored-by: Gordon Lam (SH) <yeelam@microsoft.com>
2026-01-28 18:46:34 -05:00
<PlatformToolset Condition="'$(VisualStudioVersion)' == '18.0'">v145</PlatformToolset>
2020-12-14 15:20:45 +03:00
<CharacterSet>Unicode</CharacterSet>
2022-08-27 02:17:20 +03:00
<DesktopCompatible>true</DesktopCompatible>
2023-11-22 09:52:32 -08:00
<SpectreMitigation>Spectre</SpectreMitigation>
2020-12-14 15:20:45 +03:00
</PropertyGroup>
Migrate spdlog from submodule to vcpkg (#48039)
## Summary
Migrate `deps/spdlog` from a git submodule to **vcpkg manifest mode**
with an overlay port pinned to the **exact same commit**
(`gabime/spdlog@616866fc`). Replaces the polyfill shim added in #47910
with a proper port-level patch.
This is the follow-up to PR #47928, which I closed after @zadjii-msft /
@DHowett clarified that the intended direction was a single combined
"move to vcpkg **and** apply a patch file" (one change, not two stepping
stones).
## Guidance honored
Per @zadjii-msft (offline):
- ✅ Convert each submodule to vcpkg **one at a time** — this PR is
**spdlog only**. `deps/expected-lite` stays a submodule (separate PR
next).
- ✅ Atomic commit per dep (multiple commits on the branch for review
traceability; squash on merge gives the requested single commit).
- ✅ **Don't bump the version.** Only variable changed: submodule →
vcpkg. Same commit (`616866fc`, v1.8.5 + 38) the submodule pointed at.
Per @DHowett
([review](https://github.com/microsoft/PowerToys/pull/48039#pullrequestreview-4338835150)):
- ✅ No vcpkg submodule — vswhere-first detection via a Terminal-style
`steps-install-vcpkg.yml` template; three-tier `VcpkgRoot` fallback (env
var → VS-shipped → runtime clone pinned to manifest baseline).
## Design
- **Repo-root manifest**: `vcpkg.json` declares only `spdlog`, with
`builtin-baseline` pinned. `vcpkg-configuration.json` registers
`deps/vcpkg-overlays/` as overlay-ports.
- **Overlay port** `deps/vcpkg-overlays/spdlog/`: `vcpkg_from_github(REF
616866fc...)` with bundled fmt preserved (`-DSPDLOG_FMT_EXTERNAL=OFF`);
the MSVC 14.51 fix from #47910 carried as a proper vcpkg patch on
`include/spdlog/fmt/bundled/format.h`.
- **vcpkg integration is global** (set in `Cpp.Build.props`, imported
via `ForceImportBeforeCppProps` for every `.vcxproj`). An earlier
attempt to make vcpkg per-project-opt-in via `deps/spdlog.props` failed
because ~85 PowerToys `.vcxproj` files import `spdlog.props` AFTER
`Microsoft.Cpp.targets`, by which point `vcpkg.props`' `ClCompile` hook
is dead-on-arrival. The trade-off (every C++ project invokes `vcpkg
install` once at build time, ~0.5 s on cache hits, manifest declares
only spdlog so install set is fixed) is documented in the expanded
`Cpp.Build.props` comment.
- **`deps/spdlog.props`** is now a thin shim that only sets the
historical `SPDLOG_*` preprocessor defines for source-compat.
- **`Cpp.Build.targets`** is a new file imported via
`ForceImportAfterCppTargets` to load `vcpkg.targets` after
`Microsoft.Cpp.targets`. A fail-fast `<Target>` errors with a clear
message if `vcpkg.props` can't be found at the resolved `VcpkgRoot`.
- **Removes** `deps/spdlog-msvc-fix/` polyfill, in-tree wrapper
`src/logging/`, spdlog submodule, the single `<ProjectReference>` in
`logger.vcxproj`, plus 3 `.slnf` refs and 2 `.slnx` refs
(`PowerToys.slnx` + `installer/PowerToysSetup.slnx`), plus 3 hard-coded
`..\deps\spdlog\include` entries in `<AdditionalIncludeDirectories>`.
- **CI**: new reusable `.pipelines/v2/templates/steps-install-vcpkg.yml`
(vswhere-first, manifest-baseline-pinned fallback clone, respects
`useVSPreview`). Gated `Cache@2` for `%LOCALAPPDATA%\vcpkg\archives`
keyed on overlay-port contents. Same vcpkg detection added to
`tools\build\build-essentials.ps1` for local devs.
## Verification
Local build matrix (all 4 configs of `logger.vcxproj` and a
representative late-import consumer):
| Config | Result | Notes |
|--------|--------|-------|
| Release \| x64 | ✅ | vcpkg install ~21 s, `logger.lib` produced |
| Debug \| x64 | ✅ | **Validates patch fixes the actual MSVC 14.51 bug**
(`_ITERATOR_DEBUG_LEVEL > 0` → `_SECURE_SCL`) |
| Release \| ARM64 | ✅ | vcpkg cross-installs `arm64-windows-static`
spdlog in ~16 s |
| Debug \| ARM64 | ✅ | **Previously DISABLED for the in-tree spdlog**
(per `<Build Solution="Debug\|ARM64" Project="false" />` in
`PowerToysSetup.slnx`); this migration FIXES that latent gap |
| FancyZonesLib (Release \| x64) | ✅ | Late-import-pattern consumer;
previously broke in v2 |
Full PowerToys CI (x64 + arm64 + CmdPal SDK + all GitHub Actions checks)
green.
**Consumer audit**: 72 `.vcxproj` files reference `logger.vcxproj`; all
72 also import `deps/spdlog.props`. No transitive-link breakage.
## Out of scope (intentional)
- `deps/expected-lite` migration — next PR per "one-at-a-time" rule.
- Remote vcpkg binary cache (Azure Artifacts NuGet feed). Local pipeline
`Cache@2` works for now, but a remote feed survives across pipelines and
is the long-term answer. Happy to split this into a follow-up.
## Notes for review
- Patch in the overlay port is identical content to PR #47928's patch
but regenerated with LF line endings (vcpkg's `vcpkg_apply_patches` is
strict; no `--ignore-whitespace`).
- Once PowerToys eventually bumps spdlog past v1.14 (which ships fmt
10.2 and drops the affected code path), the overlay port can be deleted
and we can use upstream vcpkg's `spdlog` directly.
- Re. official-release pipelines and terrapin / less-restricted network
isolation: VS-shipped vcpkg is the primary path (no network); the
fallback clone is only exercised when VS doesn't ship vcpkg. Happy to
wire terrapin into the fallback as a follow-up if the official build
template needs it.
Closes the work tracked in #47928 (which was closed unmerged).
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Dustin L. Howett <dustin@howett.net>
2026-05-27 15:45:24 +08:00
<!--
vcpkg integration. Set globally and loaded before Microsoft.Cpp.props (via
ForceImportBeforeCppProps) so that vcpkg.props' ClCompile hook is in place
before the C++ targets run. VcpkgRoot is resolved via the same three-tier
fallback used by microsoft/terminal (env var → VS-shipped → deps/vcpkg).
-->
<PropertyGroup Label="vcpkg">
<VcpkgEnabled>true</VcpkgEnabled>
<VcpkgEnableManifest>true</VcpkgEnableManifest>
<VcpkgManifestEnabled>true</VcpkgManifestEnabled>
<VcpkgManifestRoot>$(MSBuildThisFileDirectory)</VcpkgManifestRoot>
<VcpkgOSTarget>windows</VcpkgOSTarget>
<VcpkgUseStatic>true</VcpkgUseStatic>
<!--
Force VcpkgConfiguration to follow $(Configuration). Without this,
vcpkg.props infers VcpkgConfiguration from $(UseDebugLibraries), which
Microsoft.Cpp.Default.props has already defaulted to 'false' by the
time vcpkg.props is imported here (the PowerToys-wide Debug override
below runs LATER). That would silently link the Release-built spdlog
into Debug consumers and trigger LNK2038 (MT/MTd, _ITERATOR_DEBUG_LEVEL).
-->
<VcpkgConfiguration>$(Configuration)</VcpkgConfiguration>
<!-- vcpkg validates triplets case-sensitively; PowerToys uses ARM64 capital-case. -->
<VcpkgPlatformTarget Condition="'$(Platform)' == 'ARM64'">arm64</VcpkgPlatformTarget>
<VcpkgApplocalDeps>false</VcpkgApplocalDeps>
<VcpkgInstalledDir>$(MSBuildThisFileDirectory)vcpkg_installed\$(Platform)\</VcpkgInstalledDir>
<VcpkgRoot Condition="'$(VcpkgRoot)' == ''">$(VCPKG_ROOT)</VcpkgRoot>
<VcpkgRoot Condition="'$(VcpkgRoot)' == '' and '$(VsInstallRoot)' != ''">$(VsInstallRoot)\VC\vcpkg</VcpkgRoot>
<VcpkgRoot Condition="'$(VcpkgRoot)' == '' or !Exists('$(VcpkgRoot)\vcpkg.exe')">$(MSBuildThisFileDirectory)deps\vcpkg</VcpkgRoot>
<CAExcludePath>$(CAExcludePath);$(VcpkgInstalledDir)</CAExcludePath>
<VCPkgLocalAppDataDisabled>true</VCPkgLocalAppDataDisabled>
</PropertyGroup>
<!-- Fail fast with an actionable message instead of opaque C1083 spdlog/spdlog.h errors. -->
<Target Name="PowerToysEnsureVcpkgAvailable"
BeforeTargets="PrepareForBuild"
Condition="'$(MSBuildProjectExtension)' == '.vcxproj' and '$(VcpkgEnabled)' == 'true' and !Exists('$(VcpkgRoot)\scripts\buildsystems\msbuild\vcpkg.props')">
<Error Text="PowerToys requires the 'vcpkg' Visual Studio component, but it was not found.%0A%0AOpen the Visual Studio Installer, click Modify on your VS install, search for 'vcpkg', enable 'C++ vcpkg package manager', and click Modify. (Visual Studio will also prompt you to install missing .vsconfig components when you open PowerToys.slnx.)%0A%0AIf you have vcpkg installed elsewhere, set the VCPKG_ROOT environment variable to its root before building.%0A%0ASearched: '$(VcpkgRoot)\scripts\buildsystems\msbuild\vcpkg.props'" />
</Target>
<Import Project="$(VcpkgRoot)\scripts\buildsystems\msbuild\vcpkg.props"
Condition="'$(MSBuildProjectExtension)' == '.vcxproj' and Exists('$(VcpkgRoot)\scripts\buildsystems\msbuild\vcpkg.props')" />
2020-12-14 15:20:45 +03:00
<!-- Debug/Release props -->
2025-12-16 10:46:39 +08:00
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
2021-07-12 13:35:57 +03:00
<UseDebugLibraries>true</UseDebugLibraries>
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
2025-12-16 10:46:39 +08:00
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
2021-07-12 13:35:57 +03:00
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
2020-12-14 15:20:45 +03:00
2022-12-15 18:40:29 -05:00
</Project>