Files
PowerToys/tools/CliShim/CliShimManifest.props
moooyo ae416c045a Add native CLI shims for PowerToys command-line tools (#48631)
## Summary of the Pull Request

Adds a native C++ multi-call shim that exposes existing PowerToys CLIs
through `PATH`. The shims are installed under the PowerToys `bin`
subfolder and follow the `PowerToys.<ModuleName>.CLI.exe` naming
convention. The launcher preserves the raw argument tail, shares the
caller's console, and returns the target process exit code.

| PATH-visible command | Target executable |
| --- | --- |
| `PowerToys.FancyZones.CLI.exe` | `FancyZonesCLI.exe` |
| `PowerToys.ImageResizer.CLI.exe` |
`WinUI3Apps/PowerToys.ImageResizerCLI.exe` |
| `PowerToys.FileLocksmith.CLI.exe` | `FileLocksmithCLI.exe` |
| `PowerToys.PowerDisplay.CLI.exe` |
`WinUI3Apps/PowerToys.PowerDisplay.Cli.exe` |

proof of this work:
<img width="1044" height="294" alt="image"
src="https://github.com/user-attachments/assets/b659c552-5c08-4430-85c3-eba48f286eb0"
/>
<img width="1137" height="244" alt="image"
src="https://github.com/user-attachments/assets/5fed493f-dc30-428d-a618-bf612ccf3635"
/>

<img width="1727" height="868" alt="image"
src="https://github.com/user-attachments/assets/5c32fd2e-4a3a-4138-b968-fb5434eebec3"
/>


## PR Checklist

- [x] Closes: #48634
- [x] **Communication:** Discussed with core contributors in this PR
- [x] **Tests:** Added/updated and all pass
- [ ] **Localization:** CLI diagnostic messages are not localized
- [x] **Dev docs:** Updated CLI naming and installation conventions
- [x] **New binaries:** Added on the required places
  - [x] Signing JSON
  - [x] WiX installer entries
- [x] CI builds through `PowerToys.slnx`; no dedicated YML step is
required
  - [x] The existing release pipeline covers the solution and installer
- [x] **Documentation updated:** `doc/devdocs/cli-conventions.md`

## Detailed Description of the Pull Request / Additional comments

- Uses one native launcher binary for all commands and resolves the
target from the invoked shim filename.
- Installs PATH-visible shims under `PowerToys\bin`.
- Keeps the existing module CLI binaries and their deployment locations
unchanged.
- Rejects the previous unsuffixed and `*cli` command aliases.

## Validation Steps Performed

- Built `tools/CliShim.UnitTests/CliShim.UnitTests.vcxproj` in
`Release|x64`: 0 warnings, 0 errors.
- Ran `CliShim.UnitTests.dll` with `vstest.console.exe`: 5/5 tests
passed.
- Verified the CLI manifest, WiX command names, and `bin` installation
directory are synchronized.
- Ran `git diff --check`.

---------

Co-authored-by: Yu Leng <yuleng@microsoft.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: d11c4221-248f-44a9-85fb-7017ed43f4ce
2026-08-14 14:32:27 +08:00

48 lines
2.4 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) Microsoft Corporation. Licensed under the MIT license. -->
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- Single source of truth for the runtime mapping and installed command names. -->
<!-- RelativeTarget is resolved from the installed bin folder and must use '/' separators. -->
<ItemGroup>
<CliShim Include="PowerToys.FancyZones.CLI">
<RelativeTarget>../FancyZonesCLI.exe</RelativeTarget>
</CliShim>
<CliShim Include="PowerToys.ImageResizer.CLI">
<RelativeTarget>../WinUI3Apps/PowerToys.ImageResizerCLI.exe</RelativeTarget>
</CliShim>
<CliShim Include="PowerToys.FileLocksmith.CLI">
<RelativeTarget>../FileLocksmithCLI.exe</RelativeTarget>
</CliShim>
<CliShim Include="PowerToys.PowerDisplay.CLI">
<RelativeTarget>../WinUI3Apps/PowerToys.PowerDisplay.Cli.exe</RelativeTarget>
</CliShim>
</ItemGroup>
<!--
Emits the mapping above as a C++ initializer list. The shim and its unit tests both import
this file, so the tests always assert against the same table the shim was built from and a
new command cannot be added to one without the other picking it up.
-->
<Target Name="GenerateCliShimTargets"
BeforeTargets="ClCompile"
Inputs="$(MSBuildProjectFullPath);$(MSBuildThisFileFullPath)"
Outputs="$(IntDir)CliShimTargets.g.inc">
<!--
RelativeTarget is emitted into a C++ string literal verbatim, so a Windows-style separator
becomes an escape sequence: "..\WinUI3Apps\x.exe" fails to compile as C4129 (promoted to an
error by TreatWarningAsError), and "..\bin\x.exe" compiles into control characters instead.
Both diagnostics would point at the generated file rather than at this one, so reject the
separator here, where the fix is.
-->
<Error Condition="$([System.String]::Copy('%(CliShim.RelativeTarget)').Contains('\'))"
Text="CliShim RelativeTarget must use '/' separators: '%(CliShim.Identity)' is mapped to '%(CliShim.RelativeTarget)'." />
<ItemGroup>
<_CliShimTargetLine Include="{ L%22%(CliShim.Identity)%22, L%22%(CliShim.RelativeTarget)%22 }," />
</ItemGroup>
<MakeDir Directories="$(IntDir)" />
<WriteLinesToFile File="$(IntDir)CliShimTargets.g.inc"
Lines="@(_CliShimTargetLine)"
Overwrite="true" />
</Target>
</Project>