Repository navigation
[Peek] Add CLI support for previewing multiple files/folders. Fix multiple CLI issues - #49724
Merged
Boliang Zhang (LegendaryBlair) merged 2 commits intoOct 14, 2026
Conversation
…ssues around command line and runner PID validation.
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Folder display names and item-count visibility have unresolved edge-case defects, and the core CLI navigation path lacks automated coverage.
3 open findings
What changed in this PR
Adds robust Peek CLI support for multiple files and folders while distinguishing CLI launches from Runner launches.
Changes:
- Adds explicit Runner PID parsing and validation.
- Resolves CLI paths and supports mixed multi-item navigation.
- Generalizes item-count UI state and adds argument-classifier tests.
| File | Description |
|---|---|
src/modules/peek/peek/dllmain.cpp |
Passes the Runner PID using an explicit flag. |
src/modules/peek/Peek.UI/PeekXAML/MainWindow.xaml |
Binds title visibility to generalized item state. |
src/modules/peek/Peek.UI/PeekXAML/App.xaml.cs |
Classifies launches, validates PIDs, and resolves CLI paths. |
src/modules/peek/Peek.UI/NativeMethods.txt |
Normalizes the final entry formatting. |
src/modules/peek/Peek.UI/Models/SelectedItemsByPaths.cs |
Represents multi-path CLI selections. |
src/modules/peek/Peek.UI/MainWindowViewModel.cs |
Creates folder/file items and enables CLI navigation. |
src/modules/peek/Peek.Common/Helpers/LaunchArgumentsClassifier.cs |
Separates Runner and CLI argument forms. |
src/modules/peek/Peek.Common.UnitTests/LaunchArgumentsClassifierTests.cs |
Tests launch argument classification. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| /// navigation, from either Explorer or CLI. | ||
| /// Controls the visibility of the index/total counter in the title bar. | ||
| /// </summary> | ||
| public bool HasMultipleItems => (Items?.Count ?? 0) > 1; |
Comment on lines
+189
to
+192
| string name = Path.GetFileName(path); | ||
| items.Add(Directory.Exists(path) | ||
| ? new FolderItem(path, name, path) | ||
| : new FileItem(path, name)); |
Comment on lines
+189
to
+192
| string name = Path.GetFileName(path); | ||
| items.Add(Directory.Exists(path) | ||
| ? new FolderItem(path, name, path) | ||
| : new FileItem(path, name)); |
Boliang Zhang (LegendaryBlair)
approved these changes
Oct 14, 2026
Boliang Zhang (LegendaryBlair)
merged commit Oct 14, 2026
6d81089
into
microsoft:main
5 checks passed
Boliang Zhang (LegendaryBlair)
pushed a commit
that referenced
this pull request
Oct 15, 2026
…tiple CLI issues (#49724) <!-- 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 Previously, only one file could be previewed via the CLI. This adds support for multiple files, adds the ability to preview folders, and fixes a number of related issues with the CLI parameter parsing and validation code. <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [x] Closes: #49667 - [x] Closes: #49666 - [x] Closes: #49665 - [x] Closes: #49664 - [ ] **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 - [ ] **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 ### 1. Relative paths were not expanded into full paths Submitting relative paths via the CLI passed file validation (the file was recognised as existing), but when passed to Shell APIs for opening, a full path is required, resulting in Peek showing an error message. This is fixed in the new `InitializeFromCliPaths()` method which validates the path arguments and expands out the valid ones into full paths. ### 2. Only a single file was supported The previous CLI code ```csharp _selectedItem = new SelectedItemByPath(filePath); ``` meant that only 1 file was ever supported. Multiple files and/or folders were not. To support multiple files via the command line this PR: 1. Introduces a `SelectedItemsByPaths` class (notice the plurals), which inherits from `SelectedItem` and returns `true` from `Matches()` if the passed in path matches any of the paths passed in via the command line. 2. Updates the `Items` field in the `MainWindowViewModel` from `NeighboringItems` to a more generic `IReadOnlyList<IFileSystemItem>`. `NeighboringItems` is closely tied to the Explorer Shell API query path and should not have been exposed directly to the model and front-end. 3. Adds a `HasMultipleItems` property, replacing the `NeighboringItemsQuery.IsMultipleFilesActivation`, which controls whether the title bar shows the number of items and the current item number. This is similar to 2., where `NeighboringItems` and related types should not be part of the front-end. Screenshot showing current item number and total items in title bar: <img width="671" height="731" alt="image" src="https://github.com/user-attachments/assets/d4d724fc-728e-40d4-92cc-3a70f40f10f9" /> Folders are supported by this code in the new `InitializeFromCliPaths()`, which creates `FileItem` or `FolderItem` instances: ```csharp foreach (var path in paths) { string name = Path.GetFileName(path); items.Add(Directory.Exists(path) ? new FolderItem(path, name, path) : new FileItem(path, name)); } ``` Folder view from running `PowerToys.Peek.UI.exe .` (i.e. current folder): <img width="756" height="575" alt="image" src="https://github.com/user-attachments/assets/d834c12d-1e3e-423f-ad5b-0d2f93e55510" /> ### 3. Startup and validation fixes and increased robustness 1. **Added `--runner-pid` as a required parameter when supplying the Runner's process ID** This fixes the issue where the last argument would always be interpreted as the Runner's process ID if it was numeric. With the addition of folder previews via the CLI, this was necessary, otherwise folders with numeric names could not be previewed if they were listed as the last argument. 2. **Validated Runner PID** The numeric PID argument was always assumed to be correct previously. Providing an incorrect value manually would result in Peek opening, but it would not be linked to the Runner and could only be closed via a Task Manager kill. This PR validates that the PID is a running process and the linked exe is called "PowerToys.exe". 3. **Refactored startup code** A new `LaunchArgumentsClassifier` class determines whether Peek is being opened via the Runner or the CLI, with new `TryHandleRunnerLaunch()` and `TryHandleCliLaunch()` methods validating and preparing the items for navigation. ### 4. Other changes The more generic navigation of `IFileSystemItem`s means that the CLI does not have to be treated as a special case in the MainWindowViewModel, so `_isFromCli` has been removed. <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed 1. New unit tests for the `LaunchArgumentsClassifier` code 2. All new and existing unit tests pass: <img width="391" height="137" alt="image" src="https://github.com/user-attachments/assets/3b6a3148-9043-42b5-a2d8-69feaa6aed32" /> 3. Manual tests: - Open Peek via Explorer selection of 1 file, 1 folder, and multiple files and folder(s) mix - Open Peek via CLI with 1 file, 1 folder, and multiple files and folder(s) mix - Test navigation for all above combinations - Confirm Peek process closes on CLI validation error - Confirm Peek process closes when opened via the CLI when user exits the application normally - Confirm file delete still works, independent of how Peek was opened (cherry picked from commit 6d81089) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Summary of the Pull Request
Previously, only one file could be previewed via the CLI. This adds support for multiple files, adds the ability to preview folders, and fixes a number of related issues with the CLI parameter parsing and validation code.
PR Checklist
Detailed Description of the Pull Request / Additional comments
1. Relative paths were not expanded into full paths
Submitting relative paths via the CLI passed file validation (the file was recognised as existing), but when passed to Shell APIs for opening, a full path is required, resulting in Peek showing an error message. This is fixed in the new
InitializeFromCliPaths()method which validates the path arguments and expands out the valid ones into full paths.2. Only a single file was supported
The previous CLI code
meant that only 1 file was ever supported. Multiple files and/or folders were not.
To support multiple files via the command line this PR:
SelectedItemsByPathsclass (notice the plurals), which inherits fromSelectedItemand returnstruefromMatches()if the passed in path matches any of the paths passed in via the command line.Itemsfield in theMainWindowViewModelfromNeighboringItemsto a more genericIReadOnlyList<IFileSystemItem>.NeighboringItemsis closely tied to the Explorer Shell API query path and should not have been exposed directly to the model and front-end.HasMultipleItemsproperty, replacing theNeighboringItemsQuery.IsMultipleFilesActivation, which controls whether the title bar shows the number of items and the current item number. This is similar to 2., whereNeighboringItemsand related types should not be part of the front-end.Screenshot showing current item number and total items in title bar:
Folders are supported by this code in the new
InitializeFromCliPaths(), which createsFileItemorFolderIteminstances:Folder view from running
PowerToys.Peek.UI.exe .(i.e. current folder):3. Startup and validation fixes and increased robustness
Added
--runner-pidas a required parameter when supplying the Runner's process IDThis fixes the issue where the last argument would always be interpreted as the Runner's process ID if it was numeric. With the addition of folder previews via the CLI, this was necessary, otherwise folders with numeric names could not be previewed if they were listed as the last argument.
Validated Runner PID
The numeric PID argument was always assumed to be correct previously. Providing an incorrect value manually would result in Peek opening, but it would not be linked to the Runner and could only be closed via a Task Manager kill. This PR validates that the PID is a running process and the linked exe is called "PowerToys.exe".
Refactored startup code
A new
LaunchArgumentsClassifierclass determines whether Peek is being opened via the Runner or the CLI, with newTryHandleRunnerLaunch()andTryHandleCliLaunch()methods validating and preparing the items for navigation.4. Other changes
The more generic navigation of
IFileSystemItems means that the CLI does not have to be treated as a special case in the MainWindowViewModel, so_isFromClihas been removed.Validation Steps Performed
LaunchArgumentsClassifiercode