Compare commits

...

20 Commits

Author SHA1 Message Date
Jeremy Sinclair
c77ce6ebe2 Update NOTICE.md 2025-05-13 15:59:15 -04:00
Jeremy Sinclair
49cdcc5e30 [Deps][CmdPal] Update System.Text.Json package version to 9.0.5 in Extension Template 2025-05-13 15:58:24 -04:00
Jeremy Sinclair
680e8f87e9 [Deps] Update NuGet Packages from 9.0.4 to 9.0.5 2025-05-13 15:57:50 -04:00
Mike Griese
8a07b7b560 Bump our telemetry package version (#39388)
Data collection is hard.

Our internal package, which was last bumped around August 2024,
mistakenly changed a load bearing string from `ETW_GROUP` to
`MSPG_GROUP`. The former sets the ETW group id. The later does nothing.

This PR represents bumping our dependency to the version with the fix.

Considering that none of our data for CmdPal worked anyways, I took the
opportunity to rename a bunch of our events that had totally generic
names.

Closes #38704

re: #38032
regressed around: #34078
2025-05-13 12:24:26 -05:00
leileizhang
f0a23ceaeb [Fuzzing test] Use valid areaPath in OneFuzz configuration (#39393) 2025-05-13 14:39:16 +08:00
Yu Leng
f2373cf259 [cmdpal] Add some logs for WinGet extension (#39329) 2025-05-13 13:46:37 +08:00
Gordon Lam
cfdcf91625 Update Areapath in tsa.json to align latest one (#39391) 2025-05-12 21:45:49 -05:00
Dustin L. Howett
2f678d1fb3 release: stop hardcoding version numbers for the telemetry package (#39390) 2025-05-12 18:27:29 -07:00
Kai Tao
f49625210c Add log for cmd pal ext to trace exceptions (#39326)
* Add log to trace error for apps.

* Add bookmark log

* registry exception log

* fix

* Added logger for cmdpal extensions.

Signed-off-by: Shawn Yuan <shuaiyuan@microsoft.com>

* remove noise

* Update

Signed-off-by: Shawn Yuan <shuaiyuan@microsoft.com>

* change log level

* change level

* Fix comments

* Fixed comments.

Signed-off-by: Shawn Yuan <shuaiyuan@microsoft.com>

* Resolve comments

Signed-off-by: Shawn Yuan <shuaiyuan@microsoft.com>

---------

Signed-off-by: Shawn Yuan <shuaiyuan@microsoft.com>
Co-authored-by: Shawn Yuan <shuaiyuan@microsoft.com>
2025-05-12 20:38:55 +08:00
leileizhang
602eef8830 [Fuzzing test] Use valid areaPath in OneFuzz configuration (#39368)
change areaPath for fuzzing test config
2025-05-12 17:18:49 +08:00
Yu Leng
13a6287dea [cmdpal] Fix winget cannot install after clicking "install" button issue (#39324)
init

Co-authored-by: Yu Leng (from Dev Box) <yuleng@microsoft.com>
2025-05-09 13:32:15 +08:00
Yu Leng
6cb852077a [cmdpal] Disable "ignore shortcut when full screen" by default (#39323)
disable by default

Co-authored-by: Yu Leng (from Dev Box) <yuleng@microsoft.com>
2025-05-09 12:24:53 +08:00
Shawn Yuan
cdc5f073f0 Fix settings crash issue when clicking "Open Cmdpal settings..." (#39322)
Signed-off-by: Shawn Yuan <shuaiyuan@microsoft.com>
2025-05-09 10:06:19 +08:00
Kayla Cinnamon
0427a7a7b0 Remove new label from command palette (#39318)
* remove new label from cmdpal

* fix xaml styling
2025-05-08 16:49:37 -07:00
Mike Griese
2d0d12f06c Bump toolkit version to 0.2.0 in template (#39292)
This bumps the version of the toolkit consumed by the template to 0.2.0

~Ironically, I have not yet published 0.2. I'm spinning that CI build currently. But I'll have that uploaded tomorrow morning at the latest~

EDIT: package is uploaded now
2025-05-07 16:52:26 -05:00
Mike Griese
06e5db6ff0 CmdPal: Actually observe Details (#39263)
Extensions can change the properties on their Details, and they should
be observable, but they weren't. This is because the ShellPage is
ultimately responsible for exposing the details, but it doesn't own the
details. The selected ListItemViewModel from the ListPage does.

This PR just adds a event handler on ListViewModel. We'll attach/detach
that handler to ListItemViewModels as the selection changes. In the body
of that handler, we'll let the ShellPage know when the details object
changes (by sending ShowDetails/HideDetails messages).

Closes #39216
2025-05-07 17:47:57 +08:00
Niels Laute
1a097ae09c [CmdPal] Open CmdPal settings from PT settings (#39262)
* Turning description into a hyperlink

* Update expect.txt

* Update CmdPalPage.xaml.cs

* update xaml format.

Signed-off-by: Shawn Yuan <shuai.yuan.zju@gmail.com>

* update.

Signed-off-by: Shawn Yuan <shuaiyuan@microsoft.com>

* Added logger

Signed-off-by: Shawn Yuan <shuai.yuan.zju@gmail.com>

* update

Signed-off-by: Shawn Yuan <shuai.yuan.zju@gmail.com>

---------

Signed-off-by: Shawn Yuan <shuai.yuan.zju@gmail.com>
Signed-off-by: Shawn Yuan <shuaiyuan@microsoft.com>
Co-authored-by: Shawn Yuan <shuai.yuan.zju@gmail.com>
Co-authored-by: Shawn Yuan <shuaiyuan@microsoft.com>
2025-05-07 16:34:03 +08:00
Mike Griese
980ca46cdb CmdPal: URI activate, rather than using shell:AppsFolder (#39269)
* Use a URI handler for launching

this is a test

* I think we can review this

* Add a settings URI too
2025-05-07 11:30:47 +08:00
Kai Tao
6a1999d601 [cmdpal] protect cmdpal from crash if adaptive card fails (#39264)
<!-- 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
     
Card = AdaptiveCard.FromJsonString(cardJson) is called in catch block, if it fails, app will crash.
2025-05-06 17:07:32 -05:00
Mike Griese
5655c61794 Lazy-fetch the settings for extensions (#38844)
This PR stops us from synchronously initializing the settings page for every extension (including built-in's) on startup. That incurs a small penalty that really adds up the more extensions a user has.

Instead, we'll now only initialize the `CommandSettings` object when we first actually need it. 

From a relatively unscientific test, this saves approximately 10% on the initialization of builtin commands, and for my setup, it trims about 28% off extension initialization (across all built-in's / extensions):

branch | Built-in load (ms) | Extension load (ms) | %Δ builtin | %Δ extensions | 
-- | -- | -- | -- | -- |
main | 1455 | 6867.6 | | |
this PR | 1309.2 | 4919 | -10.02% | -28.37%

Closes #38321
2025-05-06 04:58:44 -05:00
79 changed files with 669 additions and 214 deletions

View File

@@ -315,6 +315,7 @@ debugbreak
declatory
decryptor
Dedup
Deeplink
DEFAULTBOOTSTRAPPERINSTALLFOLDER
DEFAULTCOLOR
DEFAULTFLAGS
@@ -326,6 +327,7 @@ DEFAULTTONULL
DEFAULTTOPRIMARY
DEFERERASE
DEFPUSHBUTTON
DEFT
deinitialization
DELA
DELETEDKEYIMAGE
@@ -346,6 +348,7 @@ devmgmt
DEVMODE
DEVMODEW
devpal
DFX
DIALOGEX
digicert
dimm

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.PowerToys.Telemetry" version="2.0.2" />
<package id="Microsoft.PowerToys.Telemetry" version="2.0.3" />
</packages>

View File

@@ -3,5 +3,5 @@
"notificationAliases": ["powertoys@microsoft.com"],
"instanceUrl": "https://microsoft.visualstudio.com",
"projectName": "OS",
"areaPath": "OS\\Windows Client and Services\\WinPD\\DEEP-Developer Experience, Ecosystem and Partnerships\\DIVE\\PowerToys"
"areaPath": "OS\\Windows Client and Services\\WinPD\\DFX-Developer Fundamentals and Experiences\\DEFT\\PowerToys"
}

View File

@@ -112,10 +112,12 @@ extends:
# Prepare the localizations and telemetry config before the release build
- template: .pipelines/v2/templates/steps-fetch-and-prepare-localizations.yml@self
- script: |
call nuget.exe restore -configFile .pipelines/release-nuget.config -PackagesDirectory . .pipelines/packages.config || exit /b 1
move /Y "Microsoft.PowerToys.Telemetry.2.0.2\build\include\TraceLoggingDefines.h" "src\common\Telemetry\TraceLoggingDefines.h" || exit /b 1
move /Y "Microsoft.PowerToys.Telemetry.2.0.2\build\include\TelemetryBase.cs" "src\common\Telemetry\TelemetryBase.cs" || exit /b 1
- pwsh: |-
$ErrorActionPreference = 'Stop'
$PSNativeCommandUseErrorActionPreference = $true
& nuget.exe restore -configFile .pipelines/release-nuget.config -PackagesDirectory . .pipelines/packages.config
Move-Item -Force -Verbose "Microsoft.PowerToys.Telemetry.*\build\include\TraceLoggingDefines.h" "src\common\Telemetry\TraceLoggingDefines.h"
Move-Item -Force -Verbose "Microsoft.PowerToys.Telemetry.*\build\include\TelemetryBase.cs" "src\common\Telemetry\TelemetryBase.cs"
displayName: Emplace telemetry files
- stage: Build_SDK

View File

@@ -31,22 +31,22 @@
<!-- Including MessagePack to force version, since it's used by StreamJsonRpc but contains vulnerabilities. After StreamJsonRpc updates the version of MessagePack, we can upgrade StreamJsonRpc instead. -->
<PackageVersion Include="MessagePack" Version="3.1.3" />
<PackageVersion Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="9.0.0" />
<PackageVersion Include="Microsoft.Data.Sqlite" Version="9.0.4" />
<PackageVersion Include="Microsoft.Data.Sqlite" Version="9.0.5" />
<!-- Including Microsoft.Bcl.AsyncInterfaces to force version, since it's used by Microsoft.SemanticKernel. -->
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="9.0.4" />
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="9.0.5" />
<PackageVersion Include="Microsoft.Diagnostics.Tracing.TraceEvent" Version="3.1.16" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="9.0.4" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="9.0.4" />
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.4" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="9.0.4" />
<PackageVersion Include="Microsoft.Extensions.Hosting.WindowsServices" Version="9.0.4" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="9.0.5" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="9.0.5" />
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.5" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="9.0.5" />
<PackageVersion Include="Microsoft.Extensions.Hosting.WindowsServices" Version="9.0.5" />
<PackageVersion Include="Microsoft.SemanticKernel" Version="1.15.0" />
<PackageVersion Include="Microsoft.Toolkit.Uwp.Notifications" Version="7.1.2" />
<PackageVersion Include="Microsoft.Web.WebView2" Version="1.0.2903.40" />
<!-- Package Microsoft.Win32.SystemEvents 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.Drawing.Common but the 8.0.1 version wasn't published to nuget. -->
<PackageVersion Include="Microsoft.Win32.SystemEvents" Version="9.0.4" />
<PackageVersion Include="Microsoft.Win32.SystemEvents" Version="9.0.5" />
<PackageVersion Include="Microsoft.WindowsPackageManager.ComInterop" Version="1.10.340" />
<PackageVersion Include="Microsoft.Windows.Compatibility" Version="9.0.4" />
<PackageVersion Include="Microsoft.Windows.Compatibility" Version="9.0.5" />
<PackageVersion Include="Microsoft.Windows.CsWin32" Version="0.2.46-beta" />
<!-- 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. -->
<!--
@@ -72,28 +72,28 @@
<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. -->
<PackageVersion Include="System.CodeDom" Version="9.0.4" />
<PackageVersion Include="System.CodeDom" Version="9.0.5" />
<PackageVersion Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
<PackageVersion Include="System.ComponentModel.Composition" Version="9.0.4" />
<PackageVersion Include="System.Configuration.ConfigurationManager" Version="9.0.4" />
<PackageVersion Include="System.Data.OleDb" Version="9.0.4" />
<PackageVersion Include="System.ComponentModel.Composition" Version="9.0.5" />
<PackageVersion Include="System.Configuration.ConfigurationManager" Version="9.0.5" />
<PackageVersion Include="System.Data.OleDb" Version="9.0.5" />
<!-- Package System.Data.SqlClient added to force it as a dependency of Microsoft.Windows.Compatibility to the latest version available at this time. -->
<PackageVersion Include="System.Data.SqlClient" Version="4.8.6" />
<!-- Package System.Diagnostics.EventLog 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.Data.OleDb but the 8.0.1 version wasn't published to nuget. -->
<PackageVersion Include="System.Diagnostics.EventLog" Version="9.0.4" />
<PackageVersion Include="System.Diagnostics.EventLog" Version="9.0.5" />
<!-- Package System.Diagnostics.PerformanceCounter added as a hack for being able to exclude the runtime assets so they don't conflict with 8.0.11. -->
<PackageVersion Include="System.Diagnostics.PerformanceCounter" Version="9.0.4" />
<PackageVersion Include="System.Drawing.Common" Version="9.0.4" />
<PackageVersion Include="System.Diagnostics.PerformanceCounter" Version="9.0.5" />
<PackageVersion Include="System.Drawing.Common" Version="9.0.5" />
<PackageVersion Include="System.IO.Abstractions" Version="22.0.13" />
<PackageVersion Include="System.IO.Abstractions.TestingHelpers" Version="22.0.13" />
<PackageVersion Include="System.Management" Version="9.0.4" />
<PackageVersion Include="System.Management" Version="9.0.5" />
<PackageVersion Include="System.Net.Http" Version="4.3.4" />
<PackageVersion Include="System.Private.Uri" Version="4.3.2" />
<PackageVersion Include="System.Reactive" Version="6.0.1" />
<PackageVersion Include="System.Runtime.Caching" Version="9.0.4" />
<PackageVersion Include="System.ServiceProcess.ServiceController" Version="9.0.4" />
<PackageVersion Include="System.Text.Encoding.CodePages" Version="9.0.4" />
<PackageVersion Include="System.Text.Json" Version="9.0.4" />
<PackageVersion Include="System.Runtime.Caching" Version="9.0.5" />
<PackageVersion Include="System.ServiceProcess.ServiceController" Version="9.0.5" />
<PackageVersion Include="System.Text.Encoding.CodePages" Version="9.0.5" />
<PackageVersion Include="System.Text.Json" Version="9.0.5" />
<PackageVersion Include="System.Text.RegularExpressions" Version="4.3.1" />
<PackageVersion Include="UnicodeInformation" Version="2.6.0" />
<PackageVersion Include="UnitsNet" Version="5.56.0" />

View File

@@ -1453,22 +1453,22 @@ SOFTWARE.
- Mages 3.0.0
- Markdig.Signed 0.34.0
- MessagePack 3.1.3
- Microsoft.Bcl.AsyncInterfaces 9.0.4
- Microsoft.Bcl.AsyncInterfaces 9.0.5
- Microsoft.CodeAnalysis.NetAnalyzers 9.0.0
- Microsoft.Data.Sqlite 9.0.4
- Microsoft.Data.Sqlite 9.0.5
- Microsoft.Diagnostics.Tracing.TraceEvent 3.1.16
- Microsoft.DotNet.ILCompiler (A)
- Microsoft.Extensions.DependencyInjection 9.0.4
- Microsoft.Extensions.Hosting 9.0.4
- Microsoft.Extensions.Hosting.WindowsServices 9.0.4
- Microsoft.Extensions.Logging 9.0.4
- Microsoft.Extensions.Logging.Abstractions 9.0.4
- Microsoft.Extensions.DependencyInjection 9.0.5
- Microsoft.Extensions.Hosting 9.0.5
- Microsoft.Extensions.Hosting.WindowsServices 9.0.5
- Microsoft.Extensions.Logging 9.0.5
- Microsoft.Extensions.Logging.Abstractions 9.0.5
- Microsoft.NET.ILLink.Tasks (A)
- Microsoft.SemanticKernel 1.15.0
- Microsoft.Toolkit.Uwp.Notifications 7.1.2
- Microsoft.Web.WebView2 1.0.2903.40
- Microsoft.Win32.SystemEvents 9.0.4
- Microsoft.Windows.Compatibility 9.0.4
- Microsoft.Win32.SystemEvents 9.0.5
- Microsoft.Windows.Compatibility 9.0.5
- Microsoft.Windows.CsWin32 0.2.46-beta
- Microsoft.Windows.CsWinRT 2.2.0
- Microsoft.Windows.SDK.BuildTools 10.0.22621.2428
@@ -1487,25 +1487,25 @@ SOFTWARE.
- SharpCompress 0.37.2
- StreamJsonRpc 2.21.69
- StyleCop.Analyzers 1.2.0-beta.556
- System.CodeDom 9.0.4
- System.CodeDom 9.0.5
- System.CommandLine 2.0.0-beta4.22272.1
- System.ComponentModel.Composition 9.0.4
- System.Configuration.ConfigurationManager 9.0.4
- System.Data.OleDb 9.0.4
- System.ComponentModel.Composition 9.0.5
- System.Configuration.ConfigurationManager 9.0.5
- System.Data.OleDb 9.0.5
- System.Data.SqlClient 4.8.6
- System.Diagnostics.EventLog 9.0.4
- System.Diagnostics.PerformanceCounter 9.0.4
- System.Drawing.Common 9.0.4
- System.Diagnostics.EventLog 9.0.5
- System.Diagnostics.PerformanceCounter 9.0.5
- System.Drawing.Common 9.0.5
- System.IO.Abstractions 22.0.13
- System.IO.Abstractions.TestingHelpers 22.0.13
- System.Management 9.0.4
- System.Management 9.0.5
- System.Net.Http 4.3.4
- System.Private.Uri 4.3.2
- System.Reactive 6.0.1
- System.Runtime.Caching 9.0.4
- System.ServiceProcess.ServiceController 9.0.4
- System.Text.Encoding.CodePages 9.0.4
- System.Text.Json 9.0.4
- System.Runtime.Caching 9.0.5
- System.ServiceProcess.ServiceController 9.0.5
- System.Text.Encoding.CodePages 9.0.5
- System.Text.Json 9.0.5
- System.Text.RegularExpressions 4.3.1
- UnicodeInformation 2.6.0
- UnitsNet 5.56.0

View File

@@ -17,7 +17,7 @@
"org": "microsoft",
"project": "OS",
"AssignedTo": "leilzh@microsoft.com",
"AreaPath": "OS\\Windows Client and Services\\WinPD\\DEEP-Developer Experience, Ecosystem and Partnerships\\SHINE\\PowerToys",
"AreaPath": "OS\\Windows Client and Services\\WinPD\\DFX-Developer Fundamentals and Experiences\\DEFT\\SALT",
"IterationPath": "OS\\Future"
},
"jobNotificationEmail": "leilzh@microsoft.com",

View File

@@ -17,7 +17,7 @@
"org": "microsoft",
"project": "OS",
"AssignedTo": "mengyuanchen@microsoft.com",
"AreaPath": "OS\\Windows Client and Services\\WinPD\\DEEP-Developer Experience, Ecosystem and Partnerships\\SHINE\\PowerToys",
"AreaPath": "OS\\Windows Client and Services\\WinPD\\DFX-Developer Fundamentals and Experiences\\DEFT\\SALT",
"IterationPath": "OS\\Future"
},
"jobNotificationEmail": "mengyuanchen@microsoft.com",
@@ -58,7 +58,7 @@
"org": "microsoft",
"project": "OS",
"AssignedTo": "mengyuanchen@microsoft.com",
"AreaPath": "OS\\Windows Client and Services\\WinPD\\DEEP-Developer Experience, Ecosystem and Partnerships\\SHINE\\PowerToys",
"AreaPath": "OS\\Windows Client and Services\\WinPD\\DFX-Developer Fundamentals and Experiences\\DEFT\\SALT",
"IterationPath": "OS\\Future"
},
"jobNotificationEmail": "mengyuanchen@microsoft.com",
@@ -99,7 +99,7 @@
"org": "microsoft",
"project": "OS",
"AssignedTo": "mengyuanchen@microsoft.com",
"AreaPath": "OS\\Windows Client and Services\\WinPD\\DEEP-Developer Experience, Ecosystem and Partnerships\\SHINE\\PowerToys",
"AreaPath": "OS\\Windows Client and Services\\WinPD\\DFX-Developer Fundamentals and Experiences\\DEFT\\SALT",
"IterationPath": "OS\\Future"
},
"jobNotificationEmail": "mengyuanchen@microsoft.com",
@@ -140,7 +140,7 @@
"org": "microsoft",
"project": "OS",
"AssignedTo": "mengyuanchen@microsoft.com",
"AreaPath": "OS\\Windows Client and Services\\WinPD\\DEEP-Developer Experience, Ecosystem and Partnerships\\SHINE\\PowerToys",
"AreaPath": "OS\\Windows Client and Services\\WinPD\\DFX-Developer Fundamentals and Experiences\\DEFT\\SALT",
"IterationPath": "OS\\Future"
},
"jobNotificationEmail": "mengyuanchen@microsoft.com",

View File

@@ -217,10 +217,9 @@ public:
CmdPal::m_enabled.store(true);
std::wstring packageName = L"Microsoft.CommandPalette";
std::wstring launchPath = L"shell:AppsFolder\\Microsoft.CommandPalette_8wekyb3d8bbwe!App";
std::wstring launchPath = L"x-cmdpal://background";
#ifdef IS_DEV_BRANDING
packageName = L"Microsoft.CommandPalette.Dev";
launchPath = L"shell:AppsFolder\\Microsoft.CommandPalette.Dev_8wekyb3d8bbwe!App";
#endif
if (!package::GetRegisteredPackage(packageName, false).has_value())
@@ -269,7 +268,7 @@ public:
if (!firstEnableCall)
{
Logger::trace("Not first attempt, try to launch");
LaunchApp(launchPath, L"RunFromPT", false /*no elevated*/, false /*error pop up*/);
LaunchApp(launchPath, L"", false /*no elevated*/, false /*error pop up*/);
}
else
{
@@ -297,7 +296,7 @@ public:
int retry = 0;
do
{
auto launch_result = LaunchApp(path, L"RunFromPT", false, retry < max_retry);
auto launch_result = LaunchApp(path, L"", false, retry < max_retry);
if (launch_result)
{
Logger::info(L"CmdPal launched successfully after {} retries.", retry);

View File

@@ -3,7 +3,7 @@
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Microsoft.CommandPalette.Extensions" Version="0.1.0" />
<PackageVersion Include="Microsoft.CommandPalette.Extensions" Version="0.2.0" />
<PackageVersion Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="9.0.0-preview.24508.2" />
<PackageVersion Include="Microsoft.Web.WebView2" Version="1.0.2903.40" />
<PackageVersion Include="Microsoft.Windows.CsWin32" Version="0.2.46-beta" />
@@ -12,6 +12,6 @@
<PackageVersion Include="Microsoft.WindowsAppSDK" Version="1.7.250401001" />
<PackageVersion Include="Shmuelie.WinRTServer" Version="2.1.1" />
<PackageVersion Include="StyleCop.Analyzers" Version="1.2.0-beta.556" />
<PackageVersion Include="System.Text.Json" Version="9.0.3" />
<PackageVersion Include="System.Text.Json" Version="9.0.5" />
</ItemGroup>
</Project>

View File

@@ -128,7 +128,7 @@ public partial class CommandBarViewModel : ObservableObject,
// this comes in when the primary button is tapped
public void InvokePrimaryCommand()
{
PerformCommand(SecondaryCommand);
PerformCommand(PrimaryCommand);
}
// this comes in when the secondary button is tapped

View File

@@ -66,8 +66,10 @@ public sealed class CommandProviderWrapper
DisplayName = provider.DisplayName;
Icon = new(provider.Icon);
Icon.InitializeProperties();
// Note: explicitly not InitializeProperties()ing the settings here. If
// we do that, then we'd regress GH #38321
Settings = new(provider.Settings, this, _taskScheduler);
Settings.InitializeProperties();
Logger.LogDebug($"Initialized command provider {ProviderId}");
}
@@ -151,9 +153,11 @@ public sealed class CommandProviderWrapper
Icon = new(model.Icon);
Icon.InitializeProperties();
// Note: explicitly not InitializeProperties()ing the settings here. If
// we do that, then we'd regress GH #38321
Settings = new(model.Settings, this, _taskScheduler);
Settings.InitializeProperties();
// We do need to explicitly initialize commands though
InitializeCommands(commands, fallbacks, serviceProvider, pageContext);
Logger.LogDebug($"Loaded commands from {DisplayName} ({ProviderId})");
@@ -194,21 +198,6 @@ public sealed class CommandProviderWrapper
}
}
/* This is a View/ExtensionHost piece
* public void AllowSetForeground(bool allow)
{
if (!IsExtension)
{
return;
}
var iextn = extensionWrapper?.GetExtensionObject();
unsafe
{
PInvoke.CoAllowSetForegroundWindow(iextn);
}
}*/
public override bool Equals(object? obj) => obj is CommandProviderWrapper wrapper && isValid == wrapper.isValid;
public override int GetHashCode() => _commandProvider.GetHashCode();

View File

@@ -2,18 +2,25 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using ManagedCommon;
using Microsoft.CmdPal.UI.ViewModels.Models;
using Microsoft.CommandPalette.Extensions;
namespace Microsoft.CmdPal.UI.ViewModels;
public partial class CommandSettingsViewModel(ICommandSettings _unsafeSettings, CommandProviderWrapper provider, TaskScheduler mainThread)
public partial class CommandSettingsViewModel(ICommandSettings? _unsafeSettings, CommandProviderWrapper provider, TaskScheduler mainThread)
{
private readonly ExtensionObject<ICommandSettings> _model = new(_unsafeSettings);
public ContentPageViewModel? SettingsPage { get; private set; }
public void InitializeProperties()
public bool Initialized { get; private set; }
public bool HasSettings =>
_model.Unsafe != null && // We have a settings model AND
(!Initialized || SettingsPage != null); // we weren't initialized, OR we were, and we do have a settings page
private void UnsafeInitializeProperties()
{
var model = _model.Unsafe;
if (model == null)
@@ -27,4 +34,27 @@ public partial class CommandSettingsViewModel(ICommandSettings _unsafeSettings,
SettingsPage.InitializeProperties();
}
}
public void SafeInitializeProperties()
{
try
{
UnsafeInitializeProperties();
}
catch (Exception ex)
{
Logger.LogError($"Failed to load settings page", ex: ex);
}
Initialized = true;
}
public void DoOnUiThread(Action action)
{
Task.Factory.StartNew(
action,
CancellationToken.None,
TaskCreationOptions.None,
mainThread);
}
}

View File

@@ -6,6 +6,7 @@ using System.Text.Json;
using AdaptiveCards.ObjectModel.WinUI3;
using AdaptiveCards.Templating;
using CommunityToolkit.Mvvm.Messaging;
using ManagedCommon;
using Microsoft.CmdPal.UI.ViewModels.Messages;
using Microsoft.CmdPal.UI.ViewModels.Models;
using Microsoft.CommandPalette.Extensions;
@@ -28,43 +29,67 @@ public partial class ContentFormViewModel(IFormContent _form, WeakReference<IPag
public AdaptiveCardParseResult? Card { get; private set; }
private static string Serialize(string? s) =>
JsonSerializer.Serialize(s, JsonSerializationContext.Default.String);
private static bool TryBuildCard(
string templateJson,
string dataJson,
out AdaptiveCardParseResult? card,
out Exception? error)
{
card = null;
error = null;
try
{
var template = new AdaptiveCardTemplate(templateJson);
var cardJson = template.Expand(dataJson);
card = AdaptiveCard.FromJsonString(cardJson);
return true;
}
catch (Exception ex)
{
Logger.LogError("Error building card from template: {Message}", ex.Message);
error = ex;
return false;
}
}
public override void InitializeProperties()
{
var model = _formModel.Unsafe;
if (model == null)
if (model is null)
{
return;
}
try
{
TemplateJson = model.TemplateJson;
StateJson = model.StateJson;
DataJson = model.DataJson;
TemplateJson = model.TemplateJson;
StateJson = model.StateJson;
DataJson = model.DataJson;
AdaptiveCardTemplate template = new(TemplateJson);
var cardJson = template.Expand(DataJson);
Card = AdaptiveCard.FromJsonString(cardJson);
if (TryBuildCard(TemplateJson, DataJson, out var builtCard, out var renderingError))
{
Card = builtCard;
UpdateProperty(nameof(Card));
return;
}
catch (Exception e)
{
// If we fail to parse the card JSON, then display _our own card_
// with the exception
AdaptiveCardTemplate template = new(ErrorCardJson);
var serializeString = (string? s) => JsonSerializer.Serialize(s, JsonSerializationContext.Default.String);
// todo: we could probably stick Card.Errors in there too
var dataJson = $$"""
{
"error_message": {{serializeString(e.Message)}},
"error_stack": {{serializeString(e.StackTrace)}},
"inner_exception": {{serializeString(e.InnerException?.Message)}},
"template_json": {{serializeString(TemplateJson)}},
"data_json": {{serializeString(DataJson)}}
}
""";
var cardJson = template.Expand(dataJson);
Card = AdaptiveCard.FromJsonString(cardJson);
var errorPayload = $$"""
{
"error_message": {{Serialize(renderingError!.Message)}},
"error_stack": {{Serialize(renderingError.StackTrace)}},
"inner_exception": {{Serialize(renderingError.InnerException?.Message)}},
"template_json": {{Serialize(TemplateJson)}},
"data_json": {{Serialize(DataJson)}}
}
""";
if (TryBuildCard(ErrorCardJson, errorPayload, out var errorCard, out var _))
{
Card = errorCard;
UpdateProperty(nameof(Card));
return;
}
UpdateProperty(nameof(Card));

View File

@@ -61,6 +61,8 @@ public partial class ListViewModel : PageViewModel, IDisposable
private Task? _initializeItemsTask;
private CancellationTokenSource? _cancellationTokenSource;
private ListItemViewModel? _lastSelectedItem;
public override bool IsInitialized
{
get => base.IsInitialized; protected set
@@ -330,6 +332,11 @@ public partial class ListViewModel : PageViewModel, IDisposable
[RelayCommand]
private void UpdateSelectedItem(ListItemViewModel? item)
{
if (_lastSelectedItem != null)
{
_lastSelectedItem.PropertyChanged -= SelectedItemPropertyChanged;
}
if (item != null)
{
SetSelectedItem(item);
@@ -367,6 +374,43 @@ public partial class ListViewModel : PageViewModel, IDisposable
TextToSuggest = item.TextToSuggest;
});
_lastSelectedItem = item;
_lastSelectedItem.PropertyChanged += SelectedItemPropertyChanged;
}
private void SelectedItemPropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
{
var item = _lastSelectedItem;
if (item == null)
{
return;
}
// already on the UI thread here
switch (e.PropertyName)
{
case nameof(item.Command):
case nameof(item.SecondaryCommand):
case nameof(item.AllCommands):
case nameof(item.Name):
WeakReferenceMessenger.Default.Send<UpdateCommandBarMessage>(new(item));
break;
case nameof(item.Details):
if (ShowDetails && item.HasDetails)
{
WeakReferenceMessenger.Default.Send<ShowDetailsMessage>(new(item.Details));
}
else
{
WeakReferenceMessenger.Default.Send<HideDetailsMessage>();
}
break;
case nameof(item.TextToSuggest):
TextToSuggest = item.TextToSuggest;
break;
}
}
private void ClearSelectedItem()

View File

@@ -18,6 +18,8 @@ public partial class ProviderSettingsViewModel(
IServiceProvider _serviceProvider) : ObservableObject
{
private readonly SettingsModel _settings = _serviceProvider.GetService<SettingsModel>()!;
private readonly Lock _initializeSettingsLock = new();
private Task? _initializeSettingsTask;
public string DisplayName => _provider.DisplayName;
@@ -34,6 +36,9 @@ public partial class ProviderSettingsViewModel(
public IconInfoViewModel Icon => _provider.Icon;
[ObservableProperty]
public partial bool LoadingSettings { get; set; } = _provider.Settings?.HasSettings ?? false;
public bool IsEnabled
{
get => _providerSettings.IsEnabled;
@@ -56,15 +61,60 @@ public partial class ProviderSettingsViewModel(
}
}
private void Provider_CommandsChanged(CommandProviderWrapper sender, CommandPalette.Extensions.IItemsChangedEventArgs args)
/// <summary>
/// Gets a value indicating whether returns true if we have a settings page
/// that's initialized, or we are still working on initializing that
/// settings page. If we don't have a settings object, or that settings
/// object doesn't have a settings page, then we'll return false.
/// </summary>
public bool HasSettings
{
OnPropertyChanged(nameof(ExtensionSubtext));
OnPropertyChanged(nameof(TopLevelCommands));
get
{
if (_provider.Settings == null)
{
return false;
}
if (_provider.Settings.Initialized)
{
return _provider.Settings.HasSettings;
}
// settings still need to be loaded.
return LoadingSettings;
}
}
public bool HasSettings => _provider.Settings != null && _provider.Settings.SettingsPage != null;
/// <summary>
/// Gets will return the settings page, if we have one, and have initialized it.
/// If we haven't initialized it, this will kick off a thread to start
/// initializing it.
/// </summary>
public ContentPageViewModel? SettingsPage
{
get
{
if (_provider.Settings == null)
{
return null;
}
public ContentPageViewModel? SettingsPage => HasSettings ? _provider?.Settings?.SettingsPage : null;
if (_provider.Settings.Initialized)
{
LoadingSettings = false;
return _provider.Settings.SettingsPage;
}
// Don't load the settings if we're already working on it
lock (_initializeSettingsLock)
{
_initializeSettingsTask ??= Task.Run(InitializeSettingsPage);
}
return null;
}
}
[field: AllowNull]
public List<TopLevelViewModel> TopLevelCommands
@@ -90,4 +140,30 @@ public partial class ProviderSettingsViewModel(
}
private void Save() => SettingsModel.SaveSettings(_settings);
private void InitializeSettingsPage()
{
if (_provider.Settings == null)
{
return;
}
_provider.Settings.SafeInitializeProperties();
_provider.Settings.DoOnUiThread(() =>
{
// Changing these properties will try to update XAML, and that has
// to be handled on the UI thread, so we need to raise them on the
// UI thread
LoadingSettings = false;
OnPropertyChanged(nameof(HasSettings));
OnPropertyChanged(nameof(LoadingSettings));
OnPropertyChanged(nameof(SettingsPage));
});
}
private void Provider_CommandsChanged(CommandProviderWrapper sender, CommandPalette.Extensions.IItemsChangedEventArgs args)
{
OnPropertyChanged(nameof(ExtensionSubtext));
OnPropertyChanged(nameof(TopLevelCommands));
}
}

View File

@@ -40,7 +40,7 @@ public partial class SettingsModel : ObservableObject
public bool ShowSystemTrayIcon { get; set; } = true;
public bool IgnoreShortcutWhenFullscreen { get; set; } = true;
public bool IgnoreShortcutWhenFullscreen { get; set; }
public Dictionary<string, ProviderSettings> ProviderSettings { get; set; } = [];

View File

@@ -45,6 +45,9 @@ public partial class TopLevelCommandManager : ObservableObject,
public async Task<bool> LoadBuiltinsAsync()
{
var s = new Stopwatch();
s.Start();
_builtInCommands.Clear();
// Load built-In commands first. These are all in-proc, and
@@ -64,6 +67,10 @@ public partial class TopLevelCommandManager : ObservableObject,
}
}
s.Stop();
Logger.LogDebug($"Loading built-ins took {s.ElapsedMilliseconds}ms");
return true;
}

View File

@@ -73,26 +73,12 @@ public partial class App : Application
/// Invoked when the application is launched.
/// </summary>
/// <param name="args">Details about the launch request and process.</param>
protected override void OnLaunched(LaunchActivatedEventArgs args)
protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
{
AppWindow = new MainWindow();
var cmdArgs = Environment.GetCommandLineArgs();
var runFromPT = false;
foreach (var arg in cmdArgs)
{
if (arg == "RunFromPT")
{
runFromPT = true;
break;
}
}
if (!runFromPT)
{
AppWindow.Activate();
}
var activatedEventArgs = Microsoft.Windows.AppLifecycle.AppInstance.GetCurrent().GetActivatedEventArgs();
((MainWindow)AppWindow).HandleLaunch(activatedEventArgs);
}
/// <summary>

View File

@@ -3,7 +3,6 @@
// See the LICENSE file in the project root for more information.
using System.Diagnostics.Tracing;
using Microsoft.CommandPalette.Extensions;
using Microsoft.PowerToys.Telemetry;
using Microsoft.PowerToys.Telemetry.Events;
@@ -13,4 +12,9 @@ namespace Microsoft.CmdPal.UI.Events;
public class BeginInvoke : EventBase, IEvent
{
public PartA_PrivTags PartA_PrivTags => PartA_PrivTags.ProductAndServiceUsage;
public BeginInvoke()
{
EventName = "CmdPal_BeginInvoke";
}
}

View File

@@ -3,7 +3,6 @@
// See the LICENSE file in the project root for more information.
using System.Diagnostics.Tracing;
using Microsoft.CommandPalette.Extensions;
using Microsoft.PowerToys.Telemetry;
using Microsoft.PowerToys.Telemetry.Events;
@@ -13,4 +12,9 @@ namespace Microsoft.CmdPal.UI.Events;
public class ColdLaunch : EventBase, IEvent
{
public PartA_PrivTags PartA_PrivTags => PartA_PrivTags.ProductAndServiceUsage;
public ColdLaunch()
{
EventName = "CmdPal_ColdLaunch";
}
}

View File

@@ -3,7 +3,6 @@
// See the LICENSE file in the project root for more information.
using System.Diagnostics.Tracing;
using Microsoft.CommandPalette.Extensions;
using Microsoft.PowerToys.Telemetry;
using Microsoft.PowerToys.Telemetry.Events;
@@ -17,6 +16,8 @@ public class OpenPage : EventBase, IEvent
public OpenPage(int pageDepth)
{
PageDepth = pageDepth;
EventName = "CmdPal_OpenPage";
}
public PartA_PrivTags PartA_PrivTags => PartA_PrivTags.ProductAndServiceUsage;

View File

@@ -3,7 +3,6 @@
// See the LICENSE file in the project root for more information.
using System.Diagnostics.Tracing;
using Microsoft.CommandPalette.Extensions;
using Microsoft.PowerToys.Telemetry;
using Microsoft.PowerToys.Telemetry.Events;
@@ -13,4 +12,9 @@ namespace Microsoft.CmdPal.UI.Events;
public class ReactivateInstance : EventBase, IEvent
{
public PartA_PrivTags PartA_PrivTags => PartA_PrivTags.ProductAndServiceUsage;
public ReactivateInstance()
{
EventName = "CmdPal_ReactivateInstance";
}
}

View File

@@ -19,6 +19,8 @@ using Microsoft.UI.Composition.SystemBackdrops;
using Microsoft.UI.Input;
using Microsoft.UI.Windowing;
using Microsoft.UI.Xaml;
using Microsoft.Windows.AppLifecycle;
using Windows.ApplicationModel.Activation;
using Windows.Foundation;
using Windows.Graphics;
using Windows.UI;
@@ -240,7 +242,7 @@ public sealed partial class MainWindow : WindowEx,
unsafe
{
BOOL value = false;
PInvoke.DwmSetWindowAttribute(_hwnd, DWMWINDOWATTRIBUTE.DWMWA_CLOAK, (void*)&value, (uint)sizeof(BOOL));
PInvoke.DwmSetWindowAttribute(_hwnd, DWMWINDOWATTRIBUTE.DWMWA_CLOAK, &value, (uint)sizeof(BOOL));
}
PInvoke.SetForegroundWindow(hwnd);
@@ -320,7 +322,7 @@ public sealed partial class MainWindow : WindowEx,
unsafe
{
BOOL value = true;
PInvoke.DwmSetWindowAttribute(_hwnd, DWMWINDOWATTRIBUTE.DWMWA_CLOAK, (void*)&value, (uint)sizeof(BOOL));
PInvoke.DwmSetWindowAttribute(_hwnd, DWMWINDOWATTRIBUTE.DWMWA_CLOAK, &value, (uint)sizeof(BOOL));
}
}
@@ -423,6 +425,40 @@ public sealed partial class MainWindow : WindowEx,
}
}
public void HandleLaunch(AppActivationArguments? activatedEventArgs)
{
if (activatedEventArgs == null)
{
Summon(string.Empty);
return;
}
if (activatedEventArgs.Kind == Microsoft.Windows.AppLifecycle.ExtendedActivationKind.Protocol)
{
if (activatedEventArgs.Data is IProtocolActivatedEventArgs protocolArgs)
{
if (protocolArgs.Uri.ToString() is string uri)
{
// was the URI "x-cmdpal://background" ?
if (uri.StartsWith("x-cmdpal://background", StringComparison.OrdinalIgnoreCase))
{
// we're running, we don't want to activate our window. bail
return;
}
else if (uri.StartsWith("x-cmdpal://settings", StringComparison.OrdinalIgnoreCase))
{
WeakReferenceMessenger.Default.Send<OpenSettingsMessage>(new());
return;
}
}
return;
}
}
Activate();
}
public void Summon(string commandId) =>
// The actual showing and hiding of the window will be done by the

View File

@@ -39,6 +39,7 @@ WM_RBUTTONUP
WM_LBUTTONUP
WM_LBUTTONDBLCLK
MessageBox
DwmGetWindowAttribute
DwmSetWindowAttribute
DWM_CLOAKED_APP
DWM_CLOAKED_APP

View File

@@ -70,6 +70,13 @@
DisplayName="ms-resource:StartupTaskNameDev" />
</uap5:Extension>
<uap:Extension Category="windows.protocol">
<uap:Protocol Name="x-cmdpal">
<uap:Logo>Assets\StoreLogo.png</uap:Logo>
<uap:DisplayName>Command Palette Dev URI scheme</uap:DisplayName>
</uap:Protocol>
</uap:Extension>
</Extensions>
</Application>

View File

@@ -70,6 +70,14 @@
DisplayName="ms-resource:StartupTaskName" />
</uap5:Extension>
<uap:Extension Category="windows.protocol">
<uap:Protocol Name="x-cmdpal">
<uap:Logo>Assets\StoreLogo.png</uap:Logo>
<uap:DisplayName>Command Palette URI scheme</uap:DisplayName>
</uap:Protocol>
</uap:Extension>
</Extensions>
</Application>

View File

@@ -418,15 +418,20 @@ public sealed partial class ShellPage : Microsoft.UI.Xaml.Controls.Page,
{
_ = DispatcherQueue.TryEnqueue(() =>
{
if (_settingsWindow == null)
{
_settingsWindow = new SettingsWindow();
}
_settingsWindow.Activate();
OpenSettings();
});
}
public void OpenSettings()
{
if (_settingsWindow == null)
{
_settingsWindow = new SettingsWindow();
}
_settingsWindow.Activate();
}
public void Receive(ShowDetailsMessage message)
{
// TERRIBLE HACK TODO GH #245

View File

@@ -2,10 +2,14 @@
// 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.Runtime.InteropServices;
using ManagedCommon;
using Microsoft.CmdPal.UI.Events;
using Microsoft.PowerToys.Telemetry;
using Microsoft.Windows.AppLifecycle;
using Windows.Win32;
using Windows.Win32.Foundation;
using Windows.Win32.UI.WindowsAndMessaging;
namespace Microsoft.CmdPal.UI;
@@ -30,7 +34,33 @@ internal sealed class Program
return 0;
}
Logger.InitializeLogger("\\CmdPal\\Logs\\");
try
{
Logger.InitializeLogger("\\CmdPal\\Logs\\");
}
catch (COMException e)
{
// This is unexpected. For the sake of debugging:
// pop a message box
PInvoke.MessageBox(
(HWND)IntPtr.Zero,
$"Failed to initialize the logger. COMException: \r{e.Message}",
"Command Palette",
MESSAGEBOX_STYLE.MB_OK | MESSAGEBOX_STYLE.MB_ICONERROR);
return 0;
}
catch (Exception e2)
{
// This is unexpected. For the sake of debugging:
// pop a message box
PInvoke.MessageBox(
(HWND)IntPtr.Zero,
$"Failed to initialize the logger. Unknown Exception: \r{e2.Message}",
"Command Palette",
MESSAGEBOX_STYLE.MB_OK | MESSAGEBOX_STYLE.MB_ICONERROR);
return 0;
}
Logger.LogDebug($"Starting at {DateTime.UtcNow}");
PowerToysTelemetry.Log.WriteEvent(new CmdPalProcessStarted());
@@ -79,7 +109,9 @@ internal sealed class Program
if (thisApp.AppWindow is not null and
MainWindow mainWindow)
{
mainWindow.Summon(string.Empty);
mainWindow.HandleLaunch(args);
// mainWindow.Summon(string.Empty);
}
}
}

View File

@@ -2,7 +2,8 @@
"profiles": {
"Microsoft.CmdPal.UI (Package)": {
"commandName": "MsixPackage",
"nativeDebugging": false
"nativeDebugging": false,
"doNotLaunchApp": false
},
"Microsoft.CmdPal.UI (Unpackaged)": {
"commandName": "Project"

View File

@@ -113,7 +113,24 @@
Visibility="{x:Bind ViewModel.HasSettings}" />
<Frame x:Name="SettingsFrame" Visibility="{x:Bind ViewModel.HasSettings}">
<cmdpalUI:ContentPage ViewModel="{x:Bind ViewModel.SettingsPage, Mode=OneWay}" />
<controls:SwitchPresenter
HorizontalAlignment="Stretch"
TargetType="x:Boolean"
Value="{x:Bind ViewModel.LoadingSettings, Mode=OneWay}">
<controls:Case Value="True">
<ProgressRing
Width="36"
Height="36"
HorizontalAlignment="Center"
VerticalAlignment="Center"
IsIndeterminate="True" />
</controls:Case>
<controls:Case Value="False">
<cmdpalUI:ContentPage ViewModel="{x:Bind ViewModel.SettingsPage, Mode=OneWay}" />
</controls:Case>
</controls:SwitchPresenter>
</Frame>
<TextBlock

View File

@@ -2,8 +2,10 @@
// 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.Diagnostics;
using System.Threading.Tasks;
using ManagedCommon;
using Microsoft.CmdPal.Ext.Apps.Programs;
using Microsoft.CmdPal.Ext.Apps.Properties;
using Microsoft.CommandPalette.Extensions.Toolkit;
@@ -33,8 +35,9 @@ internal sealed partial class AppCommand : InvokableCommand
{
appManager.ActivateApplication(aumid, /*queryArguments*/ string.Empty, noFlags, out var unusedPid);
}
catch (System.Exception)
catch (System.Exception ex)
{
Logger.LogError(ex.Message);
}
}).ConfigureAwait(false);
}
@@ -46,7 +49,14 @@ internal sealed partial class AppCommand : InvokableCommand
// const ActivateOptions noFlags = ActivateOptions.None;
await Task.Run(() =>
{
Process.Start(new ProcessStartInfo(path) { UseShellExecute = true });
try
{
Process.Start(new ProcessStartInfo(path) { UseShellExecute = true });
}
catch (System.Exception ex)
{
Logger.LogError(ex.Message);
}
});
}

View File

@@ -5,6 +5,7 @@
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using ManagedCommon;
using Microsoft.CmdPal.Ext.Apps.Properties;
using Microsoft.CommandPalette.Extensions.Toolkit;
@@ -38,9 +39,9 @@ internal sealed partial class OpenInConsoleCommand : InvokableCommand
Process.Start(processStartInfo);
}
catch (Exception)
catch (Exception ex)
{
// Log.Exception($"Failed to open {Name} in console, {e.Message}", e, GetType());
Logger.LogError(ex.Message);
}
});
}

View File

@@ -4,6 +4,7 @@
using System;
using System.IO;
using ManagedCommon;
using Windows.Foundation.Metadata;
using Package = Windows.ApplicationModel.Package;

View File

@@ -7,7 +7,9 @@ using System.Collections.Generic;
using System.IO.Abstractions;
using System.Linq;
using System.Xml.Linq;
using ManagedCommon;
using Microsoft.CmdPal.Ext.Apps.Utils;
using Microsoft.CommandPalette.Extensions.Toolkit;
using Windows.Win32;
using Windows.Win32.Foundation;
using Windows.Win32.System.Com;
@@ -131,8 +133,9 @@ public partial class UWP
u = new UWP(p);
u.InitializeAppInfo(p.InstalledLocation);
}
catch (Exception )
catch (Exception ex)
{
Logger.LogError(ex.Message);
return Array.Empty<UWPApplication>();
}
@@ -161,8 +164,9 @@ public partial class UWP
var path = p.InstalledLocation;
return !f && !string.IsNullOrEmpty(path);
}
catch (Exception )
catch (Exception ex)
{
Logger.LogError(ex.Message);
return false;
}
});

View File

@@ -8,12 +8,14 @@ using System.IO.Abstractions;
using System.Linq;
using System.Text;
using System.Xml;
using ManagedCommon;
using Microsoft.CmdPal.Ext.Apps.Commands;
using Microsoft.CmdPal.Ext.Apps.Properties;
using Microsoft.CmdPal.Ext.Apps.Utils;
using Microsoft.CommandPalette.Extensions.Toolkit;
using static Microsoft.CmdPal.Ext.Apps.Utils.Native;
using PackageVersion = Microsoft.CmdPal.Ext.Apps.Programs.UWP.PackageVersion;
using Theme = Microsoft.CmdPal.Ext.Apps.Utils.Theme;
namespace Microsoft.CmdPal.Ext.Apps.Programs;
@@ -154,8 +156,9 @@ public class UWPApplication : IProgram
return true;
}
}
catch (Exception)
catch (Exception ex)
{
Logger.LogError(ex.Message);
}
}
}

View File

@@ -15,6 +15,7 @@ using System.Security;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Input;
using ManagedCommon;
using Microsoft.CmdPal.Ext.Apps.Commands;
using Microsoft.CmdPal.Ext.Apps.Properties;
using Microsoft.CmdPal.Ext.Apps.Utils;
@@ -239,10 +240,12 @@ public class Win32Program : IProgram
}
catch (Exception e) when (e is SecurityException || e is UnauthorizedAccessException)
{
Logger.LogError(e.Message);
return InvalidProgram;
}
catch (Exception)
catch (Exception e)
{
Logger.LogError(e.Message);
return InvalidProgram;
}
}
@@ -317,11 +320,13 @@ public class Win32Program : IProgram
}
catch (Exception e) when (e is SecurityException || e is UnauthorizedAccessException)
{
Logger.LogError(e.Message);
return InvalidProgram;
}
}
catch (Exception)
catch (Exception e)
{
Logger.LogError(e.Message);
return InvalidProgram;
}
}
@@ -374,15 +379,17 @@ public class Win32Program : IProgram
return program;
}
catch (System.IO.FileLoadException)
catch (System.IO.FileLoadException e)
{
Logger.LogError(e.Message);
return InvalidProgram;
}
// Only do a catch all in production. This is so make developer aware of any unhandled exception and add the exception handling in.
// Error caused likely due to trying to get the description of the program
catch (Exception)
catch (Exception e)
{
Logger.LogError(e.Message);
return InvalidProgram;
}
}
@@ -402,14 +409,17 @@ public class Win32Program : IProgram
}
catch (Exception e) when (e is SecurityException || e is UnauthorizedAccessException)
{
Logger.LogError(e.Message);
return InvalidProgram;
}
catch (FileNotFoundException)
catch (FileNotFoundException e)
{
Logger.LogError(e.Message);
return InvalidProgram;
}
catch (Exception)
catch (Exception e)
{
Logger.LogError(e.Message);
return InvalidProgram;
}
}
@@ -515,16 +525,19 @@ public class Win32Program : IProgram
{
files.AddRange(Directory.EnumerateFiles(currentDirectory, $"*.{suffix}", SearchOption.TopDirectoryOnly));
}
catch (DirectoryNotFoundException)
catch (DirectoryNotFoundException e)
{
Logger.LogError(e.Message);
}
}
}
catch (Exception e) when (e is SecurityException || e is UnauthorizedAccessException)
{
Logger.LogError(e.Message);
}
catch (Exception)
catch (Exception e)
{
Logger.LogError(e.Message);
}
try
@@ -548,9 +561,11 @@ public class Win32Program : IProgram
}
catch (Exception e) when (e is SecurityException || e is UnauthorizedAccessException)
{
Logger.LogError(e.Message);
}
catch (Exception)
catch (Exception e)
{
Logger.LogError(e.Message);
}
}
while (folderQueue.Count > 0);
@@ -682,6 +697,7 @@ public class Win32Program : IProgram
}
catch (Exception e) when (e is SecurityException || e is UnauthorizedAccessException)
{
Logger.LogError(e.Message);
return string.Empty;
}
}
@@ -769,8 +785,9 @@ public class Win32Program : IProgram
icoPath = ExpandEnvironmentVariables(redirectionPath);
return true;
}
catch (IOException)
catch (IOException e)
{
Logger.LogError(e.Message);
}
icoPath = null;
@@ -839,8 +856,9 @@ public class Win32Program : IProgram
return DeduplicatePrograms(programs.Concat(runCommandPrograms).Where(program => program?.Valid == true));
}
catch (Exception)
catch (Exception e)
{
Logger.LogError(e.Message);
return Array.Empty<Win32Program>();
}
}

View File

@@ -7,6 +7,7 @@ using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using ManagedCommon;
namespace Microsoft.CmdPal.Ext.Apps.Storage;
@@ -37,8 +38,9 @@ public class ListRepository<T> : IRepository<T>, IEnumerable<T>
_items = new ConcurrentDictionary<int, T>(list.ToDictionary(i => i.GetHashCode()));
#pragma warning restore CS8602 // Dereference of a possibly null reference.
}
catch (ArgumentException)
catch (ArgumentException ex)
{
Logger.LogInfo(ex.Message);
}
}

View File

@@ -4,8 +4,8 @@
using System;
using System.Linq;
using ManagedCommon;
using Microsoft.CmdPal.Ext.Apps.Programs;
using Microsoft.CmdPal.Ext.Apps.Storage;
using Microsoft.CmdPal.Ext.Apps.Utils;
using Windows.ApplicationModel;
@@ -93,8 +93,9 @@ internal sealed partial class PackageRepository : ListRepository<UWPApplication>
// InitializeAppInfo will throw if there is no AppxManifest.xml for the package.
// Note there are sometimes multiple packages per product and this doesn't necessarily mean that we haven't found the app.
// eg. "Could not find file 'C:\\Program Files\\WindowsApps\\Microsoft.WindowsTerminalPreview_2020.616.45.0_neutral_~_8wekyb3d8bbwe\\AppxManifest.xml'."
catch (System.IO.FileNotFoundException)
catch (System.IO.FileNotFoundException ex)
{
Logger.LogError(ex.Message);
}
}

View File

@@ -6,6 +6,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using ManagedCommon;
namespace Microsoft.CmdPal.Ext.Apps.Storage;
@@ -47,8 +48,9 @@ internal sealed partial class Win32ProgramFileSystemWatchers : IDisposable
{
Directory.GetFiles(path);
}
catch (Exception)
catch (Exception e)
{
Logger.LogError(e.Message);
invalidPaths.Add(path);
}
}

View File

@@ -9,6 +9,7 @@ using System.Collections.ObjectModel;
using System.IO;
using System.IO.Abstractions;
using System.Threading.Tasks;
using ManagedCommon;
using Microsoft.CmdPal.Ext.Apps.Programs;
using Win32Program = Microsoft.CmdPal.Ext.Apps.Programs.Win32Program;
@@ -132,8 +133,9 @@ internal sealed partial class Win32ProgramRepository : ListRepository<Programs.W
oldApp = Win32Program.GetAppFromPath(oldPath);
}
}
catch (Exception)
catch (Exception ex)
{
Logger.LogError(ex.Message);
}
// To remove the old app which has been renamed and to add the new application.
@@ -192,8 +194,9 @@ internal sealed partial class Win32ProgramRepository : ListRepository<Programs.W
app = Programs.Win32Program.GetAppFromPath(path);
}
}
catch (Exception)
catch (Exception ex)
{
Logger.LogError(ex.Message);
}
if (app != null)

View File

@@ -6,6 +6,7 @@ using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Text;
using ManagedCommon;
namespace Microsoft.CmdPal.Ext.Apps.Utils;
@@ -138,9 +139,9 @@ public class ShellLinkHelper : IShellLinkHelper
{
((IPersistFile)link).Load(path, STGM_READ);
}
catch (System.IO.FileNotFoundException)
catch (System.IO.FileNotFoundException ex)
{
// Log.Exception("Path could not be retrieved", ex, GetType(), path);
Logger.LogError(ex.Message);
return string.Empty;
}
@@ -163,9 +164,9 @@ public class ShellLinkHelper : IShellLinkHelper
((IShellLinkW)link).GetDescription(buffer, MAX_PATH);
Description = buffer.ToString();
}
catch (Exception)
catch (Exception ex)
{
// Log.Exception($"Failed to fetch description for {target}, {e.Message}", e, GetType());
Logger.LogError(ex.Message);
Description = string.Empty;
}

View File

@@ -9,6 +9,7 @@ using System.Linq;
using System.Text;
using System.Text.Json.Nodes;
using System.Text.RegularExpressions;
using ManagedCommon;
using Microsoft.CmdPal.Ext.Bookmarks.Properties;
using Microsoft.CommandPalette.Extensions.Toolkit;
using Windows.System;
@@ -101,7 +102,7 @@ internal sealed partial class BookmarkPlaceholderForm : FormContent
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"Error launching URL: {ex.Message}");
Logger.LogError(ex.Message);
}
return CommandResult.GoHome();

View File

@@ -7,6 +7,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using ManagedCommon;
using Microsoft.CmdPal.Ext.Bookmarks.Properties;
using Microsoft.CmdPal.Ext.Indexer;
using Microsoft.CommandPalette.Extensions;
@@ -97,8 +98,7 @@ public partial class BookmarksCommandProvider : CommandProvider
}
catch (Exception ex)
{
// debug log error
Debug.WriteLine($"Error loading commands: {ex.Message}");
Logger.LogError(ex.Message);
}
if (_bookmarks == null)

View File

@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System;
using ManagedCommon;
using Microsoft.CmdPal.Ext.Bookmarks.Properties;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;
@@ -34,7 +35,7 @@ internal sealed partial class OpenInTerminalCommand : InvokableCommand
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"Error launching Windows Terminal: {ex.Message}");
Logger.LogError(ex.Message);
}
return CommandResult.Dismiss();

View File

@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System;
using ManagedCommon;
using Microsoft.CommandPalette.Extensions.Toolkit;
using Windows.System;
@@ -44,7 +45,7 @@ public partial class UrlCommand : InvokableCommand
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"Error launching URL: {ex.Message}");
Logger.LogError(ex.Message);
}
return CommandResult.Dismiss();
@@ -87,9 +88,9 @@ public partial class UrlCommand : InvokableCommand
return faviconUrl;
}
}
catch (UriFormatException)
catch (UriFormatException ex)
{
// return "🔗";
Logger.LogError(ex.Message);
}
return "🔗";

View File

@@ -9,6 +9,7 @@ using System.Linq;
using System.Resources;
using System.Text;
using System.Threading.Tasks;
using ManagedCommon;
using Microsoft.CmdPal.Ext.Registry.Classes;
using Microsoft.CmdPal.Ext.Registry.Helpers;
using Microsoft.CmdPal.Ext.Registry.Properties;
@@ -37,7 +38,7 @@ internal sealed partial class OpenKeyInEditorCommand : InvokableCommand
RegistryHelper.OpenRegistryKey(entry.Key?.Name ?? entry.KeyPath);
return true;
}
catch (System.ComponentModel.Win32Exception)
catch (System.ComponentModel.Win32Exception ex)
{
// TODO GH #118 We need a convenient way to show errors to a user
// MessageBox.Show(
@@ -45,13 +46,13 @@ internal sealed partial class OpenKeyInEditorCommand : InvokableCommand
// Resources.OpenInRegistryEditorAccessExceptionTitle,
// MessageBoxButton.OK,
// MessageBoxImage.Error);
Logger.LogError(ex.Message);
return false;
}
#pragma warning disable CS0168, IDE0059
catch (Exception exception)
{
// TODO GH #108: Logging
// Log.Exception("Error on opening Windows registry editor", exception, typeof(Main));
Logger.LogError(exception.Message);
return false;
}
#pragma warning restore CS0168, IDE0059

View File

@@ -7,7 +7,7 @@ using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using ManagedCommon;
using Microsoft.CmdPal.Ext.Registry.Classes;
using Microsoft.CmdPal.Ext.Registry.Constants;
using Microsoft.CmdPal.Ext.Registry.Properties;

View File

@@ -5,7 +5,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using ManagedCommon;
using Microsoft.CmdPal.Ext.Registry.Classes;
using Microsoft.CmdPal.Ext.Registry.Commands;
using Microsoft.CmdPal.Ext.Registry.Constants;
@@ -96,6 +96,7 @@ internal static class ResultHelper
}
catch (Exception valueException)
{
Logger.LogError(valueException.Message);
var registryEntry = new RegistryEntry(key.Name, valueException);
resultList.Add(new ListItem(new OpenKeyInEditorCommand(registryEntry))

View File

@@ -14,6 +14,7 @@
<PackageReference Include="System.ServiceProcess.ServiceController" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\common\ManagedCommon\ManagedCommon.csproj" />
<ProjectReference Include="..\..\extensionsdk\Microsoft.CommandPalette.Extensions.Toolkit\Microsoft.CommandPalette.Extensions.Toolkit.csproj" />
</ItemGroup>
<ItemGroup>

View File

@@ -7,6 +7,7 @@ using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text.RegularExpressions;
using ManagedCommon;
namespace Microsoft.CmdPal.Ext.TimeDate.Helpers;
@@ -109,10 +110,11 @@ internal static class AvailableResultsList
{
value = dtObject.ToString(value, CultureInfo.CurrentCulture);
}
catch
catch (Exception ex)
{
if (!containsCustomSyntax)
{
Logger.LogError($"Unable to format date time with format: {value}. Error: {ex.Message}");
throw;
}
else
@@ -133,6 +135,7 @@ internal static class AvailableResultsList
}
catch (ArgumentOutOfRangeException e)
{
Logger.LogError($"ArgumentOutOfRangeException with format: {formatSyntax}. Error: {e.Message}");
results.Add(new AvailableResult()
{
Value = Resources.Microsoft_plugin_timedate_ErrorConvertCustomFormat,
@@ -144,6 +147,7 @@ internal static class AvailableResultsList
}
catch (Exception e)
{
Logger.LogError($"Exception with format: {formatSyntax}. Error: {e.Message}");
results.Add(new AvailableResult()
{
Value = Resources.Microsoft_plugin_timedate_InvalidCustomFormat + " " + formatSyntax,
@@ -325,8 +329,9 @@ internal static class AvailableResultsList
IconType = ResultIconType.DateTime,
});
}
catch
catch (Exception ex)
{
Logger.LogError($"Unable to convert to Windows file time: {ex.Message}");
results.Add(new AvailableResult()
{
Value = Resources.Microsoft_plugin_timedate_ErrorConvertWft,

View File

@@ -6,6 +6,7 @@ using System;
using System.Globalization;
using System.Text;
using System.Text.RegularExpressions;
using ManagedCommon;
namespace Microsoft.CmdPal.Ext.TimeDate.Helpers;
@@ -166,6 +167,7 @@ internal static class TimeAndDateHelper
if (DateTime.TryParse(input, out timestamp))
{
// Known date/time format
Logger.LogDebug($"Successfully parsed standard date/time format: '{input}' as {timestamp}");
return true;
}
else if (Regex.IsMatch(input, @"^u[\+-]?\d+$"))
@@ -179,10 +181,12 @@ internal static class TimeAndDateHelper
{
inputParsingErrorMsg = string.Format(CultureInfo.CurrentCulture, errorMessage, Resources.Microsoft_plugin_timedate_Unix, UnixTimeSecondsMin, UnixTimeSecondsMax);
timestamp = new DateTime(1, 1, 1, 1, 1, 1);
Logger.LogError($"Failed to parse unix timestamp: '{input}'. Value out of range.");
return false;
}
timestamp = DateTimeOffset.FromUnixTimeSeconds(secondsU).LocalDateTime;
Logger.LogDebug($"Successfully parsed unix timestamp: '{input}' as {timestamp}");
return true;
}
else if (Regex.IsMatch(input, @"^ums[\+-]?\d+$"))
@@ -196,10 +200,12 @@ internal static class TimeAndDateHelper
{
inputParsingErrorMsg = string.Format(CultureInfo.CurrentCulture, errorMessage, Resources.Microsoft_plugin_timedate_Unix_Milliseconds, UnixTimeMillisecondsMin, UnixTimeMillisecondsMax);
timestamp = new DateTime(1, 1, 1, 1, 1, 1);
Logger.LogError($"Failed to parse unix millisecond timestamp: '{input}'. Value out of range.");
return false;
}
timestamp = DateTimeOffset.FromUnixTimeMilliseconds(millisecondsUms).LocalDateTime;
Logger.LogDebug($"Successfully parsed unix millisecond timestamp: '{input}' as {timestamp}");
return true;
}
else if (Regex.IsMatch(input, @"^ft\d+$"))
@@ -212,11 +218,13 @@ internal static class TimeAndDateHelper
{
inputParsingErrorMsg = string.Format(CultureInfo.CurrentCulture, errorMessage, Resources.Microsoft_plugin_timedate_WindowsFileTime, WindowsFileTimeMin, WindowsFileTimeMax);
timestamp = new DateTime(1, 1, 1, 1, 1, 1);
Logger.LogError($"Failed to parse Windows file time: '{input}'. Value out of range.");
return false;
}
// DateTime.FromFileTime returns as local time.
timestamp = DateTime.FromFileTime(secondsFt);
Logger.LogDebug($"Successfully parsed Windows file time: '{input}' as {timestamp}");
return true;
}
else if (Regex.IsMatch(input, @"^oa[+-]?\d+[,.0-9]*$"))
@@ -230,10 +238,12 @@ internal static class TimeAndDateHelper
{
inputParsingErrorMsg = string.Format(CultureInfo.CurrentCulture, errorMessage, Resources.Microsoft_plugin_timedate_OADate, OADateMin, OADateMax);
timestamp = new DateTime(1, 1, 1, 1, 1, 1);
Logger.LogError($"Failed to parse OLE Automation date: '{input}'. Value out of range.");
return false;
}
timestamp = DateTime.FromOADate(oADate);
Logger.LogDebug($"Successfully parsed OLE Automation date: '{input}' as {timestamp}");
return true;
}
else if (Regex.IsMatch(input, @"^exc[+-]?\d+[,.0-9]*$"))
@@ -249,6 +259,7 @@ internal static class TimeAndDateHelper
// For the if itself we use 0 as min value that we can show a special message if input is 0.
inputParsingErrorMsg = string.Format(CultureInfo.CurrentCulture, errorMessage, Resources.Microsoft_plugin_timedate_Excel1900, Excel1900DateMin, Excel1900DateMax);
timestamp = new DateTime(1, 1, 1, 1, 1, 1);
Logger.LogError($"Failed to parse Excel 1900 date value: '{input}'. Value out of range.");
return false;
}
@@ -256,11 +267,13 @@ internal static class TimeAndDateHelper
{
inputParsingErrorMsg = Resources.Microsoft_plugin_timedate_InvalidInput_FakeExcel1900;
timestamp = new DateTime(1, 1, 1, 1, 1, 1);
Logger.LogError($"Failed to parse Excel 1900 date value: '{input}'. Invalid date (0 or 60).");
return false;
}
excDate = excDate <= 60 ? excDate + 1 : excDate;
timestamp = DateTime.FromOADate(excDate);
Logger.LogDebug($"Successfully parsed Excel 1900 date value: '{input}' as {timestamp}");
return true;
}
else if (Regex.IsMatch(input, @"^exf[+-]?\d+[,.0-9]*$"))
@@ -275,15 +288,18 @@ internal static class TimeAndDateHelper
{
inputParsingErrorMsg = string.Format(CultureInfo.CurrentCulture, errorMessage, Resources.Microsoft_plugin_timedate_Excel1904, Excel1904DateMin, Excel1904DateMax);
timestamp = new DateTime(1, 1, 1, 1, 1, 1);
Logger.LogError($"Failed to parse Excel 1904 date value: '{input}'. Value out of range.");
return false;
}
timestamp = DateTime.FromOADate(exfDate + 1462);
Logger.LogDebug($"Successfully parsed Excel 1904 date value: '{input}' as {timestamp}");
return true;
}
else
{
timestamp = new DateTime(1, 1, 1, 1, 1, 1);
Logger.LogWarning($"Failed to parse input: '{input}'. Format not recognized.");
return false;
}
}

View File

@@ -19,6 +19,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\common\ManagedCommon\ManagedCommon.csproj" />
<ProjectReference Include="..\..\extensionsdk\Microsoft.CommandPalette.Extensions.Toolkit\Microsoft.CommandPalette.Extensions.Toolkit.csproj" />
</ItemGroup>

View File

@@ -5,6 +5,7 @@
using System;
using System.Text;
using System.Threading;
using ManagedCommon;
namespace Microsoft.CmdPal.Ext.WebSearch.Helpers;
@@ -170,6 +171,7 @@ public static class DefaultBrowserInfo
if (!_errorLogged)
{
// Log.Exception("Exception when retrieving browser path/name. Path and Name are set to use Microsoft Edge.", e, typeof(DefaultBrowserInfo));
Logger.LogError("Exception when retrieving browser path/name. Path and Name are set to use Microsoft Edge.");
_errorLogged = true;
}
}

View File

@@ -10,6 +10,7 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\common\ManagedCommon\ManagedCommon.csproj" />
<ProjectReference Include="..\..\extensionsdk\Microsoft.CommandPalette.Extensions.Toolkit\Microsoft.CommandPalette.Extensions.Toolkit.csproj" />
</ItemGroup>

View File

@@ -156,7 +156,22 @@ public partial class InstallPackageListItem : ListItem
private async void UpdatedInstalledStatus()
{
var status = await _package.CheckInstalledStatusAsync();
try
{
var status = await _package.CheckInstalledStatusAsync();
}
catch (OperationCanceledException)
{
// DO NOTHING HERE
return;
}
catch (Exception ex)
{
// Handle other exceptions
ExtensionHost.LogMessage($"[WinGet] UpdatedInstalledStatus throw exception: {ex.Message}");
return;
}
var isInstalled = _package.InstalledVersion != null;
var installedState = isInstalled ?

View File

@@ -57,7 +57,7 @@ internal sealed partial class WinGetExtensionPage : DynamicListPage, IDisposable
{
// emptySearchForTag ===
// we don't have results yet, we haven't typed anything, and we're searching for a tag
bool emptySearchForTag = _results == null &&
var emptySearchForTag = _results == null &&
string.IsNullOrEmpty(SearchText) &&
HasTag;
@@ -116,8 +116,22 @@ internal sealed partial class WinGetExtensionPage : DynamicListPage, IDisposable
IsLoading = true;
// Save the latest search task
_currentSearchTask = DoSearchAsync(newSearch, cancellationToken);
try
{
// Save the latest search task
_currentSearchTask = DoSearchAsync(newSearch, cancellationToken);
}
catch (OperationCanceledException)
{
// DO NOTHING HERE
return;
}
catch (Exception ex)
{
// Handle other exceptions
ExtensionHost.LogMessage($"[WinGet] DoUpdateSearchText throw exception: {ex.Message}");
return;
}
// Await the task to ensure only the latest one gets processed
_ = ProcessSearchResultsAsync(_currentSearchTask, newSearch);

View File

@@ -13,6 +13,7 @@
<None Remove="Assets\WindowWalker.svg" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\common\ManagedCommon\ManagedCommon.csproj" />
<ProjectReference Include="..\..\extensionsdk\Microsoft.CommandPalette.Extensions.Toolkit\Microsoft.CommandPalette.Extensions.Toolkit.csproj" />
</ItemGroup>
<ItemGroup>

View File

@@ -8,6 +8,7 @@ using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using ManagedCommon;
using Microsoft.CmdPal.Ext.WindowsServices.Commands;
using Microsoft.CmdPal.Ext.WindowsServices.Properties;
using Microsoft.CommandPalette.Extensions.Toolkit;
@@ -147,12 +148,14 @@ public static class ServiceHelper
// TODO GH #108 We need to figure out some logging
// contextAPI.ShowNotification(GetLocalizedErrorMessage(action), serviceResult.DisplayName);
// Log.Error($"The command returned {exitCode}", MethodBase.GetCurrentMethod().DeclaringType);
Logger.LogError($"The command returned {exitCode}");
}
}
catch (Win32Exception ex)
{
// TODO GH #108 We need to figure out some logging
// Log.Error(ex.Message, MethodBase.GetCurrentMethod().DeclaringType);
Logger.LogError($"Failed to change service '{serviceResult.DisplayName}' status to {action}: {ex.Message}");
}
}
#pragma warning restore IDE0059, CS0168, SA1005
@@ -173,6 +176,7 @@ public static class ServiceHelper
catch (Exception ex)
{
// TODO GH #108 We need to figure out some logging
Logger.LogError($"Failed to open services.msc: {ex.Message}");
}
}
#pragma warning restore IDE0059, CS0168, SA1005

View File

@@ -17,6 +17,7 @@
<PackageReference Include="System.ServiceProcess.ServiceController" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\common\ManagedCommon\ManagedCommon.csproj" />
<ProjectReference Include="..\..\extensionsdk\Microsoft.CommandPalette.Extensions.Toolkit\Microsoft.CommandPalette.Extensions.Toolkit.csproj" />
</ItemGroup>
<ItemGroup>

View File

@@ -4,6 +4,7 @@
using System;
using System.ServiceProcess;
using ManagedCommon;
namespace Microsoft.CmdPal.Ext.WindowsServices;
@@ -35,10 +36,11 @@ public class ServiceResult
return result;
}
catch (Exception)
catch (Exception ex)
{
// try to log the exception in the future
// retrieve properties from serviceController will throw exception. Such as PlatformNotSupportedException.
Logger.LogError($"Failed to create ServiceController: {ex.GetType().Name} - {ex.Message}");
}
return null;

View File

@@ -6,6 +6,7 @@ using System;
using System.IO;
using System.Reflection;
using System.Text.Json;
using ManagedCommon;
namespace Microsoft.CmdPal.Ext.WindowsSettings.Helpers;
@@ -60,6 +61,7 @@ internal static class JsonSettingsListHelper
{
// TODO GH #108 Logging is something we have to take care of
// Log.Exception("Error loading settings JSON file", exception, typeof(JsonSettingsListHelper));
Logger.LogError($"Error loading settings JSON file: {exception.Message}");
}
#pragma warning restore CS0168
return settings ?? new Classes.WindowsSettings();

View File

@@ -7,6 +7,7 @@ using System.Collections.ObjectModel;
using System.Globalization;
using System.Linq;
using ManagedCommon;
using Microsoft.CmdPal.Ext.WindowsSettings.Properties;
namespace Microsoft.CmdPal.Ext.WindowsSettings.Helpers;
@@ -36,6 +37,7 @@ internal static class TranslationHelper
if (string.IsNullOrEmpty(name))
{
// Log.Warn($"Resource string for [{settings.Name}] not found", typeof(TranslationHelper));
Logger.LogWarning($"Resource string for [{settings.Name}] not found");
}
settings.Name = name ?? settings.Name ?? string.Empty;
@@ -48,6 +50,7 @@ internal static class TranslationHelper
if (string.IsNullOrEmpty(type))
{
// Log.Warn($"Resource string for [{settings.Type}] not found", typeof(TranslationHelper));
Logger.LogWarning($"Resource string for [{settings.Type}] not found");
}
settings.Type = type ?? settings.Type ?? string.Empty;
@@ -69,6 +72,7 @@ internal static class TranslationHelper
if (string.IsNullOrEmpty(translatedArea))
{
// Log.Warn($"Resource string for [{area}] not found", typeof(TranslationHelper));
Logger.LogWarning($"Resource string for [{area}] not found");
}
translatedAreas.Add(translatedArea ?? area);
@@ -93,6 +97,7 @@ internal static class TranslationHelper
if (string.IsNullOrEmpty(translatedAltName))
{
// Log.Warn($"Resource string for [{altName}] not found", typeof(TranslationHelper));
Logger.LogWarning($"Resource string for [{altName}] not found");
}
translatedAltNames.Add(translatedAltName ?? altName);
@@ -108,6 +113,7 @@ internal static class TranslationHelper
if (string.IsNullOrEmpty(note))
{
// Log.Warn($"Resource string for [{settings.Note}] not found", typeof(TranslationHelper));
Logger.LogWarning($"Resource string for [{settings.Note}] not found");
}
settings.Note = note ?? settings.Note ?? string.Empty;

View File

@@ -4,6 +4,7 @@
using System;
using System.Linq;
using ManagedCommon;
namespace Microsoft.CmdPal.Ext.WindowsSettings.Helpers;
@@ -40,6 +41,7 @@ internal static class UnsupportedSettingsHelper
// TODO GH #108 Logging is something we have to take care of
// Log.Warn(warningMessage, typeof(UnsupportedSettingsHelper));
Logger.LogWarning(warningMessage);
}
var currentWindowsBuild = currentBuild != uint.MinValue
@@ -71,12 +73,9 @@ internal static class UnsupportedSettingsHelper
{
registryValueData = Win32.Registry.GetValue(registryKey, valueName, uint.MinValue);
}
catch
catch (Exception ex)
{
// Log.Exception(
// $"Can't get registry value for '{valueName}'",
// exception,
// typeof(UnsupportedSettingsHelper));
Logger.LogError($"Can't get registry value for '{valueName}' - {ex.Message}");
return uint.MinValue;
}

View File

@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System.Linq;
using ManagedCommon;
namespace Microsoft.CmdPal.Ext.WindowsSettings.Helpers;
@@ -34,6 +35,7 @@ internal static class WindowsSettingsPathHelper
{
// TODO GH #108 Logging is something we have to take care of
// Log.Warn($"The type property is not set for setting [{settings.Name}] in json. Skipping generating of settings path.", typeof(WindowsSettingsPathHelper));
Logger.LogWarning($"The type property is not set for setting [{settings.Name}] in json. Skipping generating of settings path.");
continue;
}
@@ -41,12 +43,14 @@ internal static class WindowsSettingsPathHelper
if (!string.IsNullOrEmpty(settings.JoinedAreaPath))
{
// Log.Debug($"The property [JoinedAreaPath] of setting [{settings.Name}] was filled from the json. This value is not used and will be overwritten.", typeof(WindowsSettingsPathHelper));
Logger.LogDebug($"The property [JoinedAreaPath] of setting [{settings.Name}] was filled from the json. This value is not used and will be overwritten.");
}
if (!string.IsNullOrEmpty(settings.JoinedFullSettingsPath))
{
// TODO GH #108 Logging is something we have to take care of
// Log.Debug($"The property [JoinedFullSettingsPath] of setting [{settings.Name}] was filled from the json. This value is not used and will be overwritten.", typeof(WindowsSettingsPathHelper));
Logger.LogDebug($"The property [JoinedFullSettingsPath] of setting [{settings.Name}] was filled from the json. This value is not used and will be overwritten.");
}
// Generating path values.

View File

@@ -20,6 +20,7 @@
<PackageReference Include="System.ServiceProcess.ServiceController" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\common\ManagedCommon\ManagedCommon.csproj" />
<ProjectReference Include="..\..\extensionsdk\Microsoft.CommandPalette.Extensions.Toolkit\Microsoft.CommandPalette.Extensions.Toolkit.csproj" />
</ItemGroup>
<ItemGroup>

View File

@@ -9,6 +9,7 @@ using System.Linq;
using System.Resources;
using System.Text;
using System.Threading.Tasks;
using ManagedCommon;
using Microsoft.CmdPal.Ext.WindowsTerminal.Helpers;
using Microsoft.CmdPal.Ext.WindowsTerminal.Properties;
using Microsoft.CommandPalette.Extensions;
@@ -60,6 +61,7 @@ internal sealed partial class LaunchProfileAsAdminCommand : InvokableCommand
//var message = Resources.run_terminal_failed;
//Log.Exception("Failed to open Windows Terminal", ex, GetType());
//_context.API.ShowMsg(name, message, string.Empty);
Logger.LogError($"Failed to open Windows Terminal: {ex.Message}");
}
}
#pragma warning restore IDE0059, CS0168, SA1005
@@ -81,6 +83,7 @@ internal sealed partial class LaunchProfileAsAdminCommand : InvokableCommand
// var message = Resources.run_terminal_failed;
// Log.Exception("Failed to open Windows Terminal", ex, GetType());
// _context.API.ShowMsg(name, message, string.Empty);
Logger.LogError($"Failed to open Windows Terminal: {ex.Message}");
}
}
#pragma warning restore IDE0059, CS0168
@@ -94,6 +97,7 @@ internal sealed partial class LaunchProfileAsAdminCommand : InvokableCommand
catch
{
// TODO GH #108 We need to figure out some logging
// No need to log here, as the exception is already logged in LaunchElevated
}
return CommandResult.Dismiss();

View File

@@ -9,6 +9,7 @@ using System.Linq;
using System.Resources;
using System.Text;
using System.Threading.Tasks;
using ManagedCommon;
using Microsoft.CmdPal.Ext.WindowsTerminal.Helpers;
using Microsoft.CmdPal.Ext.WindowsTerminal.Properties;
using Microsoft.CommandPalette.Extensions;
@@ -52,6 +53,7 @@ internal sealed partial class LaunchProfileCommand : InvokableCommand
// var message = Resources.run_terminal_failed;
// Log.Exception("Failed to open Windows Terminal", ex, GetType());
// _context.API.ShowMsg(name, message, string.Empty);
Logger.LogError($"Failed to open Windows Terminal: {ex.Message}");
}
}
#pragma warning restore IDE0059, CS0168
@@ -65,6 +67,7 @@ internal sealed partial class LaunchProfileCommand : InvokableCommand
catch
{
// TODO GH #108 We need to figure out some logging
// No need to log here, as the exception is already logged in the Launch method
}
return CommandResult.Dismiss();

View File

@@ -8,7 +8,7 @@ using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Security.Principal;
using ManagedCommon;
using Windows.Management.Deployment;
// using Wox.Plugin.Logger;
@@ -41,6 +41,7 @@ public class TerminalQuery : ITerminalQuery
{
// TODO: what kind of logging should we do?
// Log.Warn($"No Windows Terminal packages installed", typeof(TerminalQuery));
Logger.LogWarning("No Windows Terminal packages installed");
}
foreach (var terminal in Terminals)
@@ -49,6 +50,7 @@ public class TerminalQuery : ITerminalQuery
{
// TODO: what kind of logging should we do?
// Log.Warn($"Failed to find settings file {terminal.SettingsPath}", typeof(TerminalQuery));
Logger.LogWarning($"Failed to find settings file {terminal.SettingsPath}");
continue;
}

View File

@@ -15,6 +15,7 @@
<None Remove="Assets\WindowsTerminal.svg" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\common\ManagedCommon\ManagedCommon.csproj" />
<ProjectReference Include="..\..\extensionsdk\Microsoft.CommandPalette.Extensions.Toolkit\Microsoft.CommandPalette.Extensions.Toolkit.csproj" />
</ItemGroup>
<ItemGroup>

View File

@@ -4,6 +4,7 @@
using System;
using System.IO;
using ManagedCommon;
using Microsoft.UI.Xaml.Media.Imaging;
// using Wox.Infrastructure.Image;
@@ -43,6 +44,7 @@ public class TerminalPackage
{
// Not using wox anymore, TODO: find the right new way to handle this
// image.UriSource = new Uri(ImageLoader.ErrorIconPath);
Logger.LogError($"Logo file not found: {LogoPath}");
}
return image;

View File

@@ -12,7 +12,7 @@
"org": "microsoft",
"project": "OS",
"AssignedTo": "leilzh@microsoft.com",
"AreaPath": "OS\\Windows Client and Services\\WinPD\\DEEP-Developer Experience, Ecosystem and Partnerships\\DIVE\\SALT",
"AreaPath": "OS\\Windows Client and Services\\WinPD\\DFX-Developer Fundamentals and Experiences\\DEFT\\SALT",
"IterationPath": "OS\\Future"
},
"jobNotificationEmail": "PowerToys@microsoft.com",

View File

@@ -20,7 +20,7 @@
"org": "microsoft",
"project": "OS",
"AssignedTo": "mengyuanchen@microsoft.com",
"AreaPath": "OS\\Windows Client and Services\\WinPD\\DEEP-Developer Experience, Ecosystem and Partnerships\\SHINE\\PowerToys",
"AreaPath": "OS\\Windows Client and Services\\WinPD\\DFX-Developer Fundamentals and Experiences\\DEFT\\SALT",
"IterationPath": "OS\\Future"
},
"jobNotificationEmail": "mengyuanchen@microsoft.com",
@@ -61,7 +61,7 @@
"org": "microsoft",
"project": "OS",
"AssignedTo": "mengyuanchen@microsoft.com",
"AreaPath": "OS\\Windows Client and Services\\WinPD\\DEEP-Developer Experience, Ecosystem and Partnerships\\SHINE\\PowerToys",
"AreaPath": "OS\\Windows Client and Services\\WinPD\\DFX-Developer Fundamentals and Experiences\\DEFT\\SALT",
"IterationPath": "OS\\Future"
},
"jobNotificationEmail": "mengyuanchen@microsoft.com",

View File

@@ -27,12 +27,17 @@
Severity="Informational" />
<controls:SettingsGroup x:Uid="CmdPal_Activation_GroupSettings" IsEnabled="{x:Bind ViewModel.IsEnabled, Mode=OneWay}">
<tkcontrols:SettingsCard x:Uid="CmdPal_ActivationShortcut" HeaderIcon="{ui:FontIcon Glyph=&#xEDA7;}">
<controls:ShortcutControl
MinWidth="{StaticResource SettingActionControlMinWidth}"
HotkeySettings="{x:Bind Path=ViewModel.Hotkey, Mode=OneWay}"
IsEnabled="False" />
<tkcontrols:SettingsCard.Description>
<HyperlinkButton
x:Name="CmdPalSettingsDeeplink"
x:Uid="CmdPal_DeeplinkContent"
Click="CmdPalSettingsDeeplink_Click" />
</tkcontrols:SettingsCard.Description>
</tkcontrols:SettingsCard>
</controls:SettingsGroup>
</StackPanel>

View File

@@ -2,6 +2,10 @@
// 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.Diagnostics;
using System.IO;
using ManagedCommon;
using Microsoft.PowerToys.Settings.UI.Helpers;
using Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.PowerToys.Settings.UI.ViewModels;
@@ -29,5 +33,40 @@ namespace Microsoft.PowerToys.Settings.UI.Views
{
ViewModel.RefreshEnabledState();
}
private void LaunchApp(string appPath)
{
try
{
string dir = Path.GetDirectoryName(appPath);
var processStartInfo = new ProcessStartInfo
{
FileName = appPath,
Arguments = string.Empty,
WorkingDirectory = dir,
UseShellExecute = true,
Verb = "open",
CreateNoWindow = false,
};
Process process = Process.Start(processStartInfo);
if (process == null)
{
Logger.LogError($"Failed to launch CmdPal settings page.");
}
}
catch (Exception ex)
{
Logger.LogError($"Failed to launch CmdPal settings: {ex.Message}");
}
}
private void CmdPalSettingsDeeplink_Click(object sender, Microsoft.UI.Xaml.RoutedEventArgs e)
{
// Launch CmdPal settings window
string launchPath = "x-cmdpal://settings";
LaunchApp(launchPath);
}
}
}

View File

@@ -110,9 +110,6 @@
x:Uid="Shell_TopLevelSystemTools"
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/SystemTools.png}"
SelectsOnInvoked="False">
<NavigationViewItem.InfoBadge>
<InfoBadge Style="{StaticResource NewInfoBadge}" />
</NavigationViewItem.InfoBadge>
<NavigationViewItem.MenuItems>
<NavigationViewItem
x:Uid="Shell_AdvancedPaste"
@@ -125,11 +122,7 @@
<NavigationViewItem
x:Uid="Shell_CmdPal"
helpers:NavHelper.NavigateTo="views:CmdPalPage"
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/CmdPal.png}">
<NavigationViewItem.InfoBadge>
<InfoBadge Style="{StaticResource NewInfoBadge}" />
</NavigationViewItem.InfoBadge>
</NavigationViewItem>
Icon="{ui:BitmapIcon Source=/Assets/Settings/Icons/CmdPal.png}" />
<NavigationViewItem
x:Uid="Shell_ColorPicker"
helpers:NavHelper.NavigateTo="views:ColorPickerPage"

View File

@@ -4996,8 +4996,8 @@ To record a specific window, enter the hotkey with the Alt key in the opposite m
<data name="CmdPal_ActivationShortcut.Header" xml:space="preserve">
<value>Activation shortcut</value>
</data>
<data name="CmdPal_ActivationShortcut.Description" xml:space="preserve">
<value>Go to Command Palette settings to customize the activation shortcut.</value>
<data name="CmdPal_DeeplinkContent.Content" xml:space="preserve">
<value>Open Command Palette settings to customize the activation shortcut</value>
</data>
<data name="Help_chromaCIE" xml:space="preserve">
<value>chroma (CIE LCh)</value>

View File

@@ -77,7 +77,6 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
IsEnabled = gpo == GpoRuleConfigured.Enabled || (gpo != GpoRuleConfigured.Disabled && ModuleHelper.GetIsModuleEnabled(generalSettingsConfig, moduleType)),
IsLocked = gpo == GpoRuleConfigured.Enabled || gpo == GpoRuleConfigured.Disabled,
Icon = ModuleHelper.GetModuleTypeFluentIconName(moduleType),
IsNew = moduleType == ModuleType.CmdPal,
EnabledChangedCallback = EnabledChangedOnUI,
DashboardModuleItems = GetModuleItems(moduleType),
});