mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-01-09 07:52:53 +08:00
<!-- 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 Adds a dedicated command-line interface (CLI) executable for Image Resizer (PowerToys.ImageResizerCLI.exe) ## Command `PowerToys.ImageResizerCLI.exe [options] [files...]` ## Options (High Level) | Option (aliases) | Description | |-----------------|-------------| | `--help` | Show help | | `--show-config` | Print current effective configuration | | `--destination`, `-d` | Output directory (optional) | | `--width`, `-w` | Width | | `--height`, `-h` | Height | | `--unit`, `-u` | Unit (Pixel / Percent / Inch / Centimeter) | | `--fit`, `-f` | Fit mode (Fill / Fit / Stretch) | | `--size`, `-s` | Preset size index (supports `0` for Custom) | | `--shrink-only` | Only shrink (do not enlarge) | | `--replace` | Replace original | | `--ignore-orientation` | Ignore EXIF orientation | | `--remove-metadata` | Strip metadata | | `--quality`, `-q` | JPEG quality (1–100) | | `--keep-date-modified` | Preserve source last-write time | | `--file-name` | Output filename format | ## Example usage ``` # Show help PowerToys.ImageResizerCLI.exe --help # Show current config PowerToys.ImageResizerCLI.exe --show-config # Resize with explicit dimensions PowerToys.ImageResizerCLI.exe --width 800 --height 600 .\image.png # Use preset size 0 (Custom) and output to a folder PowerToys.ImageResizerCLI.exe --size 0 -d "C:\Output" .\photo.png # Preserve source LastWriteTime PowerToys.ImageResizerCLI.exe --width 800 --height 600 --keep-date-modified -d "C:\Output" .\image.png ```  <!-- 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 - [x] **Tests:** Added/updated and all pass - [x] **Localization:** All end-user-facing strings can be localized - [x] **Dev docs:** Added/updated - [x] **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
3.1 KiB
3.1 KiB
CLI Conventions
This document describes the conventions for implementing command-line interfaces (CLI) in PowerToys modules.
Library
Use the System.CommandLine library for CLI argument parsing. This is already defined in Directory.Packages.props:
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
Add the reference to your project:
<PackageReference Include="System.CommandLine" />
Option Naming and Definition
- Use
--kebab-casefor long form (e.g.,--shrink-only). - Use single
-xfor short form (e.g.,-s,-w). - Define aliases as static readonly arrays:
["--silent", "-s"]. - Create options using
Option<T>with descriptive help text. - Add validators for options that require range or format checking.
RootCommand Setup
- Create a
RootCommandwith a brief description. - Add all options and arguments to the command.
Parsing
- Use
Parser(rootCommand).Parse(args)to parse CLI arguments. - Extract option values using
parseResult.GetValueForOption(). - Note: Use
Parserdirectly;RootCommand.Parse()may not be available with the pinned System.CommandLine version.
Parse/Validation Errors
- On parse/validation errors, print error messages and usage, then exit with non-zero code.
Examples
Reference implementations:
- Awake:
src/modules/Awake/Awake/Program.cs - ImageResizer:
src/modules/imageresizer/ui/Cli/
Help Output
- Provide a
PrintUsage()method for custom help formatting if needed.
Best Practices
- Consistency: Follow existing module patterns.
- Documentation: Always provide help text for each option.
- Validation: Validate input and provide clear error messages.
- Atomicity: Make one logical change per PR; avoid drive-by refactors.
- Build/Test Discipline: Build and test synchronously, one terminal per operation.
- Style: Follow repo analyzers (
.editorconfig, StyleCop) and formatting rules.
Logging Requirements
- Use
ManagedCommon.Loggerfor consistent logging. - Initialize logging early in
Main(). - Use dual output (console + log file) for errors and warnings to ensure visibility.
- Reference:
src/modules/imageresizer/ui/Cli/CliLogger.cs
Error Handling
Exit Codes
0: Success1: General error (parsing, validation, runtime)2: Invalid arguments (optional)
Exception Handling
- Always wrap
Main()in try-catch for unhandled exceptions. - Log exceptions before exiting with non-zero code.
- Display user-friendly error messages to stderr.
- Preserve detailed stack traces in log files only.
Testing Requirements
- Include tests for argument parsing, validation, and edge cases.
- Place CLI tests in module-specific test projects (e.g.,
src/modules/[module]/tests/*CliTests.cs).
Signing and Deployment
- CLI executables are signed automatically in CI/CD.
- New CLI tools: Add your executable and dll to
.pipelines/ESRPSigning_core.jsonin the signing list. - CLI executables are deployed alongside their parent module (e.g.,
C:\Program Files\PowerToys\modules\[ModuleName]\). - Use self-contained deployment (import
Common.SelfContained.props).