Compare commits

..

40 Commits

Author SHA1 Message Date
Leilei Zhang
c79f3b4c39 Merge branch 'main' of https://github.com/microsoft/PowerToys into leilzh/testing 2025-06-17 15:44:05 +08:00
Kai Tao
c487638758 Workspaces: PWA apps should not necessarily configure profile to launch. (#39971)
<!-- 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
Workspace support for pwa is now limited, it is tight to specific
Profile launch. If you create a pwa app with a profile other than
"Default", launch will fail. Then you have to manually configure that
profile to launch.
This pr fix it by launching with shell:appsfolder\appusermodelId

<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist

- [X] **Closes:** #36384
- [ ] **Communication:** I've discussed this with core contributors
already. If work hasn't been agreed, this work might be rejected
- [ ] **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

<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
- [X] Create a new workspace with a pwa app(Other than default profile)
should be no problem.
- [X] Existing workspace with a pwa(default profile and other profile)
should launch successfully without problem

1. with pt version 91.1, create a loop pwa with "Profile 1" instead of
"Default" in edge.
2. capture and launch actually launch the edge instead of loop
3. Create profile with this impl and launch
4. Launch pwa successfully

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-06-17 15:39:44 +08:00
Kai Tao
252dbb5853 Settings: Generate bug report should tell user there is bug report generating (#40060)
### <!-- 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
### Bug report tool status tracking:

Currently, After clicking the generate package button, button is still
active, as we do not have bug report progress, this will confuse user
whether they actually clicks the button.
Add an enable status to acknowledge the bug generating

<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist

- [ ] **Closes:** #xxx
- [ ] **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

## Detailed Description of the Pull Request / Additional comments
1. Progress bar should be present in generating report place when there
is bug report going on.
2. Runner&Settings should know each other when they trigger the bug
report.
3. Runner tray icon menu item should be disabled when there is one bug
report going on.
4. After bug report generation, everything should be like before.


## Validation Steps Performed


https://github.com/user-attachments/assets/dcbf8e6e-c5e1-4d23-9dab-f16c11ed56cf

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2025-06-17 14:49:54 +08:00
leileizhang
655398e173 Fix PDF generation – reset stream position (#40072)
<!-- 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
This is an additional fix that extends the work done in
https://github.com/microsoft/PowerToys/pull/40023

fix #39851
2025-06-17 14:25:08 +08:00
S. M. Mohiuddin Khan Shiam
f7257bf1d1 Fix PDF thumbnail generation – add System.Drawing reference and reset stream position (#40023)
##  Problem

[PdfThumbnailProvider](cci:1://file:///d:/Github/PowerToys/src/modules/previewpane/PdfThumbnailProvider/PdfThumbnailProvider.cs:15:8-18:9)
could fail at compile-time **and/or** produce empty or invalid
thumbnails at runtime:

1.
[Image](cci:1://file:///d:/Github/PowerToys/src/modules/previewpane/PdfThumbnailProvider/PdfThumbnailProvider.cs:81:8-103:9)
/ `Bitmap` types come from **System.Drawing**, but the namespace was
missing, causing build errors in environments that don’t rely on
implicit global usings.
2. After rendering the first PDF page to an in-memory stream, the
stream’s cursor remained at the end.
`Image.FromStream(stream.AsStream())` therefore read **zero bytes**,
throwing an exception or creating an empty bitmap.

##  Fix
* Added explicit `using System.Drawing;`.
* Added `stream.Seek(0);` right before `Image.FromStream(...)` to rewind
the stream to the beginning.

```csharp
using System.Drawing;   // new
...
page.RenderToStreamAsync(...).GetAwaiter().GetResult();
stream.Seek(0);         // rewind so Image.FromStream reads data
imageOfPage = Image.FromStream(stream.AsStream());
```
## Testing

- Rebuilt the solution – compilation succeeds without missing-namespace
errors.
- Ran thumbnail handler against multiple PDFs; thumbnails now render
correctly and no runtime exceptions are thrown.

## Impact
Users regain reliable PDF thumbnail previews in Explorer, improving
usability and preventing crashes or blank icons.

---------

Co-authored-by: leileizhang <leilzh@microsoft.com>
2025-06-17 14:24:52 +08:00
Leilei Zhang
4f209235af Merge branch 'main' of https://github.com/microsoft/PowerToys into leilzh/testing 2025-06-17 12:52:33 +08:00
Leonardo Farias Bona
bdedc02ea5 [CropAndLock] theme (#38044)
## Summary of the Pull Request

Theme aware cropped windows.

## PR Checklist
- [x] **Closes:** #28348
- [ ] **Communication:** I've discussed this with core contributors
already. If work hasn't been agreed, this work might be rejected
- [ ] **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

## Detailed Description of the Pull Request / Additional comments

Added a Theme aware implementation that was already found on other
components, the only difference is that we are dealing with multiple
windows.
It will follow the Power Toys application theme, (windows too in case
PowerToys follows the System).
I decided to change the scope of a variable to not create a second
control of croppedWindows, this may need to be taken into consideration.

## Validation Steps Performed

Using Crop (Win + Ctrl + Shift +R)
Crop one or multiple windows.
All of them have the same theme as the application.
Went to windows theme settings, change to light theme, the app changes
accordingly.

Same behavior was tested with Thumbnail (Win  + Ctrl + Shift + T)

Closing windows and changing the theme again.
2025-06-17 11:49:31 +08:00
Heiko
b2d7182dcd [RegPreview] Various improvements on how files are saved (#37628)
<!-- 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

### This PR implements various fixes and improvements into
RegistryPreview for saving files:
1. Adds an unsaved file indicator in the title bar like in Notepad. (As
indicator we show the * character before the file title.)
2. The save button behaves like a "save as" button, if the file does not
exist on disk like in Notepad. (Without fix when running as non-admin
you get an access denied error message.)
3. If the app gets closed without saving and the file does not exist on
disk, then the user is now asked for the path. (Fixes crash on clicking
save button while closing the app.)
4. Failed save actions are handled now correctly on dirty closing,
opening files and all other actions that require saving the current
state. They will stop the process.
5. A fix for an incorrect enabled state of the save button after
opening, reloading and saving a file.
6. Reuse file name on save as button, if known. Otherwise use "new file"
template name like in Notepad.
7. Fix an app crash if you click the window's close button a second time
while the "Should save?" dialog is opened.
8. Added an reload dialog in case of unsaved changes.


![image](https://github.com/user-attachments/assets/9045446e-e9a3-4b81-8aa0-515b0821a969)


![image](https://github.com/user-attachments/assets/0888fbd2-851b-4101-a177-be9a3675b5ae)


<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist

- [x] **Closes:** #36876, #36875
- [x] **Communication:** I've discussed this with core contributors
already. If work hasn't been agreed, this work might be rejected
- [x] **Tests:** Added/updated and all pass
- [x] **Localization:** All end user facing strings can be localized
- [ ] **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

<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed

Local test build.

---------

Co-authored-by: Gordon Lam (SH) <yeelam@microsoft.com>
2025-06-17 11:35:35 +08:00
Heiko
82e9d42e02 [CmdPal > Tiem & Date] Fix missing command of FallbackItem (#40048)
<!-- 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

The fallback items of Time & Date plugin missing the command. This PR
add the missing copy command.

<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist

- [x] **Closes:** #40029
- [x] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [ ] **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

<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
2025-06-17 00:20:47 +08:00
Leilei Zhang
012fd0eb8b update more version 2025-06-16 20:58:05 +08:00
Leilei Zhang
041cdc57dc add more version 2025-06-16 18:43:55 +08:00
Leilei Zhang
3bf0c04ad5 update NOTICE.md 2025-06-16 17:46:58 +08:00
Jiří Polášek
74d92df078 Add 'Restart Windows Explorer' command, implemented using Restart Manager (#39258)
<!-- Enter a brief description/summary of your PR here. What does it
fix/what does it change/how was it tested (even manually, if necessary)?
-->
## Summary of the Pull Request
- Adds a new **"Restart Windows Explorer"** command to the **"Windows
System Commands"** provider
- Implemented using **Restart Manager** to allow restoring previously
opened Explorer windows after restart
- This depends on the *"Restore previous folder windows at logon"*
option in File Explorer Options
- An explicit timeout was added for terminating processes, since Restart
Manager uses very long timeouts 😴
- The shell process name (`explorer`) is hardcoded  
- The command attempts to terminate all `explorer` processes
indiscriminately
- Execution requires confirmation (if enabled in settings)


![image](https://github.com/user-attachments/assets/a9a955d5-a52b-4a57-bcb1-85293362c17a)


<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist

- [ ] **Closes:** #39213 
- [ ] **Communication:** I've discussed this with core contributors
already. If work hasn't been agreed, this work might be rejected
- [ ] **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

<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
2025-06-16 17:21:21 +08:00
Leilei Zhang
c2975dfe55 update all version 2025-06-16 17:00:12 +08:00
Heiko
2255106a78 [CmdPal > Time&Date] Fix outdated result (#40050)
<!-- 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

The results in Time&Date ext are cached. This leads to outdated results
and makes no sense for a time/date query.
The PR fixes this.

<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist

- [x] **Closes:** #39973 
- [x] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [ ] **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

<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
2025-06-16 16:46:51 +08:00
Leilei Zhang
e53961c30b update version 2025-06-16 15:19:30 +08:00
leileizhang
2ade73834d [CmdPal]Integrate versioning into the CalculatorEngineCommon project (#40059)
<!-- 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

Add a version project reference to the CalculatorEngineCommon project to
integrate versioning support.

<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist

- [ ] **Closes:** #xxx
- [ ] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [ ] **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

<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
2025-06-16 15:12:17 +08:00
Gordon Lam
ecfc9e9ab2 Fix Build Warning on Host (#40027)
<!-- 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
Fixed build warnings WMC1510 in `HostsMainPage.xaml` that were
preventing proper AOT (Ahead-of-Time) compilation compatibility for XAML
data bindings.
### Problem
The Hosts module was generating multiple WMC1510 warnings during build:
```
src\modules\Hosts\HostsUILib\HostsMainPage.xaml(614,13): Warning WMC1510: Ensure the property path is trimming and AOT compatible by making use of 'Compiled Bindings (x:bind)' if possible or by specifying the 'x:DataType' directive...
```

These warnings occurred on 6 different binding expressions in the
EntryDialog ContentDialog that bound to properties of the `Entry` model
class.

### Solution
Applied the recommended fix by adding proper type information for the
XAML compiler:

1. **Added `x:DataType="models:Entry"`** to the ContentDialog element to
specify the binding context type
2. **Added `[Bindable]` attribute** to the Entry model class to ensure
WinRT compatibility

### Changes Made
- **HostsMainPage.xaml**: Added `x:DataType="models:Entry"` attribute to
the EntryDialog ContentDialog
- **Entry.cs**: Added `[Bindable]` attribute and `using
Microsoft.UI.Xaml.Data;` directive

<!-- 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
-  Resolves all 6 WMC1510 warnings in the specified lines
-  Ensures AOT compilation compatibility
-  No functional changes to UI behavior
-  Minimal code changes (3 lines total)
-  Follows Microsoft's recommended approach for WinRT data binding

The fix enables proper trimming and AOT compilation while maintaining
all existing functionality.

<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Try to build and run locally without problem.
2025-06-16 14:13:16 +08:00
PesBandi
3afaa18343 [Hosts]Add learn more link to warning dialog (#39946)
## Summary of the Pull Request
Adds a *Learn more* link pointing
[here](https://aka.ms/PowerToysOverview_HostsFileEditor) (the same as in
the settings) to the warning dialog that shows up when Hosts File Editor
starts
## PR Checklist
- [x] **Closes:** #39859
- [ ] **Communication:** I've discussed this with core contributors
already. If work hasn't been agreed, this work might be rejected
- [ ] **Tests:** Added/updated and all pass
- [x] **Localization:** All end user facing strings can be localized
- [x] **Dev docs:** No need
- [x] **New binaries:** None
- [x] **Documentation updated:** No need
## Detailed Description of the Pull Request / Additional comments

![Image](https://github.com/user-attachments/assets/f26c4fc9-fc3f-45d1-9976-77295b524b97)
<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
Tested the UI manually
2025-06-16 14:08:29 +08:00
Leilei Zhang
821f0b7aa7 Merge branch 'main' of https://github.com/microsoft/PowerToys into alzollin/actionsInvoke 2025-06-16 13:59:01 +08:00
leileizhang
fa111538ae Fix Peek always showing warning message by updating IsWarningMessageVisible logic (#40056)
<!-- 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
This PR fixes an issue where the warning message in Peek was always
displayed, even when not applicable.

**Root cause**
When non-video files were triggered, the logic did not call
`IsWarningMessageVisible(string? missingCodecName)`
as expected. As a result, the default UI state caused the warning
message to always appear.

**Fix**
Updated the method signature and call sites to:
`public Visibility IsWarningMessageVisible(IPreviewer? previewer,
PreviewState? state)`
This ensures that the logic is consistently triggered across different
preview handlers and has access to the necessary context to determine
whether the warning message should be shown.

<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist

- [ ] **Closes:** #xxx
- [ ] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [ ] **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

<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
2025-06-16 13:39:56 +08:00
Yu Leng
be68bfd3ab [CmdPal][AOT] Fix fontIcon issue when build with AOT (#40058)
<!-- 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
FontIcon will be trimmed, we need to create a rd.xml to keep them.

<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist

- [x] **Closes:** #40057
- [x] **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

<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed

Co-authored-by: Yu Leng <yuleng@microsoft.com>
2025-06-16 13:37:00 +08:00
leileizhang
790676844d [S360] Revert "[CmdPal][AOT] Replace CommunityToolkit.MarkdownTextBlock with CommunityToolkit.Lab.MarkdownTextBlock (#39974)" (#40055)
This reverts commit 7d257cf00c due to a
security concern involving multiple feeds

<!-- 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

<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist

- [ ] **Closes:** #xxx
- [ ] **Communication:** I've discussed this with core contributors
already. If the work hasn't been agreed, this work might be rejected
- [ ] **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

<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
2025-06-16 13:31:27 +08:00
PesBandi
64ad9b56ad [CmdPal][Apps]Add copy path command (#39984)
## Summary of the Pull Request
Adds a *Copy path* command to the <kbd>Ctrl</kbd>+<kbd>K</kbd> menu in
the All apps extension
## PR Checklist
- [x] **Closes:** #39500 (as mentioned in the discussion, the other
requests will be tracked over in #39501)
- [x] **Communication:** I've discussed this with core contributors
already + has Help wanted
- [x] **Tests:** All pass
- [x] **Localization:** All end user facing strings can be localized
- [x] **Dev docs:** No need
- [x] **New binaries:** None
- [x] **Documentation updated:** No need
## Detailed Description of the Pull Request / Additional comments
Copies the exe full path for standard programs. Copies the package
directory for UWPs.
Shows a *Copied to clipboard!* toast on a successful copy and closes.
Shows a toast when copying fails, keeps CmdPal open.

![image](https://github.com/user-attachments/assets/ad89a583-13c8-475c-973b-b0f5e7556e31)
## Validation Steps Performed
Manually tested copying for UWPs and Win32 programs
2025-06-16 12:10:50 +08:00
Leilei Zhang
512f55a481 unique the build version 2025-06-16 12:08:10 +08:00
Yu Leng
7d257cf00c [CmdPal][AOT] Replace CommunityToolkit.MarkdownTextBlock with CommunityToolkit.Lab.MarkdownTextBlock (#39974)
<!-- 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
Why?
The old library doesn't support native AOT. They implement the new one
but still in the lab project.
There are some breaking changes. So, seems we can not 100% to make it
align with the old version.

https://github.com/CommunityToolkit/Labs-Windows/tree/main/components/MarkdownTextBlock

compare:
old:

![image](https://github.com/user-attachments/assets/c2d20d1c-77b8-4bd5-a6e9-45ef30e90ea4)
new:

![image](https://github.com/user-attachments/assets/f65c1acd-ee91-491e-9efd-08ebd191dc58)

old:

![image](https://github.com/user-attachments/assets/129bee49-04c3-4667-88d8-b27718ccd51b)

![image](https://github.com/user-attachments/assets/10c6f845-13ce-4e6b-8fbf-017c8a654fa2)

![image](https://github.com/user-attachments/assets/6f95de3f-e6fb-43a8-9a81-487b20f97f23)

new:

![image](https://github.com/user-attachments/assets/f661731a-efc1-4ffd-86d1-f24cbbe3b9c3)

![image](https://github.com/user-attachments/assets/22cf3e24-f27b-4cef-8e80-352451323bb6)

![image](https://github.com/user-attachments/assets/46719831-905a-450e-b789-93bbedd418bd)

old:

![image](https://github.com/user-attachments/assets/3dd7713a-f5fa-4e1d-90a1-30a518b5df36)

new:

![image](https://github.com/user-attachments/assets/616a176f-a9aa-4f23-9f01-98b30a7c33c4)

old:

![image](https://github.com/user-attachments/assets/5758b51c-44a3-4748-9092-c827009ccc8e)

new:

![image](https://github.com/user-attachments/assets/8deed4cf-e87e-425f-b5a7-61dcab676e45)


<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist

- [ ] **Closes:** #xxx
- [ ] **Communication:** I've discussed this with core contributors
already. If work hasn't been agreed, this work might be rejected
- [ ] **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

<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed

---------

Co-authored-by: Yu Leng <yuleng@microsoft.com>
2025-06-16 08:36:45 +08:00
Leilei Zhang
c5c64767c1 Merge branch 'main' of https://github.com/microsoft/PowerToys into alzollin/actionsInvoke 2025-06-16 08:11:25 +08:00
Leilei Zhang
a40b7d23ff fix spelling 2025-06-15 20:14:52 +08:00
Leilei Zhang
b539c75240 fix cswin32 build error in peek 2025-06-15 20:03:52 +08:00
Clint Rutkas
106923db84 Moving chris to security org (#40038)
Chris, best of luck in security org :)
2025-06-13 21:02:59 +00:00
Davide Giacometti
6f68f5f34a [CmdPal] Fix and localize alias settings (#39708)
<!-- 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

Fixes alias settings and add localization for Direct/Indirect.


![Animation](https://github.com/user-attachments/assets/64780f64-f695-4e34-9b90-828ec456c6d3)

<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist

- [x] **Closes:** #39569
- [ ] **Communication:** I've discussed this with core contributors
already. If work hasn't been agreed, this work might be rejected
- [ ] **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

<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed

Manually tested
2025-06-13 19:58:33 +02:00
Davide Giacometti
aa8cfd505a [CmdPal] Close Gracefully (#39589)
<!-- 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

CmdPal is leaking extensions processes as the process is immediately
killed.
This PR fixes the 1.5s wait for the process to end correctly and also
close extensions.

<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist

- [ ] **Closes:** #xxx
- [ ] **Communication:** I've discussed this with core contributors
already. If work hasn't been agreed, this work might be rejected
- [ ] **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

<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed

- Verified that if CmdPal closes in 1.5s, extensions and process are
closed (note that GitHub extension doesn't close probably due to
https://github.com/microsoft/PowerToys/pull/39209)
- Verified that if CmdPal doesn't close in 1.5s the process is killed
and extensions aren't closed (tested adding a delay in the code)
2025-06-13 19:57:40 +02:00
Gordon Lam
349de60e47 Include all the Unittest as part of CI pipeline (#40024)
Include all the UnitTest as part of CI pipeline.

The results are promising:
a. All tests passed
b. No noticeable increase in execution time
c. Additional modules are now covered, including Settings, Color Picker,
Peek, Run V1, and others.
 
Here is all ~5000 Unittests - [Pipelines - Run PowerToys
CI_2506.12022](https://dev.azure.com/shine-oss/PowerToys/_build/results?buildId=133714&view=ms.vss-test-web.build-test-results-tab)
Here is the original ~3000 Unittests - [Pipelines - Run PowerToys
CI_2506.12021](https://dev.azure.com/shine-oss/PowerToys/_build/results?buildId=133677&view=ms.vss-test-web.build-test-results-tab)

Co-authored-by: Kai Tao <69313318+vanzue@users.noreply.github.com>
2025-06-13 08:59:25 -07:00
Heiko
abc5c3e249 [RegistryPreview] Extended preview for value data (#37689)
<!-- 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

Add a button to the data grid that shows a windows for complex value
preview.

### Screenshots
**Button**

![image](https://github.com/user-attachments/assets/bb275831-be6d-490c-9193-5df719ce6c39)

**Context menu** (Usefull on long data, if button is scrolled out of
view.)

![image](https://github.com/user-attachments/assets/f5fb07ef-6f73-4eac-a289-9dce1c610ceb)

**Preview: REG_SZ**

![image](https://github.com/user-attachments/assets/e03fbbc7-adaa-40d0-967c-7783b1a97b74)

**Preview: REG_MULTI_SZ**

![image](https://github.com/user-attachments/assets/717590a6-7d91-4c9c-8e94-d875a5d2ba6b)

**Preview: REG_EXPAND_SZ**

![image](https://github.com/user-attachments/assets/20135b66-528f-40e7-beed-adfc2b50313d)

**Preview: REG_DWORD and REG_QWORD**

![image](https://github.com/user-attachments/assets/b60110ab-bfc7-40e7-ada3-d278a62b9d01)

**Preview: REG_BINARY**

![image](https://github.com/user-attachments/assets/95f81036-6833-439e-8c01-b3a45c2d8edd)

![image](https://github.com/user-attachments/assets/ce237664-da96-4dbd-835f-969982560b9f)


<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist

- [x] **Closes:** #36877
- [x] **Communication:** I've discussed this with core contributors
already. If work hasn't been agreed, this work might be rejected
- [x] **Tests:** Added/updated and all pass
- [x] **Localization:** All end user facing strings can be localized =>
missing yet
- [ ] **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

Additionally this PR updates the context menu for values.

<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed

Tested code with a local build.
2025-06-13 18:08:01 +08:00
PesBandi
ce058f1dc7 [ColorPicker]Add option to choose what clicking individual mouse buttons does (#39025)
## Summary of the Pull Request
Enables the users to choose what left, right, and middle click does when
color picker is open.
<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist

- [x] **Closes:** #39006
- [x] **Communication:** I've discussed this with core contributors
already
- [x] **Tests:** All pass
- [x] **Localization:** All end user facing strings can be localized
- [x] **Dev docs:** No need
- [x] **New binaries:** None
- [x] **Documentation updated:** No need
## Detailed Description of the Pull Request / Additional comments
![Screenshot of the
settings](https://github.com/user-attachments/assets/a3e1349b-6bb9-4e2f-97f3-a5106a7d92ce)
Adds option to choose from 3 click behaviors for each standard mouse
button:
* **Pick color and open editor**: Copies color to clipboard, saves it to
the color history and opens the editor
* **Pick color and close**: Copies color to clipboard, saves it to the
color history and exits
* **Close**: Closes color picker without copying the color

Pressing <kbd>Enter</kbd> or <kbd>Space</kbd> does what clicking the
primary button would.
Left and middle click actions execute on mouse down, right click on
mouse up for reasons discussed previously (I can't find the conversation
now)
Default settings are chosen in such a way that very little or nothing
changes by updating.
## Validation Steps Performed
Tested:
* Migrating settings from v2.0 to v2.1 (v1 to v2.1 not tested)
* Settings page displays and saves settings correctly
* Default settings load correctly
* All three click actions do what they are supposed to
* Activation behavior works as expected, doesn't affect click actions
2025-06-13 18:01:40 +08:00
leileizhang
2d1676b7df [CmdPal][AOT] Using ExprTk to make the Cal extension AOT-compatible (#39972)
<!-- 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
This PR replaces the original Mages-based expression evaluation engine
with a WinRT-wrapped version of Exprtk in the CmdPalCalculator module.

### Key Changes
**Expression Engine:**

- All expression parsing and evaluation now use Exprtk (via a WinRT
wrapper) instead of Mages.

**Base Conversion Handling:**

- Since Exprtk does not support non-decimal (binary, octal, hexadecimal)
input natively, added logic to convert all such inputs to decimal before
evaluation.

**Code Structure:**

- The overall logic and API surface remain unchanged except for the
engine and base conversion handling.
- All previous Mages references and dependencies have been removed.

<!-- Please review the items on the PR checklist before submitting-->
## PR Checklist

- [ ] **Closes:** #xxx
- [ ] **Communication:** I've discussed this with core contributors
already. If work hasn't been agreed, this work might be rejected
- [ ] **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

<!-- Describe how you validated the behavior. Add automated tests
wherever possible, but list manual validation steps taken as well -->
## Validation Steps Performed
2025-06-13 12:27:53 +08:00
Alexandre Zollinger Chohfi
d168ae5b9b Added lock for UpdateMoreCommands. 2025-06-12 10:31:03 +08:00
Alexandre Zollinger Chohfi
1870fc31ee Update src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Indexer/Properties/Resources.resx
Co-authored-by: Mike Griese <migrie@microsoft.com>
2025-06-12 10:31:03 +08:00
Alexandre Zollinger Chohfi
54f7e1e123 Addressed PR Feedback. 2025-06-12 10:31:03 +08:00
Gordon Lam (SH)
39fa4c37d3 Rebased with main 2025-06-12 10:30:59 +08:00
150 changed files with 6429 additions and 442 deletions

View File

@@ -91,6 +91,7 @@ Hemmerlein
hlaueriksson
Horvalds
Howett
hotkidfamily
htcfreek
Huynh
Ionut
@@ -98,6 +99,7 @@ jamrobot
Jaswal
Jaylyn
jefflord
Jeremic
Jordi
jyuwono
kai
@@ -222,6 +224,7 @@ openai
Quickime
regedit
roslyn
Skia
Spotify
Vanara
wangyi

View File

@@ -126,3 +126,4 @@
^src/common/sysinternals/Eula/
^tools/Verification scripts/Check preview handler registration\.ps1$
ignore$
^src/modules/registrypreview/RegistryPreviewUILib/Controls/HexBox/.*$

View File

@@ -156,6 +156,7 @@ builttoroam
BVal
BValue
byapp
BYCOMMAND
BYPOSITION
CALCRECT
CALG
@@ -202,6 +203,7 @@ CLIPSIBLINGS
closesocket
clp
CLSCTX
CLSCTXLOCALSERVER
clsids
Clusion
cmder
@@ -815,6 +817,7 @@ LOCALDISPLAY
localpackage
LOCALSYSTEM
LOCATIONCHANGE
LOCKTYPE
LOGFONT
LOGFONTW
logon
@@ -910,6 +913,7 @@ metafile
mfc
Mgmt
Microwaved
middleclickaction
midl
mii
mindaro
@@ -1251,6 +1255,7 @@ prg
prgh
prgms
pri
primaryclickaction
PRINTCLIENT
printmanagement
prm
@@ -1426,6 +1431,7 @@ SDKDDK
sdns
searchterm
SEARCHUI
secondaryclickaction
SECONDARYDISPLAY
secpol
securestring
@@ -1510,6 +1516,7 @@ SICHINT
SIDs
siex
sigdn
Signedness
SIGNINGSCENARIO
signtool
SINGLEKEY
@@ -1659,6 +1666,7 @@ TDefault
TDevice
telephon
templatenamespace
TESTONLY
testprocess
TEXCOORD
TEXTBOXNEWLINE
@@ -1711,6 +1719,7 @@ trx
tsa
TSender
TServer
tskill
tstoi
TStr
tweakme

View File

@@ -41,6 +41,9 @@ Write-Output ""
Write-Output "Restoring dotnet tools..."
dotnet tool restore --disable-parallel --no-cache
# Use Regex syntax
$PathExcludes = "(\\obj\\)|(\\bin\\)|(\\x64\\)|(\\Generated Files\\PowerRenameXAML\\)|(\\RegistryPreviewUILib\\Controls\\HexBox\\)"
if (-not $Passive)
{
# Look for unstaged changed files by default
@@ -87,7 +90,7 @@ if (-not $Passive)
}
Write-Output "Running Git Diff: $gitDiffCommand"
$files = Invoke-Expression $gitDiffCommand | Select-String -Pattern "\.xaml$"
$files = Invoke-Expression $gitDiffCommand | Select-String -Pattern "\.xaml$" | Where-Object { $_ -notmatch $PathExcludes }
if (-not $Passive -and -not $Main -and -not $Unstaged -and -not $Staged -and -not $LastCommit)
{
@@ -107,7 +110,7 @@ if (-not $Passive)
else
{
Write-Output "Checking all files (passively)"
$files = Get-ChildItem -Path "$PSScriptRoot\..\src\*.xaml" -Recurse | Select-Object -ExpandProperty FullName | Where-Object { $_ -notmatch "(\\obj\\)|(\\bin\\)|(\\x64\\)|(\\Generated Files\\PowerRenameXAML\\)" }
$files = Get-ChildItem -Path "$PSScriptRoot\..\src\*.xaml" -Recurse | Select-Object -ExpandProperty FullName | Where-Object { $_ -notmatch $PathExcludes }
if ($files.count -gt 0)
{

View File

@@ -99,7 +99,7 @@ jobs:
${{ else }}:
OutputBuildPlatform: ${{ platform }}
variables:
MakeAppxPath: 'C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x86\MakeAppx.exe'
MakeAppxPath: 'C:\Program Files (x86)\Windows Kits\10\bin\10.0.26100.0\x86\MakeAppx.exe'
# Azure DevOps abhors a vacuum
# If these are blank, expansion will fail later on... which will result in direct substitution of the variable *names*
# later on. We'll just... set them to a single space and if we need to, check IsNullOrWhiteSpace.
@@ -332,6 +332,7 @@ jobs:
/p:VCRTForwarders-IncludeDebugCRT=false
/p:PowerToysRoot=$(Build.SourcesDirectory)
/p:PublishProfile=InstallationPublishProfile.pubxml
/p:TargetFramework=net9.0-windows10.0.26100.0
/bl:$(LogOutputDirectory)\publish-${{ join('_',split(project, '/')) }}.binlog
$(RestoreAdditionalProjectSourcesArg)
platform: $(BuildPlatform)
@@ -394,10 +395,7 @@ jobs:
testAssemblyVer2: |
**\KeyboardManagerEngineTest.dll
**\KeyboardManagerEditorTest.dll
**\UnitTests-CommonLib.dll
**\PowerRenameUnitTests.dll
**\UnitTests-FancyZones.dll
**\\WorkspacesLibUnitTests.dll
**\*UnitTest*.dll
!**\obj\**
- pwsh: |-

View File

@@ -28,6 +28,8 @@ $versionExceptions = @(
"ObjectModelCsProjection.dll",
"RendererCsProjection.dll") -join '|';
$nullVersionExceptions = @(
"SkiaSharp.Views.WinUI.Native.dll",
"libSkiaSharp.dll",
"codicon.ttf",
"e_sqlite3.dll",
"getfilesiginforedist.dll",

View File

@@ -9,6 +9,7 @@
"Microsoft.VisualStudio.Component.Windows10SDK.19041",
"Microsoft.VisualStudio.Component.Windows10SDK.20348",
"Microsoft.VisualStudio.Component.Windows10SDK.22621",
"Microsoft.VisualStudio.Component.Windows10SDK.26100",
"Microsoft.VisualStudio.ComponentGroup.UWP.VC",
"Microsoft.VisualStudio.Component.UWP.VC.ARM64",
"Microsoft.VisualStudio.Component.VC.Runtimes.ARM64.Spectre",

View File

@@ -181,7 +181,6 @@ ZoomIt source code was originally implemented by [Sysinternals](https://sysinter
## PowerToys core team
- [@cinnamon-msft](https://github.com/cinnamon-msft) - Kayla Cinnamon - Lead
- [@nguyen-dows](https://github.com/nguyen-dows) - Christopher Nguyen - Product Manager
- [@craigloewen-msft](https://github.com/craigloewen-msft) - Craig Loewen - Product Manager
- [@niels9001](https://github.com/niels9001/) - Niels Laute - Product Manager
- [@dhowett](https://github.com/dhowett) - Dustin Howett - Dev lead
@@ -213,6 +212,7 @@ ZoomIt source code was originally implemented by [Sysinternals](https://sysinter
- [@ethanfangg](https://github.com/ethanfangg) - Ethan Fang - Product Manager
- [@plante-msft](https://github.com/plante-msft) - Connor Plante - Product Manager
- [@joadoumie](https://github.com/joadoumie) - Jordi Adoumie - Product Manager
- [@nguyen-dows](https://github.com/nguyen-dows) - Christopher Nguyen - Product Manager
- [@enricogior](https://github.com/enricogior) - Enrico Giordani - Dev Lead
- [@bzoz](https://github.com/bzoz) - Bartosz Sosnowski - Dev
- [@ivan100sic](https://github.com/ivan100sic) - Ivan Stošić - Dev

View File

@@ -96,8 +96,8 @@
<!-- Global props OverrideWindowsTargetPlatformVersion-->
<PropertyGroup Label="Globals">
<WindowsTargetPlatformVersion>10.0.22621.0</WindowsTargetPlatformVersion>
<TargetPlatformVersion>10.0.22621.0</TargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0.26100.0</WindowsTargetPlatformVersion>
<TargetPlatformVersion>10.0.26100.0</TargetPlatformVersion>
<WindowsTargetPlatformMinVersion>10.0.19041.0</WindowsTargetPlatformMinVersion>
</PropertyGroup>

View File

@@ -47,14 +47,14 @@
<PackageVersion Include="Microsoft.Win32.SystemEvents" Version="9.0.6" />
<PackageVersion Include="Microsoft.WindowsPackageManager.ComInterop" Version="1.10.340" />
<PackageVersion Include="Microsoft.Windows.Compatibility" Version="9.0.6" />
<PackageVersion Include="Microsoft.Windows.CsWin32" Version="0.2.46-beta" />
<PackageVersion Include="Microsoft.Windows.CsWin32" Version="0.3.183" />
<!-- CsWinRT version needs to be set to have a WinRT.Runtime.dll at the same version contained inside the NET SDK we're currently building on CI. -->
<!--
TODO: in Common.Dotnet.CsWinRT.props, on upgrade, verify RemoveCsWinRTPackageAnalyzer is no longer needed.
This is present due to a bug in CsWinRT where WPF projects cause the analyzer to fail.
-->
<PackageVersion Include="Microsoft.Windows.CsWinRT" Version="2.2.0" />
<PackageVersion Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22621.2428" />
<PackageVersion Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.4188" />
<PackageVersion Include="Microsoft.WindowsAppSDK" Version="1.7.250513003" />
<PackageVersion Include="Microsoft.Xaml.Behaviors.WinUI.Managed" Version="2.0.9" />
<PackageVersion Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.39" />
@@ -69,6 +69,8 @@
<PackageVersion Include="ReverseMarkdown" Version="4.1.0" />
<PackageVersion Include="ScipBe.Common.Office.OneNote" Version="3.0.1" />
<PackageVersion Include="SharpCompress" Version="0.37.2" />
<!-- Don't update SkiaSharp.Views.WinUI to version 3.* branch as this brakes the HexBox control in Registry Preview. -->
<PackageVersion Include="SkiaSharp.Views.WinUI" Version="2.88.9" />
<PackageVersion Include="StreamJsonRpc" Version="2.21.69" />
<PackageVersion Include="StyleCop.Analyzers" Version="1.2.0-beta.556" />
<!-- Package System.CodeDom added as a hack for being able to exclude the runtime assets so they don't conflict with 8.0.1. This is a dependency of System.Management but the 8.0.1 version wasn't published to nuget. -->

View File

@@ -1427,6 +1427,37 @@ EXHIBIT A -Mozilla Public License.
## Utility: Registry Preview
### HexBox.WinUI
We use HexBox.WinUI to show a preview of binary values.
**Source**: https://github.com/hotkidfamily/HexBox.WinUI
```
MIT License
Copyright (c) 2019 Filip Jeremic
Copyright (c) 2024~2025 hotkidfamily@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
```
### Monaco Editor
**Source**: https://github.com/Microsoft/monaco-editor
@@ -1457,6 +1488,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
```
## NuGet Packages used by PowerToys
- AdaptiveCards.ObjectModel.WinUI3 2.0.0-beta
@@ -1501,9 +1533,9 @@ SOFTWARE.
- Microsoft.Web.WebView2 1.0.2903.40
- Microsoft.Win32.SystemEvents 9.0.6
- Microsoft.Windows.Compatibility 9.0.6
- Microsoft.Windows.CsWin32 0.2.46-beta
- Microsoft.Windows.CsWin32 0.3.183
- Microsoft.Windows.CsWinRT 2.2.0
- Microsoft.Windows.SDK.BuildTools 10.0.22621.2428
- Microsoft.Windows.SDK.BuildTools 10.0.26100.4188
- Microsoft.WindowsAppSDK 1.7.250513003
- Microsoft.WindowsPackageManager.ComInterop 1.10.340
- Microsoft.Xaml.Behaviors.WinUI.Managed 2.0.9
@@ -1517,6 +1549,7 @@ SOFTWARE.
- ReverseMarkdown 4.1.0
- ScipBe.Common.Office.OneNote 3.0.1
- SharpCompress 0.37.2
- SkiaSharp.Views.WinUI 2.88.9
- StreamJsonRpc 2.21.69
- StyleCop.Analyzers 1.2.0-beta.556
- System.CodeDom 9.0.6

View File

@@ -8,10 +8,10 @@ SET VCToolsVersion=!VCToolsVersion!
SET ClearDevCommandPromptEnvVars=false
rem In case of Release we should not use Debug CRT in VCRT forwarders
msbuild !PTRoot!\src\modules\previewpane\MonacoPreviewHandler\MonacoPreviewHandler.csproj -t:Publish -p:Configuration="Release" -p:Platform="!PlatformArg!" -p:AppxBundle=Never -p:PowerToysRoot=!PTRoot! -p:VCRTForwarders-IncludeDebugCRT=false -p:PublishProfile=InstallationPublishProfile.pubxml
msbuild !PTRoot!\src\modules\previewpane\MonacoPreviewHandler\MonacoPreviewHandler.csproj -t:Publish -p:Configuration="Release" -p:Platform="!PlatformArg!" -p:AppxBundle=Never -p:PowerToysRoot=!PTRoot! -p:VCRTForwarders-IncludeDebugCRT=false -p:PublishProfile=InstallationPublishProfile.pubxml -p:TargetFramework=net9.0-windows10.0.26100.0
msbuild !PTRoot!\src\modules\previewpane\MarkdownPreviewHandler\MarkdownPreviewHandler.csproj -t:Publish -p:Configuration="Release" -p:Platform="!PlatformArg!" -p:AppxBundle=Never -p:PowerToysRoot=!PTRoot! -p:VCRTForwarders-IncludeDebugCRT=false -p:PublishProfile=InstallationPublishProfile.pubxml
msbuild !PTRoot!\src\modules\previewpane\MarkdownPreviewHandler\MarkdownPreviewHandler.csproj -t:Publish -p:Configuration="Release" -p:Platform="!PlatformArg!" -p:AppxBundle=Never -p:PowerToysRoot=!PTRoot! -p:VCRTForwarders-IncludeDebugCRT=false -p:PublishProfile=InstallationPublishProfile.pubxml -p:TargetFramework=net9.0-windows10.0.26100.0
msbuild !PTRoot!\src\modules\previewpane\SvgPreviewHandler\SvgPreviewHandler.csproj -t:Publish -p:Configuration="Release" -p:Platform="!PlatformArg!" -p:AppxBundle=Never -p:PowerToysRoot=!PTRoot! -p:VCRTForwarders-IncludeDebugCRT=false -p:PublishProfile=InstallationPublishProfile.pubxml
msbuild !PTRoot!\src\modules\previewpane\SvgPreviewHandler\SvgPreviewHandler.csproj -t:Publish -p:Configuration="Release" -p:Platform="!PlatformArg!" -p:AppxBundle=Never -p:PowerToysRoot=!PTRoot! -p:VCRTForwarders-IncludeDebugCRT=false -p:PublishProfile=InstallationPublishProfile.pubxml -p:TargetFramework=net9.0-windows10.0.26100.0
msbuild !PTRoot!\src\modules\previewpane\SvgThumbnailProvider\SvgThumbnailProvider.csproj -t:Publish -p:Configuration="Release" -p:Platform="!PlatformArg!" -p:AppxBundle=Never -p:PowerToysRoot=!PTRoot! -p:VCRTForwarders-IncludeDebugCRT=false -p:PublishProfile=InstallationPublishProfile.pubxml
msbuild !PTRoot!\src\modules\previewpane\SvgThumbnailProvider\SvgThumbnailProvider.csproj -t:Publish -p:Configuration="Release" -p:Platform="!PlatformArg!" -p:AppxBundle=Never -p:PowerToysRoot=!PTRoot! -p:VCRTForwarders-IncludeDebugCRT=false -p:PublishProfile=InstallationPublishProfile.pubxml -p:TargetFramework=net9.0-windows10.0.26100.0

View File

@@ -4,8 +4,8 @@
<Import Project=".\Common.Dotnet.PrepareGeneratedFolder.targets" />
<PropertyGroup>
<WindowsSdkPackageVersion>10.0.22621.57</WindowsSdkPackageVersion>
<TargetFramework>net9.0-windows10.0.22621.0</TargetFramework>
<WindowsSdkPackageVersion>10.0.26100.68-preview</WindowsSdkPackageVersion>
<TargetFramework>net9.0-windows10.0.26100.0</TargetFramework>
<TargetPlatformMinVersion>10.0.19041.0</TargetPlatformMinVersion>
<SupportedOSPlatformVersion>10.0.19041.0</SupportedOSPlatformVersion>
<RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers>

View File

@@ -76,3 +76,47 @@ using System.Diagnostics.CodeAnalysis;
[assembly: SuppressMessage("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", "MVVMTK0049:Using [INotifyPropertyChanged] is not AOT compatible for WinRT", Justification = "Updated MVVM toolkit package introduced this.", Scope = "namespaceanddescendants", Target = "Peek.FilePreviewer")]
[assembly: SuppressMessage("CommunityToolkit.Mvvm.SourceGenerators.INotifyPropertyChangedGenerator", "MVVMTK0049:Using [INotifyPropertyChanged] is not AOT compatible for WinRT", Justification = "Updated MVVM toolkit package introduced this.", Scope = "type", Target = "~T:Peek.UI.Views.TitleBar")]
[assembly: SuppressMessage("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", "MVVMTK0049:Using [INotifyPropertyChanged] is not AOT compatible for WinRT", Justification = "Updated MVVM toolkit package introduced this.", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib")]
// HexBox control in RegistryPreviewUILib (We decided to copy the original code and not fix all theses problems for easier updating.)
[assembly: SuppressMessage("Design", "CA1001:Types that own disposable fields should be disposable", Justification = "<Code port with style preservation>", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
[assembly: SuppressMessage("Design", "CA1051:Do not declare visible instance fields", Justification = "<Code port with style preservation>", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
[assembly: SuppressMessage("Globalization", "CA1305:Specify IFormatProvider", Justification = "<Code port with style preservation>", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
[assembly: SuppressMessage("Naming", "CA1720:Identifiers should not contain type names", Justification = "<Code port with style preservation>", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
[assembly: SuppressMessage("Performance", "CA1805:Do not initialize unnecessarily", Justification = "<Code port with style preservation>", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1623:Property summary documentation should match accessors", Justification = "<Code port with style preservation>", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1642:Constructor summary documentation should begin with standard text", Justification = "<Code port with style preservation>", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1648:<inheritdoc> has been used on an element that doesn't inherit from a base class or implement an interface.", Justification = "<Code port with style preservation>", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1649:File name should match first type name", Justification = "<Code port with style preservation>", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1500:Braces for multi-line statements should not share line", Justification = "<Code port with style preservation>", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1502:Element should not be on a single line", Justification = "<Code port with style preservation>", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1503:Braces should not be omitted", Justification = "<Code port with style preservation>", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "<Code port with style preservation>", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1507:Code should not contain multiple blank lines in a row", Justification = "<Code port with style preservation>", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1508:Closing braces should not be preceded by blank line", Justification = "<Code port with style preservation>", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1509:Opening braces should not be preceded by blank line", Justification = "<Code port with style preservation>", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1512:Single-line comments should not be followed by blank line", Justification = "<Code port with style preservation>", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1513:Closing brace should be followed by blank line", Justification = "<Code port with style preservation>", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1514:Element documentation header should be preceded by blank line", Justification = "<Code port with style preservation>", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1515:Single-line comment should be preceded by blank line", Justification = "<Code port with style preservation>", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1516:Elements should be separated by blank line", Justification = "<Code port with style preservation>", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1119:Statement should not use unnecessary parenthesis", Justification = "<Code port with style preservation>", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "<Code port with style preservation>", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:File may only contain a single type", Justification = "<Code port with style preservation>", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1407:Arithmetic expressions should declare precedence", Justification = "<Code port with style preservation>", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1413:Use trailing comma in multi-line initializers", Justification = "<Code port with style preservation>", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
[assembly: SuppressMessage("StyleCop.CSharp.NamingRules", "SA1300:Element should begin with upper-case letter", Justification = "<Code port with style preservation>", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
[assembly: SuppressMessage("StyleCop.CSharp.NamingRules", "SA1306:Field names should begin with lower-case letter", Justification = "<Code port with style preservation>", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
[assembly: SuppressMessage("StyleCop.CSharp.NamingRules", "SA1312:Variable names should begin with lower-case letter", Justification = "<Code port with style preservation>", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
[assembly: SuppressMessage("StyleCop.CSharp.NamingRules", "SA1313:Parameter names should begin with lower-case letter", Justification = "<Code port with style preservation>", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
[assembly: SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1200:Using directives should be placed correctly", Justification = "<Code port with style preservation>", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1108:Block statements should not contain embedded comments", Justification = "<Code port with style preservation>", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1116:Split parameters should start on line after declaration", Justification = "<Code port with style preservation>", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1117:Parameters should be on same line or separate lines", Justification = "<Code port with style preservation>", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1129:Do not use default value type constructor", Justification = "<Code port with style preservation>", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
[assembly: SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "<Code port with style preservation>", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
[assembly: SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "<Code port with style preservation>", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
[assembly: SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1005:Single line comments should begin with single space", Justification = "<Code port with style preservation>", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
[assembly: SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1024:Colons Should Be Spaced Correctly", Justification = "<Code port with style preservation>", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
[assembly: SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1025:Code should not contain multiple whitespace in a row", Justification = "<Code port with style preservation>", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
[assembly: SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1028:Code should not contain trailing whitespace", Justification = "<Code port with style preservation>", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
[assembly: SuppressMessage("Usage", "CsWinRT1028:Class is not marked partial", Justification = "<Code port with style preservation>", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]

View File

@@ -0,0 +1,36 @@
#include <windows.h>
#include "resource.h"
#include "../version/version.h"
1 VERSIONINFO
FILEVERSION FILE_VERSION
PRODUCTVERSION PRODUCT_VERSION
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
#ifdef _DEBUG
FILEFLAGS VS_FF_DEBUG
#else
FILEFLAGS 0x0L
#endif
FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_DLL
FILESUBTYPE VFT2_UNKNOWN
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0" // US English (0x0409), Unicode (0x04B0) charset
BEGIN
VALUE "CompanyName", COMPANY_NAME
VALUE "FileDescription", FILE_DESCRIPTION
VALUE "FileVersion", FILE_VERSION_STRING
VALUE "InternalName", INTERNAL_NAME
VALUE "LegalCopyright", COPYRIGHT_NOTE
VALUE "OriginalFilename", ORIGINAL_FILENAME
VALUE "ProductName", PRODUCT_NAME
VALUE "ProductVersion", PRODUCT_VERSION_STRING
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200 // US English (0x0409), Unicode (1200) charset
END
END

View File

@@ -98,6 +98,11 @@
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ProjectReference Include="..\version\version.vcxproj">
<Project>{cc6e41ac-8174-4e8a-8d22-85dd7f4851df}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ClInclude Include="ExprtkEvaluator.h" />
<ClInclude Include="pch.h" />
@@ -105,6 +110,7 @@
<ClInclude Include="Calculator.h">
<DependentUpon>Calculator.idl</DependentUpon>
</ClInclude>
<ClInclude Include="resource.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="ExprtkEvaluator.cpp">
@@ -128,6 +134,9 @@
<ItemGroup>
<None Include="PropertySheet.props" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="CalculatorEngineCommon.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<Import Project="..\..\..\deps\spdlog.props" />
<ImportGroup Label="ExtensionTargets">

View File

@@ -0,0 +1,13 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by CalculatorEngineCommon.rc
//////////////////////////////
// Non-localizable
#define FILE_DESCRIPTION "CalculatorEngineCommon"
#define INTERNAL_NAME "CalculatorEngineCommon"
#define ORIGINAL_FILENAME "CalculatorEngineCommon.dll"
// Non-localizable
//////////////////////////////

View File

@@ -10,7 +10,7 @@
<ProjectGuid>{f5e1146e-b7b3-4e11-85fd-270a500bd78c}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>CropAndLock</RootNamespace>
<WindowsTargetPlatformVersion Condition=" '$(WindowsTargetPlatformVersion)' == '' ">10.0.22621.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion Condition=" '$(WindowsTargetPlatformVersion)' == '' ">10.0.26100.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformMinVersion>10.0.19041.0</WindowsTargetPlatformMinVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
@@ -154,6 +154,9 @@
<ProjectReference Include="..\..\..\common\Telemetry\EtwTrace\EtwTrace.vcxproj">
<Project>{8f021b46-362b-485c-bfba-ccf83e820cbd}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\common\Themes\Themes.vcxproj">
<Project>{98537082-0fdb-40de-abd8-0dc5a4269bab}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<Import Project="..\..\..\..\deps\spdlog.props" />

View File

@@ -17,6 +17,9 @@
#include <common/Telemetry/EtwTrace/EtwTrace.h>
#include <common/Themes/theme_helpers.h>
#include <common/Themes/theme_listener.h>
#pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
namespace winrt
@@ -35,6 +38,23 @@ namespace util
const std::wstring instanceMutexName = L"Local\\PowerToys_CropAndLock_InstanceMutex";
bool m_running = true;
// Theming
ThemeListener theme_listener{};
// Keep a list of our cropped windows
std::vector<std::shared_ptr<CropAndLockWindow>> croppedWindows;
void handleTheme()
{
auto theme = theme_listener.AppTheme;
auto isDark = theme == Theme::Dark;
Logger::info(L"Theme is now {}", isDark ? L"Dark" : L"Light");
for (auto&& croppedWindow : croppedWindows)
{
ThemeHelpers::SetImmersiveDarkMode(croppedWindow->Handle(), isDark);
}
}
int WINAPI wWinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ PWSTR lpCmdLine, _In_ int)
{
// Initialize COM
@@ -42,6 +62,8 @@ int WINAPI wWinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ PWSTR lpCmdLine, _I
Trace::CropAndLock::RegisterProvider();
theme_listener.AddChangedHandler(handleTheme);
Shared::Trace::ETWTrace trace;
trace.UpdateState(true);
@@ -107,8 +129,6 @@ int WINAPI wWinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ PWSTR lpCmdLine, _I
// Create our overlay window
std::unique_ptr<OverlayWindow> overlayWindow;
// Keep a list of our cropped windows
std::vector<std::shared_ptr<CropAndLockWindow>> croppedWindows;
// Handles and thread for the events sent from runner
HANDLE m_reparent_event_handle;
@@ -167,6 +187,7 @@ int WINAPI wWinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ PWSTR lpCmdLine, _I
croppedWindow->CropAndLock(targetWindow, cropRect);
croppedWindow->OnClosed(removeWindowCallback);
croppedWindows.push_back(croppedWindow);
handleTheme();
};
overlayWindow.reset();

View File

@@ -5,7 +5,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<PublishProtocol>FileSystem</PublishProtocol>
<TargetFramework>net9.0-windows10.0.22621.0</TargetFramework>
<TargetFramework>net9.0-windows10.0.26100.0</TargetFramework>
<TargetPlatformMinVersion>10.0.19041.0</TargetPlatformMinVersion>
<SupportedOSPlatformVersion>10.0.19041.0</SupportedOSPlatformVersion>
<PublishDir>$(PowerToysRoot)\$(Platform)\$(Configuration)\WinUI3Apps</PublishDir>

View File

@@ -6,6 +6,7 @@
<PropertyGroup>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<DefineConstants>TESTONLY</DefineConstants>
</PropertyGroup>
<PropertyGroup>

View File

@@ -611,6 +611,7 @@
<ContentDialog
x:Name="EntryDialog"
x:Uid="EntryDialog"
x:DataType="models:Entry"
IsPrimaryButtonEnabled="{Binding Valid, Mode=OneWay}"
Loaded="ContentDialog_Loaded_ApplyMargin"
PrimaryButtonStyle="{StaticResource AccentButtonStyle}">

View File

@@ -139,10 +139,23 @@ namespace HostsUILib.Views
dialog.XamlRoot = XamlRoot;
dialog.Style = Application.Current.Resources["DefaultContentDialogStyle"] as Style;
dialog.Title = resourceLoader.GetString("WarningDialog_Title");
dialog.Content = new TextBlock
dialog.Content = new StackPanel
{
Text = resourceLoader.GetString("WarningDialog_Text"),
TextWrapping = TextWrapping.Wrap,
Children =
{
new TextBlock
{
Text = resourceLoader.GetString("WarningDialog_Text"),
TextWrapping = TextWrapping.Wrap,
},
new HyperlinkButton
{
Content = resourceLoader.GetString("WarningDialog_LearnMore"),
NavigateUri = new Uri("https://aka.ms/PowerToysOverview_HostsFileEditor"),
Padding = new Thickness(0),
Margin = new Thickness(0, 5, 0, 5),
},
},
};
dialog.PrimaryButtonText = resourceLoader.GetString("WarningDialog_AcceptBtn");
dialog.PrimaryButtonStyle = Application.Current.Resources["AccentButtonStyle"] as Style;

View File

@@ -11,6 +11,9 @@ using HostsUILib.Helpers;
namespace HostsUILib.Models
{
#if !TESTONLY
[Microsoft.UI.Xaml.Data.Bindable]
#endif
public partial class Entry : ObservableObject
{
private static readonly char[] _spaceCharacters = new char[] { ' ', '\t' };

View File

@@ -331,6 +331,9 @@
<data name="WarningDialog_Title" xml:space="preserve">
<value>Warning</value>
</data>
<data name="WarningDialog_LearnMore" xml:space="preserve">
<value>Learn more</value>
</data>
<data name="WindowAdminTitle" xml:space="preserve">
<value>Administrator: Hosts File Editor</value>
<comment>Title of the window when running as administrator. "Hosts File Editor" is the name of the utility. "Hosts" refers to the system hosts file, do not loc</comment>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.1.7.250513003\build\native\Microsoft.WindowsAppSDK.props" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.1.7.250513003\build\native\Microsoft.WindowsAppSDK.props')" />
<Import Project="..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22621.2428\build\Microsoft.Windows.SDK.BuildTools.props" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22621.2428\build\Microsoft.Windows.SDK.BuildTools.props')" />
<Import Project="..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.26100.4188\build\Microsoft.Windows.SDK.BuildTools.props" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.26100.4188\build\Microsoft.Windows.SDK.BuildTools.props')" />
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.props')" />
<PropertyGroup Label="Globals">
<CppWinRTOptimized>true</CppWinRTOptimized>
@@ -139,7 +139,7 @@
<ImportGroup Label="ExtensionTargets">
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.targets')" />
<Import Project="..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
<Import Project="..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22621.2428\build\Microsoft.Windows.SDK.BuildTools.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22621.2428\build\Microsoft.Windows.SDK.BuildTools.targets')" />
<Import Project="..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.26100.4188\build\Microsoft.Windows.SDK.BuildTools.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.26100.4188\build\Microsoft.Windows.SDK.BuildTools.targets')" />
<Import Project="..\..\..\..\packages\Microsoft.Web.WebView2.1.0.2903.40\build\native\Microsoft.Web.WebView2.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Web.WebView2.1.0.2903.40\build\native\Microsoft.Web.WebView2.targets')" />
<Import Project="..\..\..\..\packages\Microsoft.WindowsAppSDK.1.7.250513003\build\native\Microsoft.WindowsAppSDK.targets" Condition="Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.1.7.250513003\build\native\Microsoft.WindowsAppSDK.targets')" />
</ImportGroup>
@@ -150,8 +150,8 @@
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.props'))" />
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.targets'))" />
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22621.2428\build\Microsoft.Windows.SDK.BuildTools.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22621.2428\build\Microsoft.Windows.SDK.BuildTools.props'))" />
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22621.2428\build\Microsoft.Windows.SDK.BuildTools.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.22621.2428\build\Microsoft.Windows.SDK.BuildTools.targets'))" />
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.26100.4188\build\Microsoft.Windows.SDK.BuildTools.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.26100.4188\build\Microsoft.Windows.SDK.BuildTools.props'))" />
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.26100.4188\build\Microsoft.Windows.SDK.BuildTools.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.SDK.BuildTools.10.0.26100.4188\build\Microsoft.Windows.SDK.BuildTools.targets'))" />
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Web.WebView2.1.0.2903.40\build\native\Microsoft.Web.WebView2.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Web.WebView2.1.0.2903.40\build\native\Microsoft.Web.WebView2.targets'))" />
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.1.7.250513003\build\native\Microsoft.WindowsAppSDK.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.1.7.250513003\build\native\Microsoft.WindowsAppSDK.props'))" />
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.WindowsAppSDK.1.7.250513003\build\native\Microsoft.WindowsAppSDK.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.WindowsAppSDK.1.7.250513003\build\native\Microsoft.WindowsAppSDK.targets'))" />

View File

@@ -3,6 +3,6 @@
<package id="Microsoft.Web.WebView2" version="1.0.2903.40" targetFramework="native" />
<package id="Microsoft.Windows.CppWinRT" version="2.0.240111.5" targetFramework="native" />
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.231216.1" targetFramework="native" />
<package id="Microsoft.Windows.SDK.BuildTools" version="10.0.22621.2428" targetFramework="native" />
<package id="Microsoft.Windows.SDK.BuildTools" version="10.0.26100.4188" targetFramework="native" />
<package id="Microsoft.WindowsAppSDK" version="1.7.250513003" targetFramework="native" />
</packages>

View File

@@ -9,7 +9,7 @@
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{0db0f63a-d2f8-4da3-a650-2d0b8724218e}</ProjectGuid>
<RootNamespace>NewPlusShellExtensionWin10</RootNamespace>
<WindowsTargetPlatformVersion>10.0.22621.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0.26100.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration">

View File

@@ -49,6 +49,8 @@ namespace WorkspacesEditor.Data
public WindowPositionWrapper Position { get; set; }
public int Monitor { get; set; }
public string Version { get; set; }
}
public struct MonitorConfigurationWrapper

View File

@@ -41,6 +41,7 @@ namespace WorkspacesEditor.Models
Maximized = other.Maximized;
Position = other.Position;
MonitorNumber = other.MonitorNumber;
Version = other.Version;
Parent = other.Parent;
IsNotFound = other.IsNotFound;
@@ -274,5 +275,7 @@ namespace WorkspacesEditor.Models
CommandLineArguments = newCommandLineValue;
OnPropertyChanged(new PropertyChangedEventArgs(nameof(AppMainParams)));
}
public string Version { get; set; }
}
}

View File

@@ -246,6 +246,7 @@ namespace WorkspacesEditor.Models
AppPath = app.ApplicationPath,
AppTitle = app.Title,
PwaAppId = string.IsNullOrEmpty(app.PwaAppId) ? string.Empty : app.PwaAppId,
Version = string.IsNullOrEmpty(app.Version) ? string.Empty : app.Version,
PackageFullName = app.PackageFullName,
AppUserModelId = app.AppUserModelId,
Parent = this,

View File

@@ -107,6 +107,7 @@ namespace WorkspacesEditor.Utils
CommandLineArguments = app.CommandLineArguments,
IsElevated = app.IsElevated,
CanLaunchElevated = app.CanLaunchElevated,
Version = app.Version,
Maximized = app.Maximized,
Minimized = app.Minimized,
Position = new ProjectData.ApplicationWrapper.WindowPositionWrapper

View File

@@ -165,16 +165,52 @@ namespace AppLauncher
if (!launched && !app.pwaAppId.empty())
{
std::filesystem::path appPath(app.path);
if (appPath.filename() == NonLocalizable::EdgeFilename)
int version = 0;
if (app.version != L"")
{
appPathFinal = appPath.parent_path() / NonLocalizable::EdgePwaFilename;
commandLineArgsFinal = NonLocalizable::PwaCommandLineAddition + app.pwaAppId + L" " + app.commandLineArgs;
try
{
version = std::stoi(app.version);
}
catch (const std::invalid_argument&)
{
Logger::error(L"Invalid version format: {}", app.version);
version = 0;
}
catch (const std::out_of_range&)
{
Logger::error(L"Version out of range: {}", app.version);
version = 0;
}
}
if (appPath.filename() == NonLocalizable::ChromeFilename)
if (version >= 1)
{
appPathFinal = appPath.parent_path() / NonLocalizable::ChromePwaFilename;
commandLineArgsFinal = NonLocalizable::PwaCommandLineAddition + app.pwaAppId + L" " + app.commandLineArgs;
auto res = LaunchApp(L"shell:AppsFolder\\" + app.appUserModelId, app.commandLineArgs, app.isElevated);
if (res.isOk())
{
launched = true;
}
else
{
launchErrors.push_back({ app.appUserModelId, res.error() });
}
}
if (!launched)
{
std::filesystem::path appPath(app.path);
if (appPath.filename() == NonLocalizable::EdgeFilename)
{
appPathFinal = appPath.parent_path() / NonLocalizable::EdgePwaFilename;
commandLineArgsFinal = NonLocalizable::PwaCommandLineAddition + app.pwaAppId + L" " + app.commandLineArgs;
}
if (appPath.filename() == NonLocalizable::ChromeFilename)
{
appPathFinal = appPath.parent_path() / NonLocalizable::ChromePwaFilename;
commandLineArgsFinal = NonLocalizable::PwaCommandLineAddition + app.pwaAppId + L" " + app.commandLineArgs;
}
}
}

View File

@@ -76,19 +76,6 @@ namespace WorkspacesLibUnitTests
Assert::IsTrue(result == nonExistentWindowAumid);
}
TEST_METHOD (PwaHelper_GetAUMIDFromWindow_InvalidWindow_ReturnsEmpty)
{
// Arrange
Utils::PwaHelper helper;
HWND invalidWindow = nullptr;
// Act
std::wstring result = helper.GetAUMIDFromWindow(invalidWindow);
// Assert
Assert::IsTrue(result.empty());
}
TEST_METHOD (PwaHelper_GetEdgeAppId_ValidConstruction_DoesNotCrash)
{
// Arrange

View File

@@ -1,5 +1,6 @@
#include "pch.h"
#include "PwaHelper.h"
#include "WindowUtils.h"
#include <filesystem>
@@ -51,7 +52,7 @@ namespace Utils
localFolder = L""; // Ensure it is explicitly set to empty on failure
}
}
return localFolder;
}
@@ -193,7 +194,7 @@ namespace Utils
return std::nullopt;
}
std::optional<std::wstring> PwaHelper::GetChromeAppId(const std::wstring& windowAumid) const
{
const auto appIdIndexStart = windowAumid.find(NonLocalizable::ChromeAppIdIdentifier);
@@ -256,85 +257,4 @@ namespace Utils
return result;
}
std::wstring PwaHelper::GetAUMIDFromWindow(HWND hwnd) const
{
std::wstring result{};
if (hwnd == NULL)
{
return result;
}
Microsoft::WRL::ComPtr<IPropertyStore> propertyStore;
HRESULT hr = SHGetPropertyStoreForWindow(hwnd, IID_PPV_ARGS(&propertyStore));
if (FAILED(hr))
{
return result;
}
PROPVARIANT propVariant;
PropVariantInit(&propVariant);
hr = propertyStore->GetValue(PKEY_AppUserModel_ID, &propVariant);
if (SUCCEEDED(hr) && propVariant.vt == VT_LPWSTR && propVariant.pwszVal != nullptr)
{
result = propVariant.pwszVal;
}
PropVariantClear(&propVariant);
Logger::info(L"Found a window with aumid {}", result);
return result;
}
std::wstring PwaHelper::GetAUMIDFromProcessId(DWORD processId) const
{
HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, processId);
if (hProcess == NULL)
{
Logger::error(L"Failed to open process handle. Error: {}", get_last_error_or_default(GetLastError()));
return {};
}
// Get the package full name for the process
UINT32 packageFullNameLength = 0;
LONG rc = GetPackageFullName(hProcess, &packageFullNameLength, nullptr);
if (rc != ERROR_INSUFFICIENT_BUFFER)
{
Logger::error(L"Failed to get package full name length. Error code: {}", rc);
CloseHandle(hProcess);
return {};
}
std::vector<wchar_t> packageFullName(packageFullNameLength);
rc = GetPackageFullName(hProcess, &packageFullNameLength, packageFullName.data());
if (rc != ERROR_SUCCESS)
{
Logger::error(L"Failed to get package full name. Error code: {}", rc);
CloseHandle(hProcess);
return {};
}
// Get the AUMID for the package
UINT32 appModelIdLength = 0;
rc = GetApplicationUserModelId(hProcess, &appModelIdLength, nullptr);
if (rc != ERROR_INSUFFICIENT_BUFFER)
{
Logger::error(L"Failed to get AppUserModelId length. Error code: {}", rc);
CloseHandle(hProcess);
return {};
}
std::vector<wchar_t> appModelId(appModelIdLength);
rc = GetApplicationUserModelId(hProcess, &appModelIdLength, appModelId.data());
if (rc != ERROR_SUCCESS)
{
Logger::error(L"Failed to get AppUserModelId. Error code: {}", rc);
CloseHandle(hProcess);
return {};
}
CloseHandle(hProcess);
return std::wstring(appModelId.data());
}
}

View File

@@ -12,19 +12,16 @@ namespace Utils
PwaHelper();
~PwaHelper() = default;
std::wstring GetAUMIDFromWindow(HWND hWnd) const;
std::optional<std::wstring> GetEdgeAppId(const std::wstring& windowAumid) const;
std::optional<std::wstring> GetChromeAppId(const std::wstring& windowAumid) const;
std::optional<std::wstring> GetChromeAppId(const std::wstring& windowAumid) const;
std::wstring SearchPwaName(const std::wstring& pwaAppId, const std::wstring& windowAumid) const;
private:
void InitAppIds(const std::wstring& browserDataFolder, const std::wstring& browserDirPrefix, const std::function<void(const std::wstring&)>& addingAppIdCallback);
void InitEdgeAppIds();
void InitChromeAppIds();
std::wstring GetAppIdFromCommandLineArgs(const std::wstring& commandLineArgs) const;
std::wstring GetAUMIDFromProcessId(DWORD processId) const;
std::map<std::wstring, std::wstring> m_edgeAppIds;
std::vector<std::wstring> m_chromeAppIds;

View File

@@ -0,0 +1,18 @@
#include "pch.h"
#include "StringUtils.h"
namespace StringUtils
{
bool CaseInsensitiveEquals(const std::wstring& str1, const std::wstring& str2)
{
if (str1.size() != str2.size())
{
return false;
}
return std::equal(str1.begin(), str1.end(), str2.begin(), [](wchar_t ch1, wchar_t ch2) {
return towupper(ch1) == towupper(ch2);
});
}
}

View File

@@ -6,15 +6,5 @@
namespace StringUtils
{
inline bool CaseInsensitiveEquals(const std::wstring& str1, const std::wstring& str2)
{
if (str1.size() != str2.size())
{
return false;
}
return std::equal(str1.begin(), str1.end(), str2.begin(), [](wchar_t ch1, wchar_t ch2) {
return towupper(ch1) == towupper(ch2);
});
}
bool CaseInsensitiveEquals(const std::wstring& str1, const std::wstring& str2);
}

View File

@@ -0,0 +1,105 @@
#include "pch.h"
#include "WindowUtils.h"
#include <filesystem>
#include <appmodel.h>
#include <shellapi.h>
#include <ShlObj.h>
#include <shobjidl.h>
#include <tlhelp32.h>
#include <wrl.h>
#include <propkey.h>
#include <wil/com.h>
#include <common/logger/logger.h>
#include <common/utils/winapi_error.h>
#include <WorkspacesLib/AppUtils.h>
#include <WorkspacesLib/CommandLineArgsHelper.h>
#include <WorkspacesLib/StringUtils.h>
namespace Utils
{
std::wstring GetAUMIDFromProcessId(DWORD processId)
{
HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, processId);
if (hProcess == NULL)
{
Logger::error(L"Failed to open process handle. Error: {}", get_last_error_or_default(GetLastError()));
return {};
}
// Get the package full name for the process
UINT32 packageFullNameLength = 0;
LONG rc = GetPackageFullName(hProcess, &packageFullNameLength, nullptr);
if (rc != ERROR_INSUFFICIENT_BUFFER)
{
Logger::error(L"Failed to get package full name length. Error code: {}", rc);
CloseHandle(hProcess);
return {};
}
std::vector<wchar_t> packageFullName(packageFullNameLength);
rc = GetPackageFullName(hProcess, &packageFullNameLength, packageFullName.data());
if (rc != ERROR_SUCCESS)
{
Logger::error(L"Failed to get package full name. Error code: {}", rc);
CloseHandle(hProcess);
return {};
}
// Get the AUMID for the package
UINT32 appModelIdLength = 0;
rc = GetApplicationUserModelId(hProcess, &appModelIdLength, nullptr);
if (rc != ERROR_INSUFFICIENT_BUFFER)
{
Logger::error(L"Failed to get AppUserModelId length. Error code: {}", rc);
CloseHandle(hProcess);
return {};
}
std::vector<wchar_t> appModelId(appModelIdLength);
rc = GetApplicationUserModelId(hProcess, &appModelIdLength, appModelId.data());
if (rc != ERROR_SUCCESS)
{
Logger::error(L"Failed to get AppUserModelId. Error code: {}", rc);
CloseHandle(hProcess);
return {};
}
CloseHandle(hProcess);
return std::wstring(appModelId.data());
}
std::wstring GetAUMIDFromWindow(HWND hwnd)
{
std::wstring result{};
if (hwnd == NULL)
{
return result;
}
Microsoft::WRL::ComPtr<IPropertyStore> propertyStore;
HRESULT hr = SHGetPropertyStoreForWindow(hwnd, IID_PPV_ARGS(&propertyStore));
if (FAILED(hr))
{
return result;
}
PROPVARIANT propVariant;
PropVariantInit(&propVariant);
hr = propertyStore->GetValue(PKEY_AppUserModel_ID, &propVariant);
if (SUCCEEDED(hr) && propVariant.vt == VT_LPWSTR && propVariant.pwszVal != nullptr)
{
result = propVariant.pwszVal;
}
PropVariantClear(&propVariant);
Logger::info(L"Found a window with aumid {}", result);
return result;
}
}

View File

@@ -0,0 +1,12 @@
#pragma once
#include <functional>
#include <WorkspacesLib/AppUtils.h>
#include <wtypes.h>
namespace Utils
{
std::wstring GetAUMIDFromWindow(HWND hWnd);
std::wstring GetAUMIDFromProcessId(DWORD processId);
};

View File

@@ -87,6 +87,7 @@ namespace WorkspacesData
const static wchar_t* MaximizedID = L"maximized";
const static wchar_t* PositionID = L"position";
const static wchar_t* MonitorID = L"monitor";
const static wchar_t* VersionID = L"version";
}
json::JsonObject ToJson(const WorkspacesProject::Application& data)
@@ -106,6 +107,7 @@ namespace WorkspacesData
json.SetNamedValue(NonLocalizable::MaximizedID, json::value(data.isMaximized));
json.SetNamedValue(NonLocalizable::PositionID, PositionJSON::ToJson(data.position));
json.SetNamedValue(NonLocalizable::MonitorID, json::value(data.monitor));
json.SetNamedValue(NonLocalizable::VersionID, json::value(data.version));
return json;
}
@@ -168,6 +170,11 @@ namespace WorkspacesData
result.position = position.value();
}
if (json.HasKey(NonLocalizable::VersionID))
{
result.version = json.GetNamedString(NonLocalizable::VersionID);
}
}
catch (const winrt::hresult_error&)
{
@@ -286,6 +293,7 @@ namespace WorkspacesData
const static wchar_t* MoveExistingWindowsID = L"move-existing-windows";
const static wchar_t* MonitorConfigurationID = L"monitor-configuration";
const static wchar_t* AppsID = L"applications";
const static wchar_t* Version = L"version";
}
json::JsonObject ToJson(const WorkspacesProject& data)

View File

@@ -33,6 +33,9 @@ namespace WorkspacesData
std::wstring appUserModelId;
std::wstring pwaAppId;
std::wstring commandLineArgs;
// empty to 1,
std::wstring version;
bool isElevated{};
bool canLaunchElevated{};
bool isMinimized{};
@@ -86,7 +89,7 @@ namespace WorkspacesData
{
WorkspacesData::WorkspacesProject::Application application;
HWND window{};
LaunchingState state { LaunchingState::Waiting };
LaunchingState state{ LaunchingState::Waiting };
};
using LaunchingAppStateMap = std::map<WorkspacesData::WorkspacesProject::Application, LaunchingAppState>;

View File

@@ -45,6 +45,7 @@
<ClInclude Include="StringUtils.h" />
<ClInclude Include="utils.h" />
<ClInclude Include="WbemHelper.h" />
<ClInclude Include="WindowUtils.h" />
<ClInclude Include="WorkspacesData.h" />
<ClInclude Include="trace.h" />
</ItemGroup>
@@ -59,8 +60,10 @@
</ClCompile>
<ClCompile Include="PwaHelper.cpp" />
<ClCompile Include="SteamGameHelper.cpp" />
<ClCompile Include="StringUtils.cpp" />
<ClCompile Include="two_way_pipe_message_ipc.cpp" />
<ClCompile Include="WbemHelper.cpp" />
<ClCompile Include="WindowUtils.cpp" />
<ClCompile Include="WorkspacesData.cpp" />
<ClCompile Include="trace.cpp" />
</ItemGroup>

View File

@@ -56,6 +56,9 @@
<ClInclude Include="SteamHelper.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="WindowUtils.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="pch.cpp">
@@ -94,6 +97,12 @@
<ClCompile Include="SteamGameHelper.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="WindowUtils.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="StringUtils.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />

View File

@@ -11,6 +11,7 @@
#include <WorkspacesLib/AppUtils.h>
#include <WorkspacesLib/PwaHelper.h>
#include <WorkspacesLib/WindowUtils.h>
#include <WindowProperties/WorkspacesWindowPropertyUtils.h>
#include "Generated Files/resource.h"
@@ -139,7 +140,7 @@ namespace SnapshotUtils
bool isChrome = appData.IsChrome();
if (isEdge || isChrome)
{
auto windowAumid = pwaHelper.GetAUMIDFromWindow(window);
auto windowAumid = Utils::GetAUMIDFromWindow(window);
std::optional<std::wstring> pwaAppId{};
if (isEdge)
@@ -158,6 +159,8 @@ namespace SnapshotUtils
appData.pwaAppId = pwaAppId.value();
appData.name = pwaName + L" (" + appData.name + L")";
// If it's pwa app, appUserModelId should be their own pwa id.
appData.appUserModelId = windowAumid;
}
}
@@ -185,6 +188,7 @@ namespace SnapshotUtils
.appUserModelId = appData.appUserModelId,
.pwaAppId = appData.pwaAppId,
.commandLineArgs = L"",
.version = L"1",
.isElevated = IsProcessElevated(pid),
.canLaunchElevated = appData.canLaunchElevated,
.isMinimized = isMinimized,

View File

@@ -13,6 +13,7 @@
#include <WindowProperties/WorkspacesWindowPropertyUtils.h>
#include <WorkspacesLib/PwaHelper.h>
#include <WorkspacesLib/WindowUtils.h>
namespace NonLocalizable
{
@@ -203,7 +204,7 @@ std::optional<WindowWithDistance> WindowArranger::GetNearestWindow(const Workspa
if (!data->IsSteamGame() && !WindowUtils::HasThickFrame(window))
{
// Only care about steam games if it has no thick frame to remain consistent with
// Only care about steam games if it has no thick frame to remain consistent with
// the behavior as before.
continue;
}
@@ -220,7 +221,7 @@ std::optional<WindowWithDistance> WindowArranger::GetNearestWindow(const Workspa
bool isChrome = appData.IsChrome();
if (isEdge || isChrome)
{
auto windowAumid = pwaHelper.GetAUMIDFromWindow(window);
auto windowAumid = Utils::GetAUMIDFromWindow(window);
std::optional<std::wstring> pwaAppId{};
if (isEdge)

View File

@@ -117,16 +117,18 @@ private:
for (DWORD pid : processIds)
{
HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
HANDLE hProcess = OpenProcess(SYNCHRONIZE | PROCESS_TERMINATE, FALSE, pid);
if (hProcess != NULL)
{
SetEvent(m_hTerminateEvent);
// Wait for 1.5 seconds for the process to end correctly and stop etw tracer
WaitForSingleObject(hProcess, 1500);
// Wait for 1.5 seconds for the process to end correctly, allowing time for ETW tracer and extensions to stop
if (WaitForSingleObject(hProcess, 1500) == WAIT_TIMEOUT)
{
TerminateProcess(hProcess, 0);
}
TerminateProcess(hProcess, 0);
CloseHandle(hProcess);
}
}

View File

@@ -8,7 +8,7 @@
<PackageVersion Include="Microsoft.Web.WebView2" Version="1.0.2903.40" />
<PackageVersion Include="Microsoft.Windows.CsWin32" Version="0.2.46-beta" />
<PackageVersion Include="Microsoft.Windows.CsWinRT" Version="2.2.0" />
<PackageVersion Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22621.2428" />
<PackageVersion Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.4188" />
<PackageVersion Include="Microsoft.WindowsAppSDK" Version="1.7.250513003" />
<PackageVersion Include="Shmuelie.WinRTServer" Version="2.1.1" />
<PackageVersion Include="StyleCop.Analyzers" Version="1.2.0-beta.556" />

View File

@@ -4,8 +4,8 @@
<RootNamespace>TemplateCmdPalExtension</RootNamespace>
<ApplicationManifest>app.manifest</ApplicationManifest>
<WindowsSdkPackageVersion>10.0.22621.57</WindowsSdkPackageVersion>
<TargetFramework>net9.0-windows10.0.22621.0</TargetFramework>
<WindowsSdkPackageVersion>10.0.26100.68-preview</WindowsSdkPackageVersion>
<TargetFramework>net9.0-windows10.0.26100.0</TargetFramework>
<TargetPlatformMinVersion>10.0.19041.0</TargetPlatformMinVersion>
<SupportedOSPlatformVersion>10.0.19041.0</SupportedOSPlatformVersion>
<RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers>

View File

@@ -102,6 +102,8 @@ public sealed partial class TopLevelViewModel : ObservableObject, IListItem
}
HandleChangeAlias();
OnPropertyChanged(nameof(AliasText));
OnPropertyChanged(nameof(IsDirectAlias));
}
}
@@ -116,6 +118,7 @@ public sealed partial class TopLevelViewModel : ObservableObject, IListItem
}
HandleChangeAlias();
OnPropertyChanged(nameof(IsDirectAlias));
}
}

View File

@@ -67,6 +67,7 @@ public partial class App : Application
"Local\\PowerToysCmdPal-ExitEvent-eb73f6be-3f22-4b36-aee3-62924ba40bfd", () =>
{
EtwTrace?.Dispose();
AppWindow?.Close();
Environment.Exit(0);
});
}

View File

@@ -57,7 +57,11 @@ public sealed partial class MainWindow : WindowEx,
InitializeComponent();
_hwnd = new HWND(WinRT.Interop.WindowNative.GetWindowHandle(this).ToInt32());
CommandPaletteHost.SetHostHwnd((ulong)_hwnd.Value);
unsafe
{
CommandPaletteHost.SetHostHwnd((ulong)_hwnd.Value);
}
_keyboardListener = new KeyboardListener();
_keyboardListener.Start();

View File

@@ -105,6 +105,10 @@
<ProjectCapability Include="Msix" />
</ItemGroup>
<ItemGroup>
<RdXmlFile Include="rd.xml" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\common\ManagedTelemetry\Telemetry\ManagedTelemetry.csproj" />
<ProjectReference Include="..\ext\Microsoft.CmdPal.Ext.System\Microsoft.CmdPal.Ext.System.csproj" />

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8" ?>
<Page
x:Class="Microsoft.CmdPal.UI.Settings.ExtensionPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
@@ -92,12 +92,11 @@
<controls:SettingsCard x:Uid="Settings_ExtensionPage_Alias_SettingsCard" HeaderIcon="{ui:FontIcon Glyph=&#xE8AC;}">
<StackPanel Orientation="Vertical">
<TextBox Text="{x:Bind AliasText, Mode=TwoWay}" />
<TextBox Text="{x:Bind AliasText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
<ToggleSwitch
x:Uid="Settings_ExtensionPage_Alias_ToggleSwitch"
IsEnabled="{x:Bind AliasText, Converter={StaticResource StringEmptyToBoolConverter}, Mode=OneWay}"
IsOn="{x:Bind IsDirectAlias, Mode=TwoWay}"
OffContent="Indirect"
OnContent="Direct" />
IsOn="{x:Bind IsDirectAlias, Mode=TwoWay}" />
</StackPanel>
</controls:SettingsCard>

View File

@@ -418,4 +418,10 @@ Right-click to remove the key combination, thereby deactivating the shortcut.</v
<data name="TrayMenu_Exit" xml:space="preserve">
<value>Exit</value>
</data>
<data name="Settings_ExtensionPage_Alias_ToggleSwitch.OnContent" xml:space="preserve">
<value>Direct</value>
</data>
<data name="Settings_ExtensionPage_Alias_ToggleSwitch.OffContent" xml:space="preserve">
<value>Indirect</value>
</data>
</root>

View File

@@ -0,0 +1,7 @@
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
<Application>
<Assembly Name="Microsoft.WinUI">
<Type Name="Microsoft.UI.Xaml.Controls.FontIconSource" Dynamic="Required All" />
</Assembly>
</Application>
</Directives>

View File

@@ -19,7 +19,7 @@
<AppContainerApplication>false</AppContainerApplication>
<ApplicationType>Windows Store</ApplicationType>
<ApplicationTypeRevision>10.0</ApplicationTypeRevision>
<WindowsTargetPlatformVersion Condition=" '$(WindowsTargetPlatformVersion)' == '' ">10.0.22621.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion Condition=" '$(WindowsTargetPlatformVersion)' == '' ">10.0.26100.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformMinVersion>10.0.19041.0</WindowsTargetPlatformMinVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />

View File

@@ -0,0 +1,49 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Globalization;
using System.Text;
using ManagedCommon;
using Microsoft.CmdPal.Ext.Apps.Properties;
using Microsoft.CommandPalette.Extensions.Toolkit;
namespace Microsoft.CmdPal.Ext.Apps.Commands;
internal sealed partial class CopyPathCommand : InvokableCommand
{
private static readonly IconInfo TheIcon = new("\ue8c8");
private readonly string _target;
public CopyPathCommand(string target)
{
Name = Resources.copy_path;
Icon = TheIcon;
_target = target;
}
private static readonly CompositeFormat CopyFailedFormat = CompositeFormat.Parse(Resources.copy_failed);
public override CommandResult Invoke()
{
try
{
ClipboardHelper.SetText(_target);
}
catch (Exception ex)
{
Logger.LogError("Copy failed: " + ex.Message);
return CommandResult.ShowToast(
new ToastArgs
{
Message = string.Format(CultureInfo.CurrentCulture, CopyFailedFormat, ex.Message),
Result = CommandResult.KeepOpen(),
});
}
return CommandResult.ShowToast(Resources.copied_to_clipboard);
}
}

View File

@@ -85,6 +85,10 @@ public class UWPApplication : IProgram
// We don't add context menu to 'run as different user', because UWP applications normally installed per user and not for all users.
}
commands.Add(
new CommandContextItem(
new CopyPathCommand(Location)));
commands.Add(
new CommandContextItem(
new OpenPathCommand(Location)
@@ -217,11 +221,10 @@ public class UWPApplication : IProgram
var capacity = 1024U;
PWSTR outBuffer = new PWSTR((char*)(void*)Marshal.AllocHGlobal((int)capacity * sizeof(char)));
var source = $"@{{{packageFullName}? {parsed}}}";
void* reserved = null;
try
{
PInvoke.SHLoadIndirectString(source, outBuffer, capacity, ref reserved).ThrowOnFailure();
PInvoke.SHLoadIndirectString(source, outBuffer.AsSpan()).ThrowOnFailure();
var loaded = outBuffer.ToString();
return string.IsNullOrEmpty(loaded) ? string.Empty : loaded;
@@ -231,7 +234,7 @@ public class UWPApplication : IProgram
try
{
var sourceFallback = $"@{{{packageFullName}?{parsedFallback}}}";
PInvoke.SHLoadIndirectString(sourceFallback, outBuffer, capacity, ref reserved).ThrowOnFailure();
PInvoke.SHLoadIndirectString(sourceFallback, outBuffer.AsSpan()).ThrowOnFailure();
var loaded = outBuffer.ToString();
return string.IsNullOrEmpty(loaded) ? string.Empty : loaded;
}

View File

@@ -198,6 +198,9 @@ public class Win32Program : IProgram
new RunAsUserCommand(!string.IsNullOrEmpty(LnkFilePath) ? LnkFilePath : FullPath, ParentDirectory)));
}
commands.Add(new CommandContextItem(
new CopyPathCommand(FullPath)));
commands.Add(new CommandContextItem(
new OpenPathCommand(ParentDirectory)));

View File

@@ -78,6 +78,33 @@ namespace Microsoft.CmdPal.Ext.Apps.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Copied to clipboard!.
/// </summary>
internal static string copied_to_clipboard {
get {
return ResourceManager.GetString("copied_to_clipboard", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Copy failed ({0}). Please try again..
/// </summary>
internal static string copy_failed {
get {
return ResourceManager.GetString("copy_failed", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Copy path.
/// </summary>
internal static string copy_path {
get {
return ResourceManager.GetString("copy_path", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Include apps found on the desktop.
/// </summary>

View File

@@ -163,12 +163,22 @@
<data name="open_location" xml:space="preserve">
<value>Open location</value>
</data>
<data name="copy_path" xml:space="preserve">
<value>Copy path</value>
</data>
<data name="run_as_administrator" xml:space="preserve">
<value>Run as administrator</value>
</data>
<data name="run_as_different_user" xml:space="preserve">
<value>Run as different user</value>
</data>
<data name="copy_failed" xml:space="preserve">
<value>Copy failed ({0}). Please try again.</value>
<comment>{0} is the error message</comment>
</data>
<data name="copied_to_clipboard" xml:space="preserve">
<value>Copied to clipboard!</value>
</data>
<data name="enable_start_menu_source" xml:space="preserve">
<value>Include apps found in the Start Menu</value>
</data>

View File

@@ -0,0 +1,42 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Microsoft.CmdPal.Ext.Indexer.Native;
using Windows.Win32;
using Windows.Win32.Foundation;
using Windows.Win32.System.Com;
using WinRT;
using WinRT.Interop;
namespace Microsoft.CmdPal.Ext.Indexer.Data;
internal static class ActionRuntimeFactory
{
private const string ActionRuntimeClsidStr = "C36FEF7E-35F3-4192-9F2C-AF1FD425FB85";
// typeof(Windows.AI.Actions.IActionRuntime).GUID
private static readonly Guid IActionRuntimeIID = Guid.Parse("206EFA2C-C909-508A-B4B0-9482BE96DB9C");
public static unsafe global::Windows.AI.Actions.ActionRuntime CreateActionRuntime()
{
IntPtr abiPtr = default;
try
{
Guid classId = Guid.Parse(ActionRuntimeClsidStr);
Guid iid = IActionRuntimeIID;
var hresult = NativeMethods.CoCreateInstance(ref Unsafe.AsRef(in classId), IntPtr.Zero, NativeHelpers.CLSCTXLOCALSERVER, ref iid, out abiPtr);
Marshal.ThrowExceptionForHR((int)hresult);
return MarshalInterface<global::Windows.AI.Actions.ActionRuntime>.FromAbi(abiPtr);
}
finally
{
MarshalInspectable<object>.DisposeAbi(abiPtr);
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@@ -0,0 +1,43 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Threading.Tasks;
using Microsoft.CommandPalette.Extensions.Toolkit;
using Windows.AI.Actions.Hosting;
namespace Microsoft.CmdPal.Ext.Indexer.Commands;
internal sealed partial class ExecuteActionCommand : InvokableCommand
{
private readonly ActionInstance actionInstance;
internal ExecuteActionCommand(ActionInstance actionInstance)
{
this.actionInstance = actionInstance;
this.Name = actionInstance.DisplayInfo.Description;
this.Icon = new IconInfo(actionInstance.Definition.IconFullPath);
}
public override CommandResult Invoke()
{
var task = Task.Run(InvokeAsync);
task.Wait();
return task.Result;
}
private async Task<CommandResult> InvokeAsync()
{
try
{
await actionInstance.InvokeAsync();
return CommandResult.GoHome();
}
catch (Exception ex)
{
return CommandResult.ShowToast("Failed to invoke action " + actionInstance.Definition.Id + ": " + ex.Message);
}
}
}

View File

@@ -4,8 +4,11 @@
using System.Collections.Generic;
using Microsoft.CmdPal.Ext.Indexer.Commands;
using Microsoft.CmdPal.Ext.Indexer.Pages;
using Microsoft.CmdPal.Ext.Indexer.Properties;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;
using Windows.Foundation.Metadata;
namespace Microsoft.CmdPal.Ext.Indexer.Data;
@@ -38,9 +41,24 @@ internal sealed partial class IndexerListItem : ListItem
}
}
MoreCommands = [
IContextItem[] moreCommands = [
..context,
new CommandContextItem(new OpenWithCommand(indexerItem)),
new CommandContextItem(new OpenWithCommand(indexerItem))];
if (ApiInformation.IsApiContractPresent("Windows.AI.Actions.ActionsContract", 4))
{
var actionsListContextItem = new ActionsListContextItem(indexerItem.FullPath);
if (actionsListContextItem.AnyActions())
{
moreCommands = [
.. moreCommands,
actionsListContextItem
];
}
}
MoreCommands = [
.. moreCommands,
new CommandContextItem(new ShowFileInFolderCommand(indexerItem.FullPath) { Name = Resources.Indexer_Command_ShowInFolder }),
new CommandContextItem(new CopyPathCommand(indexerItem)),
new CommandContextItem(new OpenInConsoleCommand(indexerItem)),

View File

@@ -34,6 +34,9 @@
<Content Update="Assets\FileExplorer.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Update="Assets\Actions.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Update="Assets\FileExplorer.svg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>

View File

@@ -11,6 +11,7 @@ public sealed partial class NativeHelpers
public const uint SEEMASKINVOKEIDLIST = 12;
public const uint CLSCTXINPROCALL = 0x17;
public const uint CLSCTXLOCALSERVER = 0x4;
public struct PropertyKeys
{

View File

@@ -1,6 +1,7 @@
{
"$schema": "https://aka.ms/CsWin32.schema.json",
"allowMarshaling": false,
"emitSingleFile": false,
"public": true
"comInterop": {
"preserveSigMethods": [ "*" ]
}
}

View File

@@ -0,0 +1,93 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
using System.Globalization;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CmdPal.Ext.Indexer.Commands;
using Microsoft.CmdPal.Ext.Indexer.Data;
using Microsoft.CmdPal.Ext.Indexer.Properties;
using Microsoft.CommandPalette.Extensions.Toolkit;
using Windows.AI.Actions;
using Windows.System;
namespace Microsoft.CmdPal.Ext.Indexer.Pages;
internal sealed partial class ActionsListContextItem : CommandContextItem
{
private readonly string fullPath;
private readonly List<CommandContextItem> actions = [];
private static readonly Lock UpdateMoreCommandsLock = new();
private static ActionRuntime actionRuntime;
public ActionsListContextItem(string fullPath)
: base(new NoOpCommand())
{
Title = Resources.Indexer_Command_Actions;
Icon = Icons.Actions;
RequestedShortcut = KeyChordHelpers.FromModifiers(alt: true, vkey: VirtualKey.A);
this.fullPath = fullPath;
UpdateMoreCommands();
}
public bool AnyActions() => actions.Count != 0;
private void ActionCatalog_Changed(global::Windows.AI.Actions.Hosting.ActionCatalog sender, object args)
{
UpdateMoreCommands();
}
private void UpdateMoreCommands()
{
try
{
lock (UpdateMoreCommandsLock)
{
if (actionRuntime == null)
{
actionRuntime = ActionRuntimeFactory.CreateActionRuntime();
Task.Delay(500).Wait();
}
actionRuntime.ActionCatalog.Changed -= ActionCatalog_Changed;
actionRuntime.ActionCatalog.Changed += ActionCatalog_Changed;
}
var extension = System.IO.Path.GetExtension(fullPath).ToLower(CultureInfo.InvariantCulture);
ActionEntity entity = null;
if (extension != null)
{
if (extension == ".jpg" || extension == ".jpeg" || extension == ".png")
{
entity = actionRuntime.EntityFactory.CreatePhotoEntity(fullPath);
}
else if (extension == ".docx" || extension == ".doc" || extension == ".pdf" || extension == ".txt")
{
entity = actionRuntime.EntityFactory.CreateDocumentEntity(fullPath);
}
}
if (entity == null)
{
entity = actionRuntime.EntityFactory.CreateFileEntity(fullPath);
}
lock (actions)
{
actions.Clear();
foreach (var actionInstance in actionRuntime.ActionCatalog.GetActionsForInputs([entity]))
{
actions.Add(new CommandContextItem(new ExecuteActionCommand(actionInstance)));
}
MoreCommands = [.. actions];
}
}
catch
{
actionRuntime = null;
}
}
}

View File

@@ -12,6 +12,8 @@ internal sealed class Icons
internal static IconInfo FileExplorer { get; } = IconHelpers.FromRelativePath("Assets\\FileExplorer.png");
internal static IconInfo Actions { get; } = IconHelpers.FromRelativePath("Assets\\Actions.png");
internal static IconInfo OpenFile { get; } = new("\uE8E5"); // OpenFile
internal static IconInfo Document { get; } = new("\uE8A5"); // Document

View File

@@ -60,6 +60,15 @@ namespace Microsoft.CmdPal.Ext.Indexer.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Actions.
/// </summary>
internal static string Indexer_Command_Actions {
get {
return ResourceManager.GetString("Indexer_Command_Actions", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Browse.
/// </summary>

View File

@@ -138,6 +138,9 @@
<data name="Indexer_Command_OpenWith" xml:space="preserve">
<value>Open with</value>
</data>
<data name="Indexer_Command_Actions" xml:space="preserve">
<value>Actions...</value>
</data>
<data name="Indexer_Command_ShowInFolder" xml:space="preserve">
<value>Show in folder</value>
</data>

View File

@@ -110,6 +110,13 @@ internal static class Commands
});
}
results.Add(new ListItem(new ExecuteCommandConfirmation(Resources.Microsoft_plugin_sys_RestartShell_name!, confirmCommands, Resources.Microsoft_plugin_sys_RestartShell_confirmation!, static () => OpenInShellHelper.OpenInShell("cmd", "/C tskill explorer && start explorer", runWithHiddenWindow: true)))
{
Title = Resources.Microsoft_plugin_sys_RestartShell!,
Subtitle = Resources.Microsoft_plugin_sys_RestartShell_description!,
Icon = Icons.RestartShellIcon,
});
// UEFI command/result. It is only available on systems booted in UEFI mode.
if (isUefi)
{

View File

@@ -20,6 +20,8 @@ public static partial class Icons
public static IconInfo RestartIcon { get; } = new IconInfo("\uE777");
public static IconInfo RestartShellIcon { get; } = new IconInfo("\uEC50");
public static IconInfo ShutdownIcon { get; } = new IconInfo("\uE7E8");
public static IconInfo SleepIcon { get; } = new IconInfo("\uE708");

View File

@@ -645,6 +645,42 @@ namespace Microsoft.CmdPal.Ext.System {
}
}
/// <summary>
/// Looks up a localized string similar to Restart Windows Explorer.
/// </summary>
public static string Microsoft_plugin_sys_RestartShell {
get {
return ResourceManager.GetString("Microsoft_plugin_sys_RestartShell", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to You are about to restart Windows Explorer, are you sure?.
/// </summary>
public static string Microsoft_plugin_sys_RestartShell_confirmation {
get {
return ResourceManager.GetString("Microsoft_plugin_sys_RestartShell_confirmation", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to End and restart the Windows Explorer shell process.
/// </summary>
public static string Microsoft_plugin_sys_RestartShell_description {
get {
return ResourceManager.GetString("Microsoft_plugin_sys_RestartShell_description", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Restart.
/// </summary>
public static string Microsoft_plugin_sys_RestartShell_name {
get {
return ResourceManager.GetString("Microsoft_plugin_sys_RestartShell_name", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to ip; mac; address.
/// </summary>

View File

@@ -417,4 +417,16 @@
<data name="Microsoft_plugin_ext_fallback_display_title" xml:space="preserve">
<value>Open System Command</value>
</data>
<data name="Microsoft_plugin_sys_RestartShell" xml:space="preserve">
<value>Restart Windows Explorer</value>
</data>
<data name="Microsoft_plugin_sys_RestartShell_description" xml:space="preserve">
<value>End and restart the Windows Explorer shell process</value>
</data>
<data name="Microsoft_plugin_sys_RestartShell_name" xml:space="preserve">
<value>Restart</value>
</data>
<data name="Microsoft_plugin_sys_RestartShell_confirmation" xml:space="preserve">
<value>You are about to restart Windows Explorer, are you sure?</value>
</data>
</root>

View File

@@ -68,6 +68,7 @@ internal sealed partial class FallbackTimeDateItem : FallbackCommandItem
Title = result.Title;
Subtitle = result.Subtitle;
Icon = result.Icon;
Command = result.Command;
}
else
{

View File

@@ -18,8 +18,6 @@ internal sealed partial class TimeDateExtensionPage : DynamicListPage
private IList<ListItem> _results = new List<ListItem>();
private bool initialized;
private SettingsManager _settingsManager;
public TimeDateExtensionPage(SettingsManager settingsManager)
@@ -35,12 +33,9 @@ internal sealed partial class TimeDateExtensionPage : DynamicListPage
public override IListItem[] GetItems()
{
if (!initialized)
{
DoExecuteSearch(string.Empty);
}
DoExecuteSearch(string.Empty);
lock (_resultsLock)
lock (_resultsLock)
{
ListItem[] results = _results.ToArray();
return results;
@@ -49,11 +44,6 @@ internal sealed partial class TimeDateExtensionPage : DynamicListPage
public override void UpdateSearchText(string oldSearch, string newSearch)
{
if (newSearch == oldSearch)
{
return;
}
DoExecuteSearch(newSearch);
}
@@ -84,7 +74,6 @@ internal sealed partial class TimeDateExtensionPage : DynamicListPage
{
lock (_resultsLock)
{
initialized = true;
this._results = result;
}

View File

@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using ManagedCommon;
@@ -188,17 +189,20 @@ public static class DefaultBrowserInfo
{
var buffer = stackalloc char[128];
var capacity = 128;
void* reserved = null;
var firstChar = str[0];
var strPtr = &firstChar;
// S_OK == 0
if (global::Windows.Win32.PInvoke.SHLoadIndirectString(
str,
fixed (char* pszSourceLocal = str)
{
if (global::Windows.Win32.PInvoke.SHLoadIndirectString(
pszSourceLocal,
buffer,
(uint)capacity,
ref reserved)
== 0)
{
return new string(buffer);
default) == 0)
{
return new string(buffer);
}
}
}

View File

@@ -37,7 +37,7 @@ public class Utilities
var FOLDERID_LocalAppData = new Guid("F1B32785-6FBA-4FCF-9D55-7B8E7F157091");
var hr = PInvoke.SHGetKnownFolderPath(
FOLDERID_LocalAppData,
(uint)KNOWN_FOLDER_FLAG.KF_FLAG_FORCE_APP_DATA_REDIRECTION,
KNOWN_FOLDER_FLAG.KF_FLAG_FORCE_APP_DATA_REDIRECTION,
null,
out var localAppDataFolder);

View File

@@ -4,7 +4,7 @@
<PathToRoot>..\..\..\..\..\</PathToRoot>
<WasdkNuget>$(PathToRoot)packages\Microsoft.WindowsAppSDK.1.7.250513003</WasdkNuget>
<CppWinRTNuget>$(PathToRoot)packages\Microsoft.Windows.CppWinRT.2.0.240111.5</CppWinRTNuget>
<WindowsSdkBuildToolsNuget>$(PathToRoot)packages\Microsoft.Windows.SDK.BuildTools.10.0.22621.2428</WindowsSdkBuildToolsNuget>
<WindowsSdkBuildToolsNuget>$(PathToRoot)packages\Microsoft.Windows.SDK.BuildTools.10.0.26100.4188</WindowsSdkBuildToolsNuget>
<WebView2Nuget>$(PathToRoot)packages\Microsoft.Web.WebView2.1.0.2903.40</WebView2Nuget>
</PropertyGroup>
<Import Project="$(WasdkNuget)\build\native\Microsoft.WindowsAppSDK.props" Condition="Exists('$(WasdkNuget)\build\native\Microsoft.WindowsAppSDK.props')" />
@@ -24,7 +24,7 @@
<ApplicationType>Windows Store</ApplicationType>
<ApplicationTypeRevision>10.0</ApplicationTypeRevision>
<WindowsTargetPlatformMinVersion>10.0.19041.0</WindowsTargetPlatformMinVersion>
<WindowsTargetPlatformVersion>10.0.22621.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0.26100.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<ItemGroup Label="ProjectConfigurations">

View File

@@ -2,6 +2,6 @@
<packages>
<package id="Microsoft.Web.WebView2" version="1.0.2903.40" targetFramework="native" />
<package id="Microsoft.Windows.CppWinRT" version="2.0.240111.5" targetFramework="native" />
<package id="Microsoft.Windows.SDK.BuildTools" version="10.0.22621.2428" targetFramework="native" />
<package id="Microsoft.Windows.SDK.BuildTools" version="10.0.26100.4188" targetFramework="native" />
<package id="Microsoft.WindowsAppSDK" version="1.7.250513003" targetFramework="native" />
</packages>

View File

@@ -107,21 +107,14 @@ namespace ColorPicker.Helpers
}
}
public void OnColorPickerMouseDown()
public void OpenColorEditor()
{
if (_userSettings.ActivationAction.Value == ColorPickerActivationAction.OpenColorPickerAndThenEditor || _userSettings.ActivationAction.Value == ColorPickerActivationAction.OpenEditor)
lock (_colorPickerVisibilityLock)
{
lock (_colorPickerVisibilityLock)
{
HideColorPicker();
}
HideColorPicker();
}
ShowColorPickerEditor();
}
else
{
EndUserSession();
}
ShowColorPickerEditor();
}
public static void SetTopMost()

View File

@@ -16,10 +16,12 @@ namespace ColorPicker.Mouse
// position and bool indicating zoom in or zoom out
event EventHandler<Tuple<System.Windows.Point, bool>> OnMouseWheel;
event MouseUpEventHandler OnMouseDown;
event PrimaryMouseDownEventHandler OnPrimaryMouseDown;
event SecondaryMouseUpEventHandler OnSecondaryMouseUp;
event MiddleMouseDownEventHandler OnMiddleMouseDown;
System.Windows.Point CurrentPosition { get; }
Color CurrentColor { get; }

View File

@@ -7,17 +7,18 @@ using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Input;
using ColorPicker.Helpers;
using ManagedCommon;
using static ColorPicker.NativeMethods;
namespace ColorPicker.Mouse
{
public delegate void MouseUpEventHandler(object sender, System.Drawing.Point p);
public delegate void PrimaryMouseDownEventHandler(object sender, IntPtr wParam);
public delegate void SecondaryMouseUpEventHandler(object sender, IntPtr wParam);
public delegate void MiddleMouseDownEventHandler(object sender, IntPtr wParam);
internal class MouseHook
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Interop object")]
@@ -30,23 +31,25 @@ namespace ColorPicker.Mouse
private const int WM_RBUTTONUP = 0x0205;
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Interop object")]
private const int WM_RBUTTONDOWN = 0x0204;
[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Interop object")]
private const int WM_MBUTTONDOWN = 0x0207;
private IntPtr _mouseHookHandle;
private HookProc _mouseDelegate;
private event MouseUpEventHandler MouseDown;
private event PrimaryMouseDownEventHandler PrimaryMouseDown;
public event MouseUpEventHandler OnMouseDown
public event PrimaryMouseDownEventHandler OnPrimaryMouseDown
{
add
{
Subscribe();
MouseDown += value;
PrimaryMouseDown += value;
}
remove
{
MouseDown -= value;
PrimaryMouseDown -= value;
Unsubscribe();
}
}
@@ -68,6 +71,23 @@ namespace ColorPicker.Mouse
}
}
private event MiddleMouseDownEventHandler MiddleMouseDown;
public event MiddleMouseDownEventHandler OnMiddleMouseDown
{
add
{
Subscribe();
MiddleMouseDown += value;
}
remove
{
MiddleMouseDown -= value;
Unsubscribe();
}
}
private event MouseWheelEventHandler MouseWheel;
public event MouseWheelEventHandler OnMouseWheel
@@ -126,9 +146,9 @@ namespace ColorPicker.Mouse
MSLLHOOKSTRUCT mouseHookStruct = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));
if (wParam.ToInt32() == WM_LBUTTONDOWN)
{
if (MouseDown != null)
if (PrimaryMouseDown != null)
{
MouseDown.Invoke(null, new System.Drawing.Point(mouseHookStruct.pt.x, mouseHookStruct.pt.y));
PrimaryMouseDown.Invoke(null, wParam);
}
return new IntPtr(-1);
@@ -150,6 +170,16 @@ namespace ColorPicker.Mouse
return new IntPtr(-1);
}
if (wParam.ToInt32() == WM_MBUTTONDOWN)
{
if (MiddleMouseDown != null)
{
MiddleMouseDown.Invoke(null, wParam);
}
return new IntPtr(-1);
}
if (wParam.ToInt32() == WM_MOUSEWHEEL)
{
if (MouseWheel != null)

View File

@@ -56,10 +56,12 @@ namespace ColorPicker.Mouse
public event EventHandler<Tuple<System.Windows.Point, bool>> OnMouseWheel;
public event MouseUpEventHandler OnMouseDown;
public event PrimaryMouseDownEventHandler OnPrimaryMouseDown;
public event SecondaryMouseUpEventHandler OnSecondaryMouseUp;
public event MiddleMouseDownEventHandler OnMiddleMouseDown;
public System.Windows.Point CurrentPosition
{
get
@@ -148,9 +150,10 @@ namespace ColorPicker.Mouse
_timer.Start();
}
_mouseHook.OnMouseDown += MouseHook_OnMouseDown;
_mouseHook.OnPrimaryMouseDown += MouseHook_OnPrimaryMouseDown;
_mouseHook.OnMouseWheel += MouseHook_OnMouseWheel;
_mouseHook.OnSecondaryMouseUp += MouseHook_OnSecondaryMouseUp;
_mouseHook.OnMiddleMouseDown += MouseHook_OnMiddleMouseDown;
if (_userSettings.ChangeCursor.Value)
{
@@ -169,10 +172,10 @@ namespace ColorPicker.Mouse
OnMouseWheel?.Invoke(this, new Tuple<System.Windows.Point, bool>(_previousMousePosition, zoomIn));
}
private void MouseHook_OnMouseDown(object sender, Point p)
private void MouseHook_OnPrimaryMouseDown(object sender, IntPtr wParam)
{
DisposeHook();
OnMouseDown?.Invoke(this, p);
OnPrimaryMouseDown?.Invoke(this, wParam);
}
private void MouseHook_OnSecondaryMouseUp(object sender, IntPtr wParam)
@@ -181,6 +184,12 @@ namespace ColorPicker.Mouse
OnSecondaryMouseUp?.Invoke(this, wParam);
}
private void MouseHook_OnMiddleMouseDown(object sender, IntPtr wParam)
{
DisposeHook();
OnMiddleMouseDown?.Invoke(this, wParam);
}
private void CopiedColorRepresentation_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
_colorFormatChanged = true;
@@ -194,9 +203,10 @@ namespace ColorPicker.Mouse
}
_previousMousePosition = new System.Windows.Point(-1, 1);
_mouseHook.OnMouseDown -= MouseHook_OnMouseDown;
_mouseHook.OnPrimaryMouseDown -= MouseHook_OnPrimaryMouseDown;
_mouseHook.OnMouseWheel -= MouseHook_OnMouseWheel;
_mouseHook.OnSecondaryMouseUp -= MouseHook_OnSecondaryMouseUp;
_mouseHook.OnMiddleMouseDown -= MouseHook_OnMiddleMouseDown;
if (_userSettings.ChangeCursor.Value)
{

View File

@@ -21,6 +21,12 @@ namespace ColorPicker.Settings
SettingItem<ColorPickerActivationAction> ActivationAction { get; }
SettingItem<ColorPickerClickAction> PrimaryClickAction { get; }
SettingItem<ColorPickerClickAction> MiddleClickAction { get; }
SettingItem<ColorPickerClickAction> SecondaryClickAction { get; }
RangeObservableCollection<string> ColorHistory { get; }
SettingItem<int> ColorHistoryLimit { get; }

View File

@@ -49,7 +49,10 @@ namespace ColorPicker.Settings
ChangeCursor = new SettingItem<bool>(true);
ActivationShortcut = new SettingItem<string>(DefaultActivationShortcut);
CopiedColorRepresentation = new SettingItem<string>(ColorRepresentationType.HEX.ToString());
ActivationAction = new SettingItem<ColorPickerActivationAction>(ColorPickerActivationAction.OpenEditor);
ActivationAction = new SettingItem<ColorPickerActivationAction>(ColorPickerActivationAction.OpenColorPicker);
PrimaryClickAction = new SettingItem<ColorPickerClickAction>(ColorPickerClickAction.PickColorThenEditor);
MiddleClickAction = new SettingItem<ColorPickerClickAction>(ColorPickerClickAction.PickColorAndClose);
SecondaryClickAction = new SettingItem<ColorPickerClickAction>(ColorPickerClickAction.Close);
ColorHistoryLimit = new SettingItem<int>(20);
ColorHistory.CollectionChanged += ColorHistory_CollectionChanged;
ShowColorName = new SettingItem<bool>(false);
@@ -78,6 +81,12 @@ namespace ColorPicker.Settings
public SettingItem<ColorPickerActivationAction> ActivationAction { get; private set; }
public SettingItem<ColorPickerClickAction> PrimaryClickAction { get; private set; }
public SettingItem<ColorPickerClickAction> MiddleClickAction { get; private set; }
public SettingItem<ColorPickerClickAction> SecondaryClickAction { get; private set; }
public RangeObservableCollection<string> ColorHistory { get; private set; } = new RangeObservableCollection<string>();
public SettingItem<int> ColorHistoryLimit { get; }
@@ -121,6 +130,9 @@ namespace ColorPicker.Settings
CopiedColorRepresentation.Value = settings.Properties.CopiedColorRepresentation;
CopiedColorRepresentationFormat = new SettingItem<string>(string.Empty);
ActivationAction.Value = settings.Properties.ActivationAction;
PrimaryClickAction.Value = settings.Properties.PrimaryClickAction;
MiddleClickAction.Value = settings.Properties.MiddleClickAction;
SecondaryClickAction.Value = settings.Properties.SecondaryClickAction;
ColorHistoryLimit.Value = settings.Properties.ColorHistoryLimit;
ShowColorName.Value = settings.Properties.ShowColorName;

View File

@@ -16,6 +16,7 @@ using ColorPicker.Settings;
using ColorPicker.ViewModelContracts;
using Common.UI;
using ManagedCommon;
using Microsoft.PowerToys.Settings.UI.Library.Enumerations;
using PowerToys.Interop;
namespace ColorPicker.ViewModels
@@ -79,9 +80,10 @@ namespace ColorPicker.ViewModels
{
SetColorDetails(mouseInfoProvider.CurrentColor);
mouseInfoProvider.MouseColorChanged += Mouse_ColorChanged;
mouseInfoProvider.OnMouseDown += MouseInfoProvider_OnMouseDown;
mouseInfoProvider.OnPrimaryMouseDown += MouseInfoProvider_OnPrimaryMouseDown;
mouseInfoProvider.OnMouseWheel += MouseInfoProvider_OnMouseWheel;
mouseInfoProvider.OnSecondaryMouseUp += MouseInfoProvider_OnSecondaryMouseUp;
mouseInfoProvider.OnMiddleMouseDown += MouseInfoProvider_OnMiddleMouseDown;
}
_userSettings.ShowColorName.PropertyChanged += (s, e) => { OnPropertyChanged(nameof(ShowColorName)); };
@@ -113,7 +115,7 @@ namespace ColorPicker.ViewModels
private void AppStateHandler_EnterPressed(object sender, EventArgs e)
{
MouseInfoProvider_OnMouseDown(null, default(System.Drawing.Point));
MouseInfoProvider_OnPrimaryMouseDown(null, default);
}
/// <summary>
@@ -167,18 +169,50 @@ namespace ColorPicker.ViewModels
SetColorDetails(color);
}
/// <summary>
/// Tell the color picker that the user have press a mouse button (after release the button)
/// </summary>
/// <param name="sender">The sender of this event</param>
/// <param name="p">The current <see cref="System.Drawing.Point"/> of the mouse cursor</param>
private void MouseInfoProvider_OnMouseDown(object sender, System.Drawing.Point p)
private void MouseInfoProvider_OnPrimaryMouseDown(object sender, IntPtr wParam)
{
ClipboardHelper.CopyToClipboard(ColorText);
HandleMouseClickAction(_userSettings.PrimaryClickAction.Value);
}
var color = GetColorString();
private void MouseInfoProvider_OnMiddleMouseDown(object sender, IntPtr wParam)
{
HandleMouseClickAction(_userSettings.MiddleClickAction.Value);
}
var oldIndex = _userSettings.ColorHistory.IndexOf(color);
private void MouseInfoProvider_OnSecondaryMouseUp(object sender, IntPtr wParam)
{
HandleMouseClickAction(_userSettings.SecondaryClickAction.Value);
}
private void HandleMouseClickAction(ColorPickerClickAction action)
{
switch (action)
{
case ColorPickerClickAction.PickColorThenEditor:
ClipboardHelper.CopyToClipboard(ColorText);
UpdateColorHistory(GetColorString());
_appStateHandler.OpenColorEditor();
break;
case ColorPickerClickAction.PickColorAndClose:
ClipboardHelper.CopyToClipboard(ColorText);
UpdateColorHistory(GetColorString());
_appStateHandler.EndUserSession();
break;
case ColorPickerClickAction.Close:
_appStateHandler.EndUserSession();
break;
}
}
private void UpdateColorHistory(string color)
{
int oldIndex = _userSettings.ColorHistory.IndexOf(color);
if (oldIndex != -1)
{
_userSettings.ColorHistory.Move(oldIndex, 0);
@@ -192,13 +226,6 @@ namespace ColorPicker.ViewModels
{
_userSettings.ColorHistory.RemoveAt(_userSettings.ColorHistory.Count - 1);
}
_appStateHandler.OnColorPickerMouseDown();
}
private void MouseInfoProvider_OnSecondaryMouseUp(object sender, IntPtr wParam)
{
_appStateHandler.EndUserSession();
}
private string GetColorString()

View File

@@ -4,7 +4,6 @@
using System;
using System.Runtime.CompilerServices;
using CommunityToolkit.Mvvm.ComponentModel;
using Microsoft.UI;
using Microsoft.UI.Xaml;
@@ -24,8 +23,8 @@ namespace Peek.FilePreviewer.Controls
private static readonly COLORREF LightThemeBgColor = new(0x00f3f3f3);
private static readonly COLORREF DarkThemeBgColor = new(0x00202020);
private static readonly HBRUSH LightThemeBgBrush = PInvoke.CreateSolidBrush(LightThemeBgColor);
private static readonly HBRUSH DarkThemeBgBrush = PInvoke.CreateSolidBrush(DarkThemeBgColor);
private static readonly HBRUSH LightThemeBgBrush = PInvoke_FilePreviewer.CreateSolidBrush(LightThemeBgColor);
private static readonly HBRUSH DarkThemeBgBrush = PInvoke_FilePreviewer.CreateSolidBrush(DarkThemeBgColor);
[ObservableProperty]
private IPreviewHandler? source;
@@ -88,19 +87,19 @@ namespace Peek.FilePreviewer.Controls
if (HandlerVisibility == Visibility.Visible)
{
PInvoke.ShowWindow(containerHwnd, SHOW_WINDOW_CMD.SW_SHOW);
PInvoke_FilePreviewer.ShowWindow(containerHwnd, SHOW_WINDOW_CMD.SW_SHOW);
IsEnabled = true;
// Clears the background from the last previewer
// The brush can only be drawn here because flashes will occur during resize
PInvoke.SetClassLongPtr(containerHwnd, GET_CLASS_LONG_INDEX.GCLP_HBRBACKGROUND, containerBgBrush);
PInvoke.UpdateWindow(containerHwnd);
PInvoke.SetClassLongPtr(containerHwnd, GET_CLASS_LONG_INDEX.GCLP_HBRBACKGROUND, IntPtr.Zero);
PInvoke.InvalidateRect(containerHwnd, (RECT*)null, true);
PInvoke_FilePreviewer.SetClassLongPtr(containerHwnd, GET_CLASS_LONG_INDEX.GCLP_HBRBACKGROUND, containerBgBrush);
PInvoke_FilePreviewer.UpdateWindow(containerHwnd);
PInvoke_FilePreviewer.SetClassLongPtr(containerHwnd, GET_CLASS_LONG_INDEX.GCLP_HBRBACKGROUND, IntPtr.Zero);
PInvoke_FilePreviewer.InvalidateRect(containerHwnd, (RECT*)null, true);
}
else
{
PInvoke.ShowWindow(containerHwnd, SHOW_WINDOW_CMD.SW_HIDE);
PInvoke_FilePreviewer.ShowWindow(containerHwnd, SHOW_WINDOW_CMD.SW_HIDE);
IsEnabled = false;
}
}
@@ -132,14 +131,14 @@ namespace Peek.FilePreviewer.Controls
visuals.SetTextColor(fgColor);
// Changing the previewer colors might not always redraw itself
PInvoke.InvalidateRect(containerHwnd, (RECT*)null, true);
PInvoke_FilePreviewer.InvalidateRect(containerHwnd, (RECT*)null, true);
}
}
private LRESULT ContainerWndProc(HWND hWnd, uint msg, WPARAM wParam, LPARAM lParam)
{
// Here for future use :)
return PInvoke.DefWindowProc(hWnd, msg, wParam, lParam);
return PInvoke_FilePreviewer.DefWindowProc(hWnd, msg, wParam, lParam);
}
private void EnsureContainerHwndCreated()
@@ -157,14 +156,14 @@ namespace Peek.FilePreviewer.Controls
fixed (char* pContainerClassName = "PeekShellPreviewHandlerContainer")
{
PInvoke.RegisterClass(new WNDCLASSW()
PInvoke_FilePreviewer.RegisterClass(new WNDCLASSW()
{
lpfnWndProc = containerWndProc,
lpszClassName = pContainerClassName,
});
// Create the container window to host the preview handler
containerHwnd = PInvoke.CreateWindowEx(
containerHwnd = PInvoke_FilePreviewer.CreateWindowEx(
WINDOW_EX_STYLE.WS_EX_LAYERED,
pContainerClassName,
null,
@@ -178,7 +177,7 @@ namespace Peek.FilePreviewer.Controls
HINSTANCE.Null);
// Allows the preview handlers to display properly
PInvoke.SetLayeredWindowAttributes(containerHwnd, default, byte.MaxValue, LAYERED_WINDOW_ATTRIBUTES_FLAGS.LWA_ALPHA);
PInvoke_FilePreviewer.SetLayeredWindowAttributes(containerHwnd, default, byte.MaxValue, LAYERED_WINDOW_ATTRIBUTES_FLAGS.LWA_ALPHA);
}
}
@@ -186,12 +185,12 @@ namespace Peek.FilePreviewer.Controls
{
EnsureContainerHwndCreated();
var dpi = (float)PInvoke.GetDpiForWindow(containerHwnd) / 96;
var dpi = (float)PInvoke_FilePreviewer.GetDpiForWindow(containerHwnd) / 96;
// Resize the container window
PInvoke.SetWindowPos(
PInvoke_FilePreviewer.SetWindowPos(
containerHwnd,
(HWND)0, // HWND_TOP
(HWND)(nint)0, // HWND_TOP
(int)(Math.Abs(args.EffectiveViewport.X) * dpi),
(int)(Math.Abs(args.EffectiveViewport.Y) * dpi),
(int)(ActualWidth * dpi),
@@ -210,7 +209,7 @@ namespace Peek.FilePreviewer.Controls
}
// Resizing the previewer might not always redraw itself
PInvoke.InvalidateRect(containerHwnd, (RECT*)null, false);
PInvoke_FilePreviewer.InvalidateRect(containerHwnd, (RECT*)null, false);
}
private void UserControl_GotFocus(object sender, RoutedEventArgs e)

View File

@@ -65,7 +65,7 @@
HorizontalAlignment="Center"
VerticalAlignment="Center"
Foreground="{StaticResource TextFillColorSecondaryBrush}"
Visibility="{x:Bind IsWarningMessageVisible(VideoPreviewer.MissingCodecName), Mode=OneWay}">
Visibility="{x:Bind IsWarningMessageVisible(VideoPreviewer, Previewer.State), Mode=OneWay}">
<Paragraph>
<Run Text="{x:Bind GetWarningMessage(VideoPreviewer.MissingCodecName), Mode=OneWay}" />
<Hyperlink Click="CodecSearchHyperlink_Click">

View File

@@ -150,9 +150,9 @@ namespace Peek.FilePreviewer
return isValidPreview ? Visibility.Visible : Visibility.Collapsed;
}
public Visibility IsWarningMessageVisible(string? missingCodecName)
public Visibility IsWarningMessageVisible(IPreviewer? previewer, PreviewState? state)
{
var shouldShow = !string.IsNullOrEmpty(missingCodecName);
var shouldShow = previewer is IVideoPreviewer videoPreviewer && MatchPreviewState(state, PreviewState.Loaded) && !string.IsNullOrEmpty(videoPreviewer.MissingCodecName);
return shouldShow ? Visibility.Visible : Visibility.Collapsed;
}

View File

@@ -1,4 +1,5 @@
{
"$schema": "https://aka.ms/CsWin32.schema.json",
"public": false
"$schema": "https://aka.ms/CsWin32.schema.json",
"public": false,
"className": "PInvoke_FilePreviewer"
}

View File

@@ -53,9 +53,9 @@ namespace Peek.FilePreviewer.Previewers.Helpers
}
}
public void Seek(long dlibMove, STREAM_SEEK dwOrigin, [Optional] ulong* plibNewPosition)
public void Seek(long dlibMove, SeekOrigin dwOrigin, [Optional] ulong* plibNewPosition)
{
long position = Stream.Seek(dlibMove, (SeekOrigin)dwOrigin);
long position = Stream.Seek(dlibMove, dwOrigin);
if (plibNewPosition != null)
{
*plibNewPosition = (ulong)position;
@@ -82,7 +82,7 @@ namespace Peek.FilePreviewer.Previewers.Helpers
throw new NotSupportedException();
}
public void LockRegion(ulong libOffset, ulong cb, uint dwLockType)
public void LockRegion(ulong libOffset, ulong cb, LOCKTYPE dwLockType)
{
throw new NotSupportedException();
}
@@ -92,7 +92,7 @@ namespace Peek.FilePreviewer.Previewers.Helpers
throw new NotSupportedException();
}
public void Stat(STATSTG* pstatstg, uint grfStatFlag)
public void Stat(STATSTG* pstatstg, STATFLAG grfStatFlag)
{
throw new NotSupportedException();
}

View File

@@ -93,7 +93,7 @@ namespace Peek.FilePreviewer.Previewers
// TODO: Figure out how to get it to run in a low integrity level
if (!HandlerFactories.TryGetValue(clsid, out var factory))
{
var hr = PInvoke.CoGetClassObject(clsid, CLSCTX.CLSCTX_LOCAL_SERVER, null, typeof(IClassFactory).GUID, out var pFactory);
var hr = PInvoke_FilePreviewer.CoGetClassObject(clsid, CLSCTX.CLSCTX_LOCAL_SERVER, null, typeof(IClassFactory).GUID, out var pFactory);
Marshal.ThrowExceptionForHR(hr);
// Storing the factory in memory helps makes the handlers load faster
@@ -149,7 +149,7 @@ namespace Peek.FilePreviewer.Previewers
}
else if (previewHandler is IInitializeWithItem initWithItem)
{
var hr = PInvoke.SHCreateItemFromParsingName(FileItem.Path, null, typeof(IShellItem).GUID, out var item);
var hr = PInvoke_FilePreviewer.SHCreateItemFromParsingName(FileItem.Path, null, typeof(IShellItem).GUID, out var item);
Marshal.ThrowExceptionForHR(hr);
initWithItem.Initialize((IShellItem)item, STGM_READ);

View File

@@ -48,21 +48,21 @@ namespace Peek.UI.Extensions
internal static HWND FindChildWindow(this HWND windowHandle, string className)
{
return PInvoke.FindWindowEx(windowHandle, HWND.Null, className, null);
return PInvoke_PeekUI.FindWindowEx(windowHandle, HWND.Null, className, null);
}
internal static Size GetMonitorSize(this HWND hwnd)
{
var monitor = PInvoke.MonitorFromWindow(hwnd, MONITOR_FROM_FLAGS.MONITOR_DEFAULTTONEAREST);
var monitor = PInvoke_PeekUI.MonitorFromWindow(hwnd, MONITOR_FROM_FLAGS.MONITOR_DEFAULTTONEAREST);
MONITORINFO info = default(MONITORINFO);
info.cbSize = 40;
PInvoke.GetMonitorInfo(monitor, ref info);
PInvoke_PeekUI.GetMonitorInfo(monitor, ref info);
return new Size(info.rcMonitor.Size.Width, info.rcMonitor.Size.Height);
}
internal static double GetMonitorScale(this HWND hwnd)
{
var dpi = PInvoke.GetDpiForWindow(hwnd);
var dpi = PInvoke_PeekUI.GetDpiForWindow(hwnd);
var scalingFactor = dpi / 96d;
return scalingFactor;
}

View File

@@ -28,12 +28,12 @@ namespace Peek.UI.Extensions
// If the window is maximized, restore to normal state before change its size
var placement = default(WINDOWPLACEMENT);
if (PInvoke.GetWindowPlacement(hwndToCenter, ref placement))
if (PInvoke_PeekUI.GetWindowPlacement(hwndToCenter, ref placement))
{
if (placement.showCmd == SHOW_WINDOW_CMD.SW_MAXIMIZE)
{
placement.showCmd = SHOW_WINDOW_CMD.SW_SHOWNORMAL;
if (!PInvoke.SetWindowPlacement(hwndToCenter, in placement))
if (!PInvoke_PeekUI.SetWindowPlacement(hwndToCenter, in placement))
{
Logger.LogError($"SetWindowPlacement failed with error {Marshal.GetLastWin32Error()}");
}
@@ -44,12 +44,12 @@ namespace Peek.UI.Extensions
Logger.LogError($"GetWindowPlacement failed with error {Marshal.GetLastWin32Error()}");
}
var monitor = PInvoke.MonitorFromWindow(hwndDesktop, MONITOR_FROM_FLAGS.MONITOR_DEFAULTTONEAREST);
var monitor = PInvoke_PeekUI.MonitorFromWindow(hwndDesktop, MONITOR_FROM_FLAGS.MONITOR_DEFAULTTONEAREST);
MONITORINFO info = default(MONITORINFO);
info.cbSize = 40;
PInvoke.GetMonitorInfo(monitor, ref info);
var dpi = PInvoke.GetDpiForWindow(new HWND(hwndDesktop));
PInvoke.GetWindowRect(hwndToCenter, out RECT windowRect);
PInvoke_PeekUI.GetMonitorInfo(monitor, ref info);
var dpi = PInvoke_PeekUI.GetDpiForWindow(new HWND((nint)hwndDesktop));
PInvoke_PeekUI.GetWindowRect(hwndToCenter, out RECT windowRect);
var scalingFactor = dpi / 96d;
var w = width.HasValue ? (int)(width * scalingFactor) : windowRect.right - windowRect.left;
var h = height.HasValue ? (int)(height * scalingFactor) : windowRect.bottom - windowRect.top;
@@ -63,7 +63,7 @@ namespace Peek.UI.Extensions
private static void SetWindowPosOrThrow(HWND hWnd, HWND hWndInsertAfter, int x, int y, int cx, int cy, SET_WINDOW_POS_FLAGS uFlags)
{
bool result = PInvoke.SetWindowPos(hWnd, hWndInsertAfter, x, y, cx, cy, uFlags);
bool result = PInvoke_PeekUI.SetWindowPos(hWnd, hWndInsertAfter, x, y, cx, cy, uFlags);
if (!result)
{
Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error());

View File

@@ -58,7 +58,7 @@ namespace Peek.UI.Helpers
object? oNull2 = null;
var serviceProvider = (IServiceProvider)shellWindows.FindWindowSW(ref oNull1, ref oNull2, SWC_DESKTOP, out int pHWND, SWFO_NEEDDISPATCH);
var shellBrowser = (IShellBrowser)serviceProvider.QueryService(PInvoke.SID_STopLevelBrowser, typeof(IShellBrowser).GUID);
var shellBrowser = (IShellBrowser)serviceProvider.QueryService(PInvoke_PeekUI.SID_STopLevelBrowser, typeof(IShellBrowser).GUID);
IShellItemArray? shellItemArray = GetShellItemArray(shellBrowser, onlySelectedFiles);
return shellItemArray;
@@ -81,7 +81,7 @@ namespace Peek.UI.Helpers
if (webBrowserApp.HWND == foregroundWindowHandle)
{
var serviceProvider = (IServiceProvider)webBrowserApp;
var shellBrowser = (IShellBrowser)serviceProvider.QueryService(PInvoke.SID_STopLevelBrowser, typeof(IShellBrowser).GUID);
var shellBrowser = (IShellBrowser)serviceProvider.QueryService(PInvoke_PeekUI.SID_STopLevelBrowser, typeof(IShellBrowser).GUID);
shellBrowser.GetWindow(out IntPtr shellBrowserHandle);
if (activeTab == shellBrowserHandle)
@@ -122,7 +122,7 @@ namespace Peek.UI.Helpers
GUITHREADINFO guiThreadInfo = new() { cbSize = (uint)Marshal.SizeOf<GUITHREADINFO>() };
// Get information for the foreground thread
if (PInvoke.GetGUIThreadInfo(0, ref guiThreadInfo))
if (PInvoke_PeekUI.GetGUIThreadInfo(0, ref guiThreadInfo))
{
return guiThreadInfo.hwndActive == hwnd && (guiThreadInfo.flags & GUITHREADINFO_FLAGS.GUI_CARETBLINKING) != 0;
}

View File

@@ -0,0 +1,5 @@
{
"$schema": "https://aka.ms/CsWin32.schema.json",
"public": false,
"className": "PInvoke_PeekUI"
}

Some files were not shown because too many files have changed in this diff Show More