Josh Soref bf16e10baf
Some checks failed
Spell checking / Check Spelling (push) Has been cancelled
Spell checking / Report (Push) (push) Has been cancelled
Spell checking / Report (PR) (push) Has been cancelled
Spell checking / Update PR (push) Has been cancelled
Updates for check-spelling v0.0.25 (#40386)
## Summary of the Pull Request

- #39572 updated check-spelling but ignored:
   > 🐣 Breaking Changes
[Code Scanning action requires a Code Scanning
Ruleset](https://github.com/check-spelling/check-spelling/wiki/Breaking-Change:-Code-Scanning-action-requires-a-Code-Scanning-Ruleset)
If you use SARIF reporting, then instead of the workflow yielding an 
when it fails, it will rely on [github-advanced-security
🤖](https://github.com/apps/github-advanced-security) to report the
failure. You will need to adjust your checks for PRs.

This means that check-spelling hasn't been properly doing its job 😦.

I'm sorry, I should have pushed a thing to this repo earlier,...

Anyway, as with most refreshes, this comes with a number of fixes, some
are fixes for typos that snuck in before the 0.0.25 upgrade, some are
for things that snuck in after, some are based on new rules in
spell-check-this, and some are hand written patterns based on running
through this repository a few times.

About the 🐣 **breaking change**: someone needs to create a ruleset for
this repository (see [Code Scanning action requires a Code Scanning
Ruleset: Sample ruleset

](https://github.com/check-spelling/check-spelling/wiki/Breaking-Change:-Code-Scanning-action-requires-a-Code-Scanning-Ruleset#sample-ruleset)).

The alternative to adding a ruleset is to change the condition to not
use sarif for this repository. In general, I think the github
integration from sarif is prettier/more helpful, so I think that it's
the better choice.

You can see an example of it working in:
- https://github.com/check-spelling-sandbox/PowerToys/pull/23

---------

Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com>
Co-authored-by: Mike Griese <migrie@microsoft.com>
Co-authored-by: Dustin L. Howett <dustin@howett.net>
2025-07-08 17:16:52 -05:00

8.4 KiB

Window Walker plugin

The window walker plugin matches the user entered query with the open windows on the system. The user can switch to the found windows, close them or kill their process.

Image of Window Walker plugin

Remarks

UWP Apps

  • The process of an UWP app can't be detected correctly for windows that are minimized while searching. At this time they are assigned to the generic process ApplicationFrameHost.exe. If the user searches for such a window while it is not minimized, then the process gets assigned correctly/updated.

Killing processes

  • Killing the Explorer process is only allowed, if each folder window is running in its own process. (See section File Explorer setting below.)
  • You can only kill elevated processes, if you have admin permissions (UAC).
  • If you kill the process of an UWP app window, you kill all instances of the app. All windows are assigned to the same process.
  • Windows of UWP apps don't know their process, until they are searched in non-minimized state.

File Explorer setting

  • To kill the Process of an Explorer window, each window has to run in a separate process. Otherwise, the process is the same one as the shell process and killing the shell process will crash the shell (Windows ui).
  • To enable this behavior the setting Launch folder windows in a separate process under Folder Options > View has to be enabled.
  • From PowerToys Run you can open the Folder options dialog by clicking the information message in the search results. The information message is only shown when searching with action keyword for explorer windows and can be hidden in the plugin settings.
  • Note: The folder option/process is evaluated in real time. After changing the setting it is enough to search again for the windows.

Folder options for Window Walker

Optional plugin settings

  • The optional plugin settings are implemented via the ISettingProvider interface from Wox.Plugin project.
  • All available settings for the plugin are defined in the WindowWalkerSettings class of the plugin. The settings can be accessed everywhere in the plugin code via the static class instance WindowWalkerSettings.Instance.
  • We have the following settings that the user can configure to change the behavior of the plugin:
    Key Default value Name/Description
    ResultsFromVisibleDesktopOnly false Show only results from visible desktop
    SubtitleShowPid false Show process id in subtitle
    SubtitleShowDesktopName true Show desktop name in subtitle (If two or more desktops exist)
    ConfirmKillProcess true Request confirmation when killing a process
    KillProcessTree false Kill process and its child processes
    OpenAfterKillAndClose false Stay open after closing windows and killing processes (Not working with kill process confirmation)
    HideKillProcessOnElevatedProcesses false Hide "kill process" button if additional permissions required
    HideExplorerSettingInfo false Hide Explorer process information

Technical details

OpenWindows.cs

  • The window walker plugin uses the EnumWindows function to enumerate all the open windows in the OpenWindows.cs class.

SearchController.cs

  • The SearchController encapsulates the functions needed to search and find matches.
  • It is responsible for updating the search text and performing a fuzzy search on all the open windows.

Window.cs

  • The Window class represents a specific window and has functions to get the name of the window, the state of the window (whether it is visible or not), the SwitchToWindow function which switches the desktop focus to the selected window and the CloseThisWindow function which closes the window. The switchToWindow action is performed when the user clicks on a window walker plugin result.
  • The Window class holds a static cache with the process information of all windows we know so far and each window instance has a property which holds its process information (name, file, ...). The process data in the cache and the window property are of the type WindowProcess.
  • To get the desktop information for a window, we use the common VirtualDesktopHelper in Wox.Plugin project. The instance of VirtualDesktopHelper is cached in the Main class of the plugin at runtime. The desktop information is stored in a property of the type VDesktop.

WindowProcess.cs

  • The WindowProcess class represents a specific process for a window.
  • It contains static methods to query process information from the system and instance methods/properties to hold/retrieve the process information we want to know about a window's process.
  • Additionally, it contains the method KillThisProcess to kill the process. (If the user has not enough permissions to kill a process they are requested via UAC.)

ResultHelper.cs

  • The ResultHelper class contains the code to create the list with all results for PT Run based on the data returned from SearchController class.
  • There is a special result that is added if the folder windows doesn't run in separate processes and the user searches for Explorer windows using the action keyword.
    • This result informs the user that there is a setting that must be enabled to be able to kill Explorer processes.
    • The result can be disabled in plugin options. When it is clicked it opens the folder options.

ContextMenuHelper.cs

WindowWalkerSettings.cs

  • The WindowWalkerSettings class provides access to all optional plugin settings.
  • The class has a static property called Instance that holds an instance of the class itself. This allows us to access the settings from everywhere in the plugin code without having additional parameters in our methods.

Score

The window walker plugin uses FuzzyMatching to get the matching indices and calculates the score by creating a 2 dimensional array of the window and the query text.

Unit Tests

We have a Unit Test project that executes various test to ensure that the plugin works as expected.

PluginSettingsTests.cs

  • The PluginSettingsTests.cs class contains tests to validate that all settings exist and that they have the correct default values.