chore: import upstream snapshot with attribution
Spell checking / Check Spelling (push) Has been cancelled
Spell checking / Update PR (push) Has been cancelled
Publish Dev Docs Website / build (push) Failing after 1s
Publish Dev Docs Website / deploy (push) Has been skipped
Spell checking / Report (Push) (push) Has been cancelled
Spell checking / Report (PR) (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 12:16:02 +08:00
commit 79031da543
8235 changed files with 1365916 additions and 0 deletions
@@ -0,0 +1,64 @@
# Calculator Plugin
The Calculator plugin as the name suggests is used to perform calculations on the user entered query.
![Image of Calculator plugin](/doc/images/launcher/plugins/calculator.png)
## Optional plugin settings
* We have the following settings that the user can configure to change the behavior of the plugin:
| Key | Default value | Name | Description |
|--------------|-----------|------------|------------|
| `InputUseEnglishFormat` | `false` | Use English (United States) number format for input | Ignores your system setting and expects numbers in the format '1,000.50' |
| `OutputUseEnglishFormat` | `false` | Use English (United States) number format for output | Ignores your system setting and returns numbers in the format '1000.50' |
* The optional plugin settings are implemented via the [`ISettingProvider`](/src/modules/launcher/Wox.Plugin/ISettingProvider.cs) interface from `Wox.Plugin` project. All available settings for the plugin are defined in the [`Main`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Main.cs) class of the plugin.
## Technical details
### [`BracketHelper`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/BracketHelper.cs)
- This helper validates the bracket usage in the input string.
### [`CalculateHelper`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/CalculateHelper.cs)
- The [`CalculateHelper.cs`](src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/CalculateHelper.cs) class checks to see if the user entered query is a valid input to the calculator and only if the input is valid does it perform the operation.
- It does so by matching the user query to a valid regex.
- This class also handles some human multiplication expression like `2(1+2)` and `(2+3)(3+4)` in order to be computed by `Mages` lib.
- It does so by matching some regex and inserting `'*'` where appropriate, e.g: `2(1+2) -> 2 * (1+2)`
- It takes into account the combination of numbers (`num`), constants (`const`), functions (`func`) and expressions in parentheses (`(exp)`).
- The blank spaces between them are also considered.
- Some combinations were not handled as they are not common such as `'const num'` or `'func const'`
### [`CalculateEngine`](src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/CalculateEngine.cs)
- The main computation is done in the [`CalculateEngine.cs`](src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/CalculateEngine.cs) file using the `Mages` library.
```csharp
var result = CalculateEngine.Interpret(query.Search, CultureInfo.CurrentUICulture);
```
### [`CalculateResult`](src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/CalculateResult.cs)
- The class which encapsulates the result of the computation.
- It comprises of the `Result` and `RoundedResult` properties.
### [`ErrorHandler`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/ErrorHandler.cs)
- The class which encapsulates the code to log errors and format the user message.
- It returns an error result if the user searches with the activation command. This error result is shown to the user.
### Score
The score of each result from the calculator plugin is `300`.
## [Unit Tests](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator.UnitTests)
We have a [Unit Test project](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator.UnitTests) that executes various test to ensure that the plugin works as expected.
### [`BracketHelperTests`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator.UnitTests/BracketHelperTests.cs)
- The [`BracketHelperTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator.UnitTests/BracketHelperTests.cs) class contains tests to validate that brackets are handled correctly.
### [`ExtendedCalculatorParserTests`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator.UnitTests/ExtendedCalculatorParserTests.cs)
- The [`ExtendedCalculatorParserTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator.UnitTests/ExtendedCalculatorParserTests.cs) class contains tests to validate that the input is parsed correctly and the result is correct.
### [`NumberTranslatorTests`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator.UnitTests/NumberTranslatorTests.cs)
- The [`NumberTranslatorTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator.UnitTests/NumberTranslatorTests.cs) class contains tests to validate that each number is converted correctly based on the defined locals.
### [`QueryTests`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator.UnitTests/QueryTests.cs)
- The [`QueryTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator.UnitTests/QueryTests.cs) class contains tests to validate that the user gets the correct results when searching.
@@ -0,0 +1,31 @@
# Unit Converter Plugin
The Unit Convert plugin as the name suggests is used to perform unit conversion on the user entered query.
This plugin uses a package called [UnitsNet](https://github.com/angularsen/UnitsNet).
![Image of Calculator plugin](/doc/images/launcher/plugins/community.unitconverter.png)
### Currently Supported Units
- [Acceleration](https://github.com/angularsen/UnitsNet/blob/master/UnitsNet/GeneratedCode/Units/AccelerationUnit.g.cs)
- [Angle](https://github.com/angularsen/UnitsNet/blob/master/UnitsNet/GeneratedCode/Units/AngleUnit.g.cs)
- [Area](https://github.com/angularsen/UnitsNet/blob/master/UnitsNet/GeneratedCode/Units/AreaUnit.g.cs)
- [Duration](https://github.com/angularsen/UnitsNet/blob/master/UnitsNet/GeneratedCode/Units/DurationUnit.g.cs)
- [Energy](https://github.com/angularsen/UnitsNet/blob/master/UnitsNet/GeneratedCode/Units/EnergyUnit.g.cs)
- [Information](https://github.com/angularsen/UnitsNet/blob/master/UnitsNet/GeneratedCode/Units/InformationUnit.g.cs)
- [Length](https://github.com/angularsen/UnitsNet/blob/master/UnitsNet/GeneratedCode/Units/LengthUnit.g.cs)
- [Mass](https://github.com/angularsen/UnitsNet/blob/master/UnitsNet/GeneratedCode/Units/MassUnit.g.cs)
- [Power](https://github.com/angularsen/UnitsNet/blob/master/UnitsNet/GeneratedCode/Units/PowerUnit.g.cs)
- [Pressure](https://github.com/angularsen/UnitsNet/blob/master/UnitsNet/GeneratedCode/Units/PressureUnit.g.cs)
- [Speed](https://github.com/angularsen/UnitsNet/blob/master/UnitsNet/GeneratedCode/Units/SpeedUnit.g.cs)
- [Temperature](https://github.com/angularsen/UnitsNet/blob/master/UnitsNet/GeneratedCode/Units/TemperatureUnit.g.cs)
- [Volume](https://github.com/angularsen/UnitsNet/blob/master/UnitsNet/GeneratedCode/Units/VolumeUnit.g.cs)
These are the ones that are currently enabled (though UnitsNet supports many more). They are defined in [`UnitHandler.cs`](/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.UnitConverter/UnitHandler.cs).
### [`InputInterpreter`](/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.UnitConverter/InputInterpreter.cs)
- Class which manipulates user input such that it may be interpreted correctly and thus converted.
- Uses a regex amongst other things to do this.
### [`UnitHandler`](/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.UnitConverter/UnitHandler.cs)
- Class that does the actual conversion.
- Supports abbreviations in user input (single, double, or none).
@@ -0,0 +1,85 @@
# Value Generator Plugin
The Value Generator plugin is used to generate hashes for strings, to calculate base64 encodings, escape and encode URLs/URIs and to generate GUIDs of version 1, 3, 4, 5, and 7.
![Image of Value Generator plugin](/doc/images/launcher/plugin/community.valuegenerator.png)
### [`IComputeRequest`](/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/IComputeRequest.cs)
- Interface for a request for computation
- the `bool Compute()` method must populate the `IsSuccessful` and one of the `Result` and `ErrorMessage` fields
- The result of `string ResultToString()` will be used for the Result's title
- The `Description` field will be used for the Result's subtitle
### [`HashRequest`](/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Generators/Hashing/HashRequest.cs)
- Implements IComputeRequest
- Supports the hashing algorithms from System.Security.Cryptography:
- MD5
- SHA1
- SHA256
- SHA384
- SHA512
- If other algorithms are added to System.Security.Cryptography, they can be added to the `_algorithms` dictionary. [`InputParser.ParseInput()`](#inputparser) will need to return a `HashRequest` for the algorithm in the query
### [`Base64Request`](/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Generators/Base64/Base64Request.cs)
- Implements IComputeRequest
- `Compute()` will populate `Result` with the base64 encoding of the byte array passed in the constructor
### [`Base64DecodeRequest`](/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Generators/Base64/Base64DecodeRequest.cs)
- Implements IComputeRequest
- `Compute()` will populate `Result` with the decoded byte array of the base64 string passed in the constructor
### [`GUIDRequest`](/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Generators/GUID/GUIDRequest.cs)
- Implements IComputeRequest
- Uses the [`GUIDGenerator`](#guidgenerator) class to generate or compute the requested GUID
### [`GUIDGenerator`](/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Generators/GUID/GUIDGenerator.cs)
- Utility class for generating or calculating GUIDs
- Generating GUID versions 1, 4, and 7 is done using builtin APIs:
- [`UuidCreateSequential`](https://learn.microsoft.com/en-us/windows/win32/api/rpcdce/nf-rpcdce-uuidcreatesequential) for version 1
- `System.Guid.NewGuid()` for version 4
- `System.Guid.CreateVersion7()` for version 7
- Versions 3 and 5 take two parameters: a namespace and a name
- The namespace must be a valid GUID or one of the [predefined ones](https://datatracker.ietf.org/doc/html/rfc4122#appendix-C)
- The `PredefinedNamespaces` dictionary contains aliases for the predefined namespaces
- The name can be any string
### [`UrlEncodeRequest`](/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Generators/Uri/UrlEncodeRequest.cs)
- Implements IComputeRequest
- `Compute()` will populate `Result` with the encoded url converted using `HttpUtility.UrlEncode()`.
### [`UrlDecodeRequest`](/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Generators/Uri/UrlDecodeRequest.cs)
- Implements IComputeRequest
- `Compute()` will populate `Result` with the decoded url converted using `HttpUtility.UrlDecode()`.
### [`DataEscapeRequest`](/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Generators/Uri/DataEscapeRequest.cs)
- Implements IComputeRequest
- `Compute()` will populate `Result` with the escaped data string converted using `System.Uri.EscapeDataString()`.
### [`DataUnescapeRequest`](/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Generators/Uri/DataUnescapeRequest.cs)
- Implements IComputeRequest
- `Compute()` will populate `Result` with the unescaped data string converted using `System.Uri.UnescapeDataString()`.
### [`HexEscapeRequest`](/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Generators/Uri/HexEscapeRequest.cs)
- Implements IComputeRequest
- `Compute()` will populate `Result` with the escaped data string converted using `System.Uri.HexEscape()`.
- Only single characters are supported as input.
### [`HexUnescapeRequest`](/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Generators/Uri/HexUnescapeRequest.cs)
- Implements IComputeRequest
- `Compute()` will populate `Result` with the unescaped data string converted using `System.Uri.HexUnescape()`.
- Only the first hexadecimal character in the string gets unescaped. The rest of the user input is ignored.
### [`InputParser`](/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/InputParser.cs)
- It is responsible only for parsing the query from the user
- Based on the user query, the `ParseInput()` method must return an object that implements the `IComputeRequest` interface or it must throw one of `FormatException` or `ArgumentException`
- Throwing an `ArgumentException` should signal the fact that the query contains a mistake that the user can fix (e.g. an unsupported hash function, an invalid GUID version, an invalid namespace, etc.)
> The error message will be shown to the user and no log message will be created
- Throwing a `FormatException` should signal either:
- that the query may become valid, and so it does not make sense to show an error just yet (e.g. the query does not contain a request yet, a hash request without a string to hash)
- that the query is completely invalid
> The error message will not be shown to the user but a log message will be created
### Adding a new value generator
1. To add a new value generator, create a folder under `/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Generators/` and inside it add a class that implements `IComputeRequest`.
2. Add any utility classes that are specific to the new generator inside the same folder to keep them separated from the other generators.
3. Modify the `InputParser.ParseInput()` to handle a request for the new generator and return an instance of the class you created in step 1
@@ -0,0 +1,17 @@
# Folder Plugin
The Folder plugin is used to navigate the directory structure and display the sub-folders and files within a folder.
![Image of Folder plugin](/doc/images/launcher/plugins/folder.png)
### [`FolderHelper.cs`](src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Sources/Path/FolderHelper.cs)
- The [`FolderHelper`](src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Sources/Path/FolderHelper.cs) class leverages the `DriveInformation` and `folderLinks` to get the folder results for a user query.
- The [`DriveInformation`](src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Sources/Path/DriveInformation.cs) class gets the list of all drives on the system.
- The [`FolderLink`](src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Sources/FolderLink.cs) object corresponds to a user created link for frequently accessed projects. This was inherited from Wox but is presently not functional as we don't have the UI setup in settings to get this user input. Each folderLink object has a `nickname`, which is the name of the folder and this can be used to directly access that folder instead of entering the entire path.
### [`IFolderProcessor.cs`](src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Sources/IFolderProcessor.cs)
The `IFolderProcessor` utilizes the `FolderHelper` class to extract the folders and return the results.
There are two types of Folder Processors, based on the type of information they are processing -
1. [`UserFolderProcessor`](src/modules/launcher/Plugins/Microsoft.Plugin.Folder/UserFolderProcessor.cs) - This Processor is currently not used in PT Run but it is used to process the user created folder links.
2. [`InternalDirectoryProcessor`](src/modules/launcher/Plugins/Microsoft.Plugin.Folder/InternalDirectoryProcessor.cs) - This processor is used to retrieve the files and folders located within the current drive or shared folder.
### Score
The first result is of score 500 and the following results are scored 10.
@@ -0,0 +1,103 @@
# History Plugin
The History Plugin allows users to search or display results they have used (selected).
## How it works
The plugin uses data that was already being captured which is, what results were clicked, and how many times. We do add a little more data to this set now.
When this plugin is queried, it creates results based on this previously selected results data.
In order to make sure selected results in the history are still valid, we re-query the relevant plugin using the PluginManager. If there are no results,
this history item is not included. This usually means that the result is no longer valid. For instance, if a file was deleted, but it's still in the selected history
we don't want to show it as a selectable result.
Because the results from the History Plugin are actually created from calls to the PluginManager, they will be exactly the same is if they did not come from the History Plugin.
## Special notes
While the results returned from the plugin are from the PluginManager, they are sometimes modified before returning. One example is the Calculator plugin.
Since the Calculator plugin operates on the current query input by the user, the results from Calculator plugin don't include that in the title. However, as a history item,
the query is very important. In this case, and maybe others in the future, we modify the tile to also include the search.
### Modified title example:
This is what the Calculator plugin normally might show:
![image](https://user-images.githubusercontent.com/4396667/184661303-4f8cf0da-2956-46b9-bdc1-ed879cd0b7cc.png)
But this is how it will look returned from the History plugin
![image](https://user-images.githubusercontent.com/4396667/184661450-9ec3c416-66df-40c8-b004-da8b0cebc5c5.png)
As you can see, here and maybe other places, other non-history plugin might be able to include extra data for the History plugin to use later.
For example, in future, plugins might be able to also set a "History Title", "History Icon", etc... But for now, it's not needed.
## Duplicates from the History Plugin in global results
If the History plugin is set to show in the global results, it might return a result that is also returned from another plugin. If a match is found,
the result from the history plugin is discarded.
## Removing items from history
A new context menu item is added to each History result, which can be used to delete it from the history.
![image](https://user-images.githubusercontent.com/4396667/184656195-6d9f1a49-652c-4027-a424-535e9fb1f2a8.png)
## Context menus
Because these results are coming from the History plugin, this plugin must invoke each menu items `LoadContextMenus` method.
We then also add the "Remove this from history" context menu action.
## Results score
When the plugin is used with the activation command, the scores are configured so the results show with the more recently selected items at the top.
If the history results are shown in the global results, the scores are not modified from that the original plugin set.
## Old Data
Items selected before this plugin was created will not show in the history because they don't contain enough data.
## Important for developers
### Important plugin values (meta-data)
| Name | Value |
| --------------- | ---------------------------------------------------- |
| ActionKeyword | `!!` |
| ExecuteFileName | `Microsoft.PowerToys.Run.Plugin.History.dll` |
| ID | `C88512156BB74580AADF7252E130BA8D` |
### Interfaces used by this plugin
The plugin uses only these interfaces (all inside the `Main.cs`):
* `Wox.Plugin.IPlugin`
* `Wox.Plugin.IContextMenu`
* `Wox.Plugin.IPluginI18n`
### Program files
| File | Content |
| ------------------------------------- | ----------------------------------------------------------------------- |
| `Images\history.dark.png` | Symbol for the results for the dark theme |
| `Images\history.light.png` | Symbol for the results for the light theme |
| `Properties\Resources.Designer.resx` | File that contain all translatable keys |
| `Properties\Resources.resx` | File that contains all translatable strings in the neutral language |
| `Main.cs` | Main class, the only place that implements the WOX interfaces |
| `ErrorHandler.cs` | Class to build error result on plugin failure |
| `plugin.json` | All meta-data for this plugin |
### Important project values (*.csproj)
| Name | Value |
| --------------- | ------------------------------------------------- |
| TargetFramework | `net6.0-windows10.0.19041.0` |
### Project dependencies
#### Projects
* `Wox.Infrastructure`
* `Wox.Plugin`
* `PowerToys.PowerLauncher`
#### Build Dependency
Access to PluginManager was needed to make this plugin work. Because of this a reference to PowerToys.PowerLauncher was needed.
Since History Plugin needs a reference to PowerToys.PowerLauncher, it cannot be set as a dependency reference in PowerToys.PowerLauncher project (else a circular reference would exist).
This means that if you build PowerToys.PowerLauncher only it will not build History Plugin. You will need to manually build History Plugin at least once and again manually if you change it.
### Caching
Right now, there is no caching. But since this plugin does cause more queries than expected to many plugins, the `BuildResult` method is likely to be improved with some level of caching.
@@ -0,0 +1,39 @@
# Indexer Plugin
The indexer plugin is used to search for files within the indexed locations of the system.
![Image of Indexer plugin](/doc/images/launcher/plugins/indexer.png)
### [Drive Detection](src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/DriveDetection)
- There are two indexing modes in Windows:
1. **Classic mode**: Only the desktop and certain customizable locations in the system are indexed. All the systems have the classic mode enabled by default.
2. **Enhanced Mode**: This mode indexes the entire PC when enabled. The user can exclude certain locations from being indexed in this mode from the Windows Search settings options.
- A drive detection warning is displayed to the users when only the custom mode is enabled on the system informing the user that not all the locations on their PC are indexed as this could lead to some results not showing up.
- The [`IndexerDriveDetection.cs`](src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/DriveDetection/IndexerDriveDetection.cs) file gets the status of the drive detection checkbox in the settings UI and depending on whether the enhanced mode is enabled or disabled, displays the warning.
- To determine whether the `EnhancedMode` is enabled or not, we check the local machine registry entry for `EnableFindMyFiles`. If it is set to 1, the enhanced mode is enabled.
### [`OleDBSearch`](src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/SearchHelper/OleDBSearch.cs)
- The `Query` function within the [`OleDBSearch.cs`](src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/SearchHelper/OleDBSearch.cs) class takes in the query and the connection string to the SystemIndex catalog as arguments and returns a list of results.
- It first opens a [connection][OLEDBConnection] to the Windows Indexer database, creates an [OleDB command][OLEDBCommand] and executes the command to get a list of results.
### [`WindowsSearchAPI`](src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/SearchHelper/WindowsSearchAPI.cs)
- The [`WindowsSearchAPI`](src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/SearchHelper/WindowsSearchAPI.cs) class leverages the [`OleDBSearch.cs`](src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/SearchHelper/OleDBSearch.cs) class to execute the query.
- It initializes the `QueryHelper` in the `InitQueryHelper()` function by creating a catalog manager to the SystemIndex catalog.
- The metadata is initialized within the query helper, such as the number of results to retrieve, the type of information to retrieve for each file (currently we retrieve the item URL, the file name and the file attributes).
- The query helper matches results using the name of the file only and they are sorted by the last modified date, ensuring that the recently modified files are ranked higher.
- The File attributes are utilized to filter out hidden files from being displayed.
### Additional Information
- There are two major types of queries generated by the indexer plugin:
1. Full Text predicates - eg: [CONTAINS][Contains]
2. Non-Full Text predicates - eg: [LIKE][Like]
- The Full text predicates are much faster than non-full text predicates as they are based on finding matches rather than comparing the query with each item in the indexer database. Hence, queries which have the `CONTAINS` keyword are much faster than those which contain the `LIKE` keyword.
- To prevent the indexer query from taking a long time and blocking the UI thread, there are two types of indexer queries which are executed. A simplified query and a full query, without and with the `LIKE` keyword respectively.
- The result list is updated with the results of the full query once they are obtained.
### Score
Each of the indexer plugin results has a score set to 0 so they are present at the bottom of the list.
[OLEDBCommand]: https://learn.microsoft.com/dotnet/api/system.data.oledb.oledbcommand?view=dotnet-plat-ext-3.1
[OLEDBConnection]: https://learn.microsoft.com/dotnet/api/system.data.oledb.oledbconnection?view=dotnet-plat-ext-3.1
[Contains]: https://learn.microsoft.com/windows/win32/search/-search-sql-contains
[Like]: https://learn.microsoft.com/windows/win32/search/-search-sql-like
@@ -0,0 +1,38 @@
# OneNote Plugin
The OneNote plugin searches your locally synced OneNote notebooks based on the user query.
![Image of OneNote plugin](/doc/images/launcher/plugins/onenote.png)
The code itself is very simple, basically just a call into OneNote interop via the https://github.com/scipbe/ScipBe-Common-Office library.
```csharp
var pages = OneNoteProvider.FindPages(query.Search);
```
The query results will be cached for 1 day, and if cached results are found they'll be returned in the initial `Query()` call; otherwise, OneNote itself will be queried in the `delayedExecution:true` overload.
If the user actions on a result, it'll open it in the OneNote app, and restore and/or focus the app as well if necessary.
```csharp
if (PInvoke.IsIconic(handle))
{
PInvoke.ShowWindow(handle, SHOW_WINDOW_CMD.SW_RESTORE);
}
PInvoke.SetForegroundWindow(handle);
```
The plugin attempts to call the library in the constructor, and if it fails with a COMException then it'll note that OneNote isn't available and not attempt to query it again.
```csharp
try
{
_ = OneNoteProvider.PageItems.Any();
_oneNoteInstalled = true;
}
catch (COMException)
{
// OneNote isn't installed, plugin won't do anything.
_oneNoteInstalled = false;
}
```
@@ -0,0 +1,38 @@
# Structural Overview
The following basic functions are common to each of the plugins. They perform some rudimentary operations such as initialization of the plugin, executing the query that has been entered, loading context menu icons, updating settings when configurations are altered in the settings UI, and updating the theme of the icons when the theme changed event is triggered.
## IPlugin Interface
Each plugin implements the `IPlugin` interface which comprises of the `Init()` and `Query()` functions.
### `Init`
- The `Init()` function initializes the context, storage and settings of each plugin. This is equivalent to a constructor and is the first function to be called in the `Main.cs` file for each plugin.
### `Query`
- For every query that the user enters into PT Run, the `PluginManager.cs` executes the `Query()` function in the `Main.cs` file corresponding to each Plugin.
### Context Menu Icons
- The `ContextMenus` are loaded for each result based on the type of the result.
- The various types of `ContextMenu` functionalities are:
- Open containing folder
- Run as Administrator
- Open in console
- Copy path
### UpdateSettings
- This function updates the settings of each plugin based on the changes made by the user in the settings UI.
- Eg: To disable drive detection in the indexer plugin, when the user checks or unchecks the drive detection check box, the `UpdateSettings()` function dispatches the changes in the check box to the plugin.
### ThemeChanged
- This function is invoked when there is a change in the theme of PT Run.
- It is used to update the `IconPath` for each plugin based on the theme.
### Save
- This function saves the configurations of each plugin so that they can be loaded the next time.
### Score
- The user query is executed against each of the plugins and the result list view is updated with results from each of the plugins.
- The ordering of the results is based on the `Score` of each Result.
- Each plugin assigns a score to a result based on its relevance. The results with higher scores are displayed higher in the list view and vice versa.
## Plugin settings
Plugin settings that are editable from the settings are stored in `PowerToys Run\settings.json`. In the very first run, those settings are populated from plugin' `plugin.json` file. Unlike Wox we do not support multiple action keywords. Instead, we have `ActionKeyword` and `IsGlobal` options.
@@ -0,0 +1,47 @@
# Program Plugin
The program plugin as the name suggests is used to search for programs installed on the system.
![Image of Program plugin](/doc/images/launcher/plugins/program.png)
There are broadly two different categories of applications:
1. Packaged applications
2. Win32 applications
### [UWP](src/modules/launcher/Plugins/Microsoft.Plugin.Program/Programs/UWP.cs)
- The logic for indexing Packaged applications is present within the [`UWP.cs`](src/modules/launcher/Plugins/Microsoft.Plugin.Program/Programs/UWP.cs) file.
- There can be multiple applications present within a package. The [`UWPApplication.cs`](src/modules/launcher/Plugins/Microsoft.Plugin.Program/Programs/UWPApplication.cs) file encapsulates the properties of a packaged application.
- To index packaged applications, the `PackageManager` retrieves all the packages for the current user and indexes all the applications.
- To retrieve the app icon for packaged applications, the assets path is retrieved from the `Application Manifest` file. There are multiple icons corresponding to each scale, target size and theme. The best icon is chosen given the theme of powerToys Run.
### [Win32Program](src/modules/launcher/Plugins/Microsoft.Plugin.Program/Programs/Win32Program.cs)
- Win32 programs in the following locations are indexed by PT Run-
1. Desktop
2. Public Desktop (Applications present on the desktop of all the users)
3. Registry (Some programs)
4. Start Menu
5. Common start menu (Applications which are common to all users)
8. Locations pointed to by the PATH environment variable.
- To prevent applications and shortcuts present in multiple locations from showing up as duplicate results, we consider apps with the same name, executable name and full path to be the same.
- The subtitle of the application result is set based on its application type. It could be one of the following:
1. Lnk Shortcuts
2. Appref files
3. Internet shortcut - steam and epic games
4. PWAs
5. Run commands - these are indexed by the PATH environment variable
### Score
- The score for each application result is based on the how many letters are matched, how close the matched letters are to the actual word and the index of the matched characters.
- There is a threshold score to decide the apps which are to be displayed and applications which have a lower score are not displayed by PT Run.
### Update Program List in Runtime
- Packaged and Win32 app helpers exist to reflect changes in the list of indexed apps when applications are installed on the system while PT Run is executing.
- Packaged applications trigger events when the package is being installed and uninstalled. PT Run listens to those events to index applications which are newly installed or to delete an app which no longer exists from the database.
- No such events exist for Win32 applications. We therefore use FileSystem Watchers to monitor the locations that we index for newly created, deleted or renamed application files and update the indexed Win32 catalog accordingly.
### Additional Notes
- Arguments can be provided to the program plugin by entering them after `--` (a double dash).
- The localization is done using the `Localization Helper`from `Wox.Plugin.Common` hosted at runtime in a variable of plugin's main class.
- The `Run commands` differ in two points from the normal `Win32Programs`:
- The result title contains the executable type.
- The file types `.cpl` and `.msc` are supported too.
@@ -0,0 +1,92 @@
# Registry Plugin
The registry plugin allows users to search the Windows registry.
## Special functions (differ from the regular functions)
* Support full base keys and short base keys (e.g. `HKLM` for `HKEY_LOCALE_MACHINE`).
* Show count of subkeys and count of values in the second result line.
* Search for value names and value data inside a registry key (syntax: `[RegistryKey]\\[ValueName]` and `[RegistryKey]\\[ValueData]`)
## The Windows Registry
The registry contains all settings for the Windows operating system and many settings of the installed (Windows only) programs.
*Note: Linux and macOS program ports typical store the settings in their own configuration files and not in the Windows registry.*
For more information about the Windows registry, see [the official documentation](https://learn.microsoft.com/windows/win32/sysinfo/registry).
For advanced information about the Windows registry, see [Windows registry information for advanced users](https://learn.microsoft.com/troubleshoot/windows-server/performance/windows-registry-advanced-users).
## Score
The score is currently not set on the results.
## Important for developers
### General
* The assembly name is cached into `_assemblyName` (to avoid to many calls of `Assembly.GetExecutingAssembly()`)
### Results
* All results override the visible search result via `QueryTextDisplay` to avoid problems with short registry base keys (e.g. `HKLM`).
* The length of a `Title` and `Subtitle` is automatic truncated, when it is to long.
## Microsoft.Plugin.Registry project
### Important plugin values (meta-data)
| Name | Value |
| --------------- | --------------------------------------------- |
| ActionKeyword | `:` |
| ExecuteFileName | `Microsoft.PowerToys.Run.Plugin.Registry.dll` |
| ID | `303417D927BF4C97BCFFC78A123BE0C8` |
### Interfaces used by this plugin
The plugin use only these interfaces (all inside the `Main.cs`):
* `Wox.Plugin.IPlugin`
* `Wox.Plugin.IContextMenu`
* `Wox.Plugin.IPluginI18n`
* `System.IDisposable`
### Program files
| File | Content |
| ------------------------------------ | ------------------------------------------------------------------------ |
| `Classes\RegistryEntry.cs` | Wrapper class for a registry key with a possible exception on access |
| `Constants\KeyName.cs` | Static used short registry key names (to avoid code and string doubling) |
| `Constants\MaxTextLength.cs` | Contain all maximum text lengths (for truncating) |
| `Enumeration\TruncateSide.cs` | Contain the possible truncate sides |
| `Helper\ContextMenuHelper.cs` | All functions to build the context menu (for each result entry) |
| `Helper\QueryHelper.cs` | All functions to analyze the search query |
| `Helper\RegistryHelper.cs` | All functions to search into the Windows registry (via `Win32.Registry`) |
| `Helper\ResultHelper.cs` | All functions to convert internal results into WOX results |
| `Helper\ValueHelper.cs` | All functions to convert values into human readable values |
| `Images\reg.dark.png` | Symbol for the results for the dark theme |
| `Images\reg.light.png` | Symbol for the results for the light theme |
| `Properties\Resources.Designer.resx` | File that contain all translatable keys |
| `Properties\Resources.resx` | File that contain all translatable strings in the neutral language |
| `Main.cs` | Main class, the only place that implement the WOX interfaces |
| `plugin.json` | All meta-data for this plugin |
### Important project values (*.csproj)
| Name | Value |
| --------------- | ------------------------------------------------------------------------------ |
| TargetFramework | `net6.0-windows` (.NET 5) or `net6.0-windows10.0.19041.0` (OS version specific)|
| LangVersion | `8.0` (mean C# 8.0) |
| Platforms | `x64` |
| Nullable | `true` |
| Output | `..\..\..\..\..\x64\Debug\modules\launcher\Plugins\Microsoft.Plugin.Registry\` |
| RootNamespace | `Microsoft.PowerToys.Run.Plugin.Registry` |
| AssemblyName | `Microsoft.PowerToys.Run.Plugin.Registry` |
### Project dependencies
#### Projects
* `Wox.Infrastructure`
* `Wox.Plugin`
@@ -0,0 +1,14 @@
# Shell Plugin
- Shell plugin emulates the Windows Run Prompt (Win+R).
- Shell Plugin is one of the non-global plugins which has an action keyword set to `>`.
![Image of Shell plugin](/doc/images/launcher/plugins/shell.png)
### Functionality
- The Shell command expands environment variables, so `>%appdata%` works as expected.
- On inheriting the Shell plugin from Wox, there are three different ways of executing a command, using the command prompt, powershell or the run prompt. To uphold the name of PT Run, the Shell plugin always executes commands as the Run prompt would.
- The Shell plugin has a concept of history where the previously executed commands show up in the drop down list along with the number of times they have been executed.
- The Run prompt has the folder plugin function where we can navigate to different locations and entering the path to a directory displays all the sub-directories. To prevent reimplementing this logic, the shell plugin references the folder plugin to implement this functionality.
### Score
The Shell plugin results have a very high score of 5000. Hence, they are one of the first results in the list.
@@ -0,0 +1,85 @@
# Windows System Commands Plugin
As the name suggests, the Windows System Commands Plugin is used to directly run Windows system commands that have been entered by the user as a query. This is done by parsing the entry and validating the command, followed by executing it.
The user can change the behavior of the plugin (language, confirmation dialog, ...) with optional plugin settings.
![Image of System Commands plugin](/doc/images/launcher/plugins/sys.gif)
Available commands:
* Shutdown
* Restart
* Sign Out
* Lock
* Sleep
* Hibernate
* Open / Empty Recycle Bin
* UEFI Firmware Settings (Only available on systems, that boot in UEFI mode.)
* IP / MAC / Address => Show information about network connections.
## Optional plugin settings
* We have the following settings that the user can configure to change the behavior of the plugin:
| Key | Default value | Name/Description |
|--------------|-----------|------------|
| `ConfirmSystemCommands` | `false` | Show a dialog to confirm system commands |
| `LocalizeSystemCommands` | `true` | Use localized system commands instead of English ones |
| `ReduceNetworkResultScore` | `true` | Reduce the priority of 'IP' and 'MAC' results to improve the order in the global results |
* The optional plugin settings are implemented via the [`ISettingProvider`](/src/modules/launcher/Wox.Plugin/ISettingProvider.cs) interface from `Wox.Plugin` project. All available settings for the plugin are defined in the [`Main`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Main.cs) class of the plugin.
## Technical details
### [`Main`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Main.cs)
* Tries to parse the user input and returns a specific Windows system command by using a [`Result`](/src/modules/launcher/Wox.Plugin/Result.cs) list.
* While parsing, the plugin uses [`FuzzyMatch`](/src/modules/launcher/Wox.Infrastructure/StringMatcher.cs) to get characters matching a result in the list.
### [`Commands.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Components/Commands.cs)
- The [`Commands`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Components/Commands.cs) class contains the definition of all available commands/results.
### [`ResultHelper.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Components/ResultHelper.cs)
- The [`ResultHelper`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Components/ResultHelper.cs) class contains methods for working with the results and some of the result features (tool tip, copy to clipboard, execute command).
- **Recycle Bin command:** The context menu action to empty the Recycle Bin is executed as an async task to not block PowerToys Run. (While the task is running the static class variable `executingEmptyRecycleBinTask` is set to true, to block multiple executions at the same time)
### [`NetworkConnectionProperties.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Components/NetworkConnectionProperties.cs)
- The [`NetworkConnectionProperties`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Components/NetworkConnectionProperties.cs) class contains methods to get the properties of a network interface/connection.
- An instance of this class collects/provides all required information about one connection/adapter.
### [`SystemPluginContext.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Components/SystemPluginContext.cs)
- An instance of the class [`SystemPluginContext`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Components/SystemPluginContext.cs) contains/defines the context data of a system plugin result. We select the context menu based on the defined properties.
- It is used for the `ContextData` property of the [`Wox.Plugin.Result`](/src/modules/launcher/Wox.Plugin/Result.cs).
### UEFI command
* The UEFI command is only available on systems, that boot in UEFI mode.
* This is validated by checking the result of the method [`GetSystemFirmwareType`](/src/modules/launcher/Wox.Plugin/Common/Win32/Win32Helpers.cs), which uses the native method [`GetFirmwareType`](/src/modules/launcher/Wox.Plugin/Common/Win32/NativeMethods.cs) in `kernel32.dll`.
## Search
### Score
* [`CalculateSearchScore`](/src/modules/launcher/Wox.Infrastructure/StringMatcher.cs) A match found near the beginning of a string is scored more than a match found near the end. A match is scored more if the characters in the patterns are closer to each other, while the score is lower if they are more spread out.
* For network results (IP address and MAC address) the score is reduced by 25 percent.
### Network results on global queries
- The network results (IP and MAC address) are only shown on global queries, if the search term starts with either IP, MAC or Address. (We compare case-insensitive.)
### Returning results
We return the results in two steps:
1. All results which we can create very fast like shutdown or logoff via [`Main.Query(Query query)`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Main.cs).
2. All results which need some time to create like the network results (IP, MAC) via [`Main.Query(Query query, bool delayedExecution)`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Main.cs).
## [Unit Tests](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System.UnitTests)
We have a [Unit Test project](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System.UnitTests) that executes various test to ensure that the plugin works as expected.
### [`ImageTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System.UnitTests/ImageTests.cs)
- The [`ImageTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System.UnitTests/ImageTests.cs) class contains tests to validate that each result shows the expected and correct image.
### [`QueryTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System.UnitTests/QueryTests.cs)
- The [`QueryTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System.UnitTests/QueryTests.cs) class contains tests to validate that the user gets the correct results when searching.
@@ -0,0 +1,178 @@
# 'Time and Date' plugin
The 'Time and Date' plugin shows the date and time in different formats. For the date and time formats the plugin uses the culture setting in Windows, if the format is not commonly defined. The user can search for the system date/time or a custom date/time. The value of each result can be copied to clipboard.
**Query examples:**
- Format: `time`
- Date/time: `10:30 AM`
- Format and date/time: `Week number::10/10/2022`
!['Time and Date' plugin](/doc/images/launcher/plugins/timedate.png)
![Search for a date in a specified format](/doc/images/launcher/plugins/timedate2.png)
## Formats
### Available formats
**Remarks**
- The following formats requires a prefix in the query when using them as date input:
- Unix Timestamp: `u`
- Unix Timestamp in milliseconds: `ums`
- Windows file time: `ft`
- OLE Automation date: `oa`
- Excel 1900 date value: `exc`
- Excel 1904 date value: `exf`
- On invalid number inputs we show a warning that tells the user which prefixes are allowed/required.
**List of available formats**
The following formats are currently available:
| Format | Example (Based on default settings) | As result | As input | Result as custom format only
|--------------|-----------|------------|------------|
| Time | 5:10 PM | x | x | |
| Date | 3/5/2022 | x | x | |
| Now | 3/5/2022 5:10 PM | x | x | |
| Time UTC | 4:10 PM | x | x | |
| Now UTC | 3/5/2022 4:10 PM | x | x | |
| Unix Timestamp | 1646496622 | x | x | |
| Unix Timestamp in milliseconds | 1646496622500 | x | x | |
| Hour | 10 | x | | |
| Minute | 30 | x | | |
| Second | 45 | x | | |
| Millisecond | 678 | x | | |
| Day (Week day) | Saturday | x | | |
| Day of the week | 6 | x | | |
| Day of the month | 5 | x | | |
| Day of the year | 64 | x | | |
| Week of the month | 1 | x | | |
| Week of the year (Calendar week, Week number) | 10 | x | | |
| Month | March | x | | |
| Month of the year | 3 | x | | |
| Month and day | March 7 | x | x | |
| Year | 2022 | x | | |
| Era | AD | x | | |
| Era abbreviation | A | x | | |
| Month and year | March 2022 | x | x | |
| Windows file time (Int64 number) | 637820976123938199 | x | x | |
| Universal time format: YYYY-MM-DD hh:mm:ss| 2022-03-05 16:20:12Z | x | x | |
| ISO 8601 | 2022-03-05T17:23:04 | x | x | |
| ISO 8601 UTC | 2022-03-05T16:23:04 | x | x | |
| ISO 8601 with time zone | 2022-03-05T17:23:04+01:00 | x | x | |
| ISO 8601 UTC with time zone | 2022-03-05T16:23:04Z | x | x | |
| RFC1123 | Sat, 05 Mar 2022 16:23:04 GMT | x | x | |
| OLE Automation date | 45723.44143763889 | | x | x |
| Excel's 1900 date value | 45723.44143763889 | | x | x |
| Excel's 1904 date value | 44261.44143763889 | | x | x |
**Custom format definition**
The user can create its own formats. One per line in the settings text box. The format of each line is `<name>=<syntax pattern>`.
If the syntax pattern starting with `UTC:` then we use the UTC time instead of the local time.
As syntax pattern the pattern from `DateTime.ToString()` and the following custom pattern are available:
- DOW: Number of the day in the week.
- WOM: Number of week in the month.
- WOY: Number of the week in the year.
- EAB: Era abbreviation.
- WFT: Windows file time.
- UXT: Unix time stamp.
- UMS: Unix time stamp in milliseconds.
- OAD: OLE Automation date.
- EXC: Excel's 1900 based date value.
- EXF: Excel's 1904 based date value.
### Add new formats
- To add a new formats you have to add them to the method `GetList()` of the [`AvailableResultsList`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate/Components/AvailableResultsList.cs) class.
- Please add the new formats in the second range. The first one is reserved for the three main formats (Time, Date, Now).
- After adding the new formats you have to update the Unit Tests!
## Optional plugin settings
- The optional plugin settings are implemented via the [`ISettingProvider`](/src/modules/launcher/Wox.Plugin/ISettingProvider.cs) interface from `Wox.Plugin` project.
- All available settings for the plugin are defined in the [`TimeDateSettings`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate/Components/TimeDateSettings.cs) class of the plugin. The settings can be accessed everywhere in the plugin code via the static class instance `TimeDateSettings.Instance`.
- We have the following settings that the user can configure to change the behavior of the plugin:
| Key | Type | Default value | Name | Description |
|--------------|--------------|-----------|------------|------------|
| `OnlyDateTimeNowGlobal` | Checkbox | `true` | Show only 'Time', 'Date', and 'Now' result for system time on global queries | Regardless of this setting, for global queries the first word of the query has to be a complete match. |
| `TimeWithSeconds` | Checkbox | `false` | Show time with seconds | This setting applies to the 'Time' and 'Now' result. |
| `DateWithWeekday` | Checkbox | `false` | Show date with weekday and name of month | This setting applies to the 'Date' and 'Now' result. |
| `HideNumberMessageOnGlobalQuery` | Checkbox | `false` | Hide 'Invalid number input' error message on global queries | |
| `CalendarFirstWeekRule` | Combo box | `-1` (Use system settings) | First week of the year | Configure the calendar rule for the first week of the year. |
| `FirstDayOfWeek` | Combo box | `-1` (Use system settings) | First day of the week | |
| `CustomFormats` | Multiline text box | `string.Empty` | Custom formats | Use date and time string format syntax and DOW (Day of Week), WOM (Week of Month), WOY (Week of the year), EAB (Era abbreviation), WFT (Windows File Time), UXT (Unix Time), UMS (Unix Time in milliseconds), OAD (OLE Automation date), EXC (Excel's 1900 based date value), EXF (Excel's 1904 based date value). If the format starts with UTC:, then Universal Time (UTC) is used. (Use a backslash to escape format sequences and the backslash character as text.) |
## Classes
### [`AvailableResult.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate/Components/AvailableResult.cs)
- Each instance of the [`AvailableResult`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate/Components/AvailableResult.cs) class represents a time/date result/format that the user can search for.
- The results/formats are defined in the `AvailableResultsList` class.
### [`AvailableResultsList.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate/Components/AvailableResultsList.cs)
- The [`AvailableResultsList`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate/Components/AvailableResultsList.cs) class contains the list of available formats/results in its method `GetList()`.
### [`ResultHelper.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate/Components/ResultHelper.cs)
- The [`ResultHelper`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate/Components/ResultHelper.cs) class contains methods for some of the result features (tool tip, copy to clipboard) and the error result on incorrect number input.
- And it contains the `SelectStringFromResources()` method for getting the resource strings based on the user input.
- The method has a parameter for the `stringId` which is the name of the string in the resource file. By default the word `Now` is automatically added at the end to get the string for a system time/date search.
- If a different/custom string is needed for a system time/date search the parameter `stringIdNow` can be used to override the default behavior of the method.
- If only a string for the system time/date search is required, you can set `stringId` to `string.Empty` and only `stringIdNow` to a valid string id.
### [`TimeAndDateHelper.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate/Components/TimeAndDateHelper.cs)
- The [`TimeAndDateHelper`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate/Components/TimeAndDateHelper.cs) class contains methods to format/convert date and time formats/strings.
- And it contains methods to return the `first week day` and `first week of the year rule` based on the current plugin settings.
### [`TimeDateSettings.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate/Components/TimeDateSettings.cs)
- The [`TimeDateSettings`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate/Components/TimeDateSettings.cs) 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.
### [`SearchController.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate/Components/SearchController.cs)
- The [`SearchController`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate/Components/SearchController.cs) encapsulates the methods needed to search and find matches.
## Search
### Tags
- We compare the user input with the label of each results. If it doesn't match we search the tags of the result too.
- For each result two tag strings are defined. One for a search with system time/date and one for a search with a custom time/date. Most of the results (except the era results) are using one of the generic tag lists: Date, Time or Format
- The selection of the tag (for "system time/date" or "custom time/date") is happening at search time in the `AvailableResultsList.cs` class.
- The different tags in a list are split by the `;` character.
### Score
- The plugin uses `FuzzyMatching` to get the matching formats, if the user searches for a specific format. The score is set based on the `FuzzySearch` result.
- To achieve a better balance between sub title matches and tag matches the score of tag matches is divided by two.
### Match requirements for global queries
On global queries the high score returned by `FuzzySearch` has negative impacts on the user experience and the search results priority/order of other plugins. To mitigate this we defined some matching requirements:
- If the query is a word of the following conjunction list, we don't return any results: for, and, nor, but, or, so
- We don't have 'yet' (synonym of 'now') on the list, because this could block results in some languages.
- The first word of the query has to be a full match with a word in the label or tag list.
- For both requirements we compare case-insensitive.
## [Unit Tests](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests)
We have a [Unit Test project](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests) that executes various test to ensure that the plugin works as expected.
### [`ImageTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests/ImageTests.cs)
- The [`ImageTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests/ImageTests.cs) class contains tests to validate that each result shows the expected and correct image.
- That we can execute the tests at any time on any machine, we set the thread culture always to `en-us` while executing the tests.
### [`PluginSettingsTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests/PluginSettingsTests.cs)
- The [`PluginSettingsTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests/PluginSettingsTests.cs) class contains tests to validate that all settings exist and that they have the correct default values.
### [`QueryTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests/QueryTests.cs)
- The [`QueryTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests/QueryTests.cs) class contains tests to validate that the user gets the correct results when searching.,
- That we can execute the tests at any time on any machine, we set the thread culture always to `en-us` while executing the tests.
### [`StringParserTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests/StringParserTests.cs)
- The [`StringParserTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests/StringParserTests.cs) class contains tests to validate that the typed string gets converted correctly into a `DateTime` object.
- That we can execute the tests at any time on any machine, we set the thread culture always to `en-us` while executing the tests.
### [`TimeAndDateHelperTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests/TimeAndDateHelperTests.cs)
- The [`TimeAndDateHelperTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests/TimeAndDateHelperTests.cs) class contains tests to validate important methods form the `TimeAndDateHelper` class that are not used for string parsing.
### [`TimeDateResultTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests/TimeDateResultTests.cs)
- The [`TimeDateResultTests.cs`](/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests/TimeDateResultTests.cs) class contains tests to validate that the time and date values are correctly formatted/calculated.
- That we can execute the tests at any time on any machine, we use a specified date/time value and set the thread culture always to `en-us` while executing the tests.
- Some tests use custom settings for the first day of week and the first week of year. (This is done in the tests for the affected results to validate them for different settings/cultures.)
- Some tests contain checks that calculate the expected result at runtime instead of using an expected value written fix in the code. This is done to get valid results on every machine at any time.
@@ -0,0 +1,19 @@
# URI Plugin
The URI Plugin, as the name suggests is used to directly run the URI that has been entered by the user as a query. This is done by parsing the entry and validating the URI, followed by executing it.
![Image of URI plugin](/doc/images/launcher/plugins/uri.png)
### [`URI Parser`](src/modules/launcher/Plugins/Microsoft.Plugin.Uri/UriHelper/ExtendedUriParser.cs)
- The [`ExtendedUriParser.cs`](src/modules/launcher/Plugins/Microsoft.Plugin.Uri/UriHelper/ExtendedUriParser.cs) file tries to parse the user input and returns a `System.Uri` result by using the `UriBuilder`.
- It also captures other cases which the UriBuilder does not handle such as when the input ends with a `:`, `.` or `:/`.
### [`URI Resolver`](src/modules/launcher/Plugins/Microsoft.Plugin.Uri/UriHelper/UriResolver.cs)
- The [`UriResolver.cs`](src/modules/launcher/Plugins/Microsoft.Plugin.Uri/UriHelper/UriResolver.cs) file returns true for Valid hosts.
- Currently there is no additional logic for filtering out invalid hosts and it always returns true for a valid Uri that was created by parsing the user query. It can be expanded in the future to filter out certain hosts.
### Default Browser Icon
- The icon for each uri result is that of the default browser set by the user.
- These details are obtained from the user registry and updated each time the theme of PT Run is changed.
### Score
- All uri plugin results have a score of 0 which indicates that they would show up after each of the other plugins, other than the indexer plugin which also has a score of 0.
@@ -0,0 +1,11 @@
## Web Search Plugin
The Web Search Plugin, as the name suggests, is used to perform a web search - in the default search engine in the default browser - on the query that has been entered by the user.
![Image of Web Search plugin](/doc/images/launcher/plugins/WebSearch.png)
## Default Browser Icon
- The icon for each web search result is that of the default browser set by the user.
- It, and the browser path, are obtained from the user registry and updated each time the theme of PT Run is changed.
## Score
- The web search result always has a score of 0 which indicates that it would show up after each of the other plugins, other than the indexer plugin and possibly the uri plugin which both have a score of 0.
@@ -0,0 +1,154 @@
# Windows Settings Plugin
The Windows settings Plugin allows users to search the Windows settings.
## Special functions (differ from the regular functions)
* Support modern Windows settings (Windows 10+)
* Support legacy Windows settings (Windows 7, 8.1)
* Support extra programs for setting (like ODBC)
* Support search by the area of the setting (like `Privacy`)
* Support search for alternative names of a setting
## How to add a new Windows Setting or change one
All Windows settings are located in `WindowsSettings.json` in root folder of the project.
The `WindowsSettings.json` use a JSON schema file that make it easier to edit it.
| Key | Optional | Value type | String prefix |
| ------------------- | -------- | ----------------- | ------------- |
| `Name` | **No** | String | |
| `Type` | **No** | String | `App` |
| `Command` | **No** | String | |
| `Areas` | Yes | List with strings | `Area` |
| `AltNames` | Yes | List with strings | |
| `Note` | Yes | String | `Note` |
| `IntroducedInBuild` | Yes | Integer | |
| `DeprecatedInBuild` | Yes | Integer | |
| `ShowAsFirstResult` | Yes | Boolean | |
A minimum entry for the `WindowsSettings.json` looks like:
```json
{
"Name": "mySetting",
"Type": "AppSettingsApp",
"Command": "ms-settings:mySetting"
}
```
A full entry for the `WindowsSettings.json` looks like:
```json
{
"Name": "mySetting",
"Type": "AppSettingsApp",
"Command": "ms-settings:mySetting",
"Areas": [ "AreaMySettingArea" ],
"AltNames": [ "NiceSetting" ],
"Note": "NoteMySettingNote",
"IntroducedInBuild" : 1903,
"DeprecatedInBuild" : 2004,
"ShowAsFirstResult" : true
}
```
### Remarks
* The `Command` for modern Windows settings should start with `ms-settings:`
* The `Command` for legacy Windows settings should start with `control`
* The integer value for `IntroducedInBuild` and `DeprecatedInBuild` must be in range of `0` to `4294967295`
* The strings for `Name`, `AltNames`, `Areas`, `Type` and `Note` must not contain whitespace(s) or special characters (#, €, $, etc.)
* The strings for `Name`, `AltNames`, `Areas`, `Type` and `Note` are used as ids for the resource file under `Properties\Resources.resx`
* When you add new strings make sure you have added all translations for it.
* If a result has `mmc.exe` as command and the note property is filled, the note is shown in the sub title too. (This is for special MMC results where we don't have a .msc file.)
## Scores
There are three different score types with different start values.
| Score type | Start value |
| ------------------ | ------------ |
| First result score | 10500 |
| High score | 10000 |
| Medium score | 5000 |
| Low score | 1000 |
Each score will be decreased by one when a condition match.
| Priority | Condition | Score type |
| -------- | ----------------------------------------------------------------- | ------------ |
| 1. | Settings name starts with the search value | High score |
| 2. | Settings name contain the search value | Medium score |
| 3. | Setting has no area | Low score |
| 4. | One area of the settings starts with the search value | Low score |
| 5. | Setting has no alternative name | Low score |
| 6. | One alternative name of the settings starts with the search value | Medium score |
| x. | no condition match | Low score |
### Remarks
* For each score condition we check if the property "ShowAsFirstResult" of the setting is true. If yes we use the firstResultScore instead of condition`s score.
## Important for developers
### General
* The assembly name is cached into `_assemblyName` (to avoid to many calls of `Assembly.GetExecutingAssembly()`)
## Microsoft.PowerToys.Run.Plugin.WindowsSettings project
### Important plugin values (meta-data)
| Name | Value |
| --------------- | ---------------------------------------------------- |
| ActionKeyword | `$` |
| ExecuteFileName | `Microsoft.PowerToys.Run.Plugin.WindowsSettings.dll` |
| ID | `5043CECEE6A748679CBE02D27D83747A` |
### Interfaces used by this plugin
The plugin use only these interfaces (all inside the `Main.cs`):
* `Wox.Plugin.IPlugin`
* `Wox.Plugin.IContextMenu`
* `Wox.Plugin.IPluginI18n`
### Program files
| File | Content |
| ------------------------------------- | ----------------------------------------------------------------------- |
| `Classes\WindowsSetting.cs` | A class that represent one Windows setting |
| `Classes\WindowsSettings.cs` | A wrapper class that only contains a list with Windows settings (see 1) |
| `Helper\ContextMenuHelper.cs` | All functions to build the context menu (for each result entry) |
| `Helper\JsonSettingsListHelper.cs` | All functions to load the windows settings from a JSON file |
| `Helper\ResultHelper.cs` | All functions to convert internal results into WOX results |
| `Helper\TranslationHelper.cs` | All functions to translate the result in the surface language |
| `Helper\UnsupportedSettingsHelper.cs` | All functions to filter not supported Windows settings out |
| `Helper\WindowsSettingsPathHelper.cs` | All functions to build the area paths |
| `Images\WindowsSettings.dark.png` | Symbol for the results for the dark theme |
| `Images\WindowsSettings.light.png` | Symbol for the results for the light theme |
| `Properties\Resources.Designer.resx` | File that contain all translatable keys |
| `Properties\Resources.resx` | File that contain all translatable strings in the neutral language |
| `Main.cs` | Main class, the only place that implement the WOX interfaces |
| `plugin.json` | All meta-data for this plugin |
1. We need this extra wrapper class to make it possible that the JSON file can have and use a JSON schema file.
Because the JSON file must have an object as root type, instead of an array.
### Important project values (*.csproj)
| Name | Value |
| --------------- | --------------------------------------------------------------------------------------------------- |
| TargetFramework | `net6.0-windows` (.NET 5) or `net6.0-windows10.0.19041.0` (OS version specific) |
| Platforms | `x64` |
| Output | `..\..\..\..\..\x64\Debug\modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.WindowsSettings\` |
| RootNamespace | `Microsoft.PowerToys.Run.Plugin.WindowsSettings` |
| AssemblyName | `Microsoft.PowerToys.Run.Plugin.WindowsSettings` |
### Project dependencies
#### Projects
* `Wox.Infrastructure`
* `Wox.Plugin`
@@ -0,0 +1,84 @@
# 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](/doc/images/launcher/plugins/windowwalker.png)
## 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](/doc/images/launcher/plugins/windowwalker_folder_options.png)
## Optional plugin settings
- The optional plugin settings are implemented via the [`ISettingProvider`](/src/modules/launcher/Wox.Plugin/ISettingProvider.cs) interface from `Wox.Plugin` project.
- All available settings for the plugin are defined in the [`WindowWalkerSettings`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/WindowWalkerSettings.cs) 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`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/OpenWindows.cs)
- The window walker plugin uses the `EnumWindows` function to enumerate all the open windows in the [`OpenWindows.cs`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/OpenWindows.cs) class.
### [`SearchController.cs`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/SearchController.cs)
- The [`SearchController`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/SearchController.cs) 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`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/Window.cs)
- The [`Window`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/Window.cs) 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`](/src/modules/launcher/Wox.Plugin/Common/VirtualDesktop/VirtualDesktopHelper.cs) in `Wox.Plugin` project. The instance of `VirtualDesktopHelper` is cached in the [`Main`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Main.cs) class of the plugin at runtime. The desktop information is stored in a property of the type [`VDesktop`](/src/modules/launcher/Wox.Plugin/Common/VirtualDesktop/VDesktop.cs).
### [`WindowProcess.cs`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/WindowProcess.cs)
- The [`WindowProcess`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/WindowProcess.cs) 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`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/ResultHelper.cs)
- The [`ResultHelper`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/ResultHelper.cs) 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`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/ContextMenuHelper.cs)
- The [`ContextMenuHelper`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/ContextMenuHelper.cs) class provides the code for the context menu items.
### [`WindowWalkerSettings.cs`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/WindowWalkerSettings.cs)
- The [`WindowWalkerSettings`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/WindowWalkerSettings.cs) 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`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Components/FuzzyMatching.cs) to get the matching indices and calculates the score by creating a 2 dimensional array of the window and the query text.
## [Unit Tests](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker.UnitTests)
We have a [Unit Test project](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker.UnitTests) that executes various test to ensure that the plugin works as expected.
### [`PluginSettingsTests.cs`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker.UnitTests/PluginSettingsTests.cs)
- The [`PluginSettingsTests.cs`](/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker.UnitTests/PluginSettingsTests.cs) class contains tests to validate that all settings exist and that they have the correct default values.