Cmdpal: user research on extension invokes (#43905)

## Summary of the Pull Request

Added two events that Niels asked for:

- `CmdPal_ExtensionInvoked`
- Track which extensions are being used (e.g., file search, app
launching, calculator, etc.).
    - Properties logged
        - ExtensionId - Unique identifier of the extension provider
        - CommandType - Display name of the command being invoked
        - Success - Whether the command executed successfully
        - ExecutionTimeMs - Execution time in milliseconds
- `CmdPal_SessionDuration`
    - Tracks how long Command Palette stays open (launch → close). 
    - Properties logged
        - DurationMs - Session duration in milliseconds
        - CommandsExecuted - Number of commands executed
        - PagesVisited - Number of pages visited
- DismissalReason - Why the session ended (Escape, LostFocus, Command,
etc.)
        - SearchQueriesCount - Number of search queries executed
        - MaxNavigationDepth - Maximum navigation depth reached
        - ErrorCount - Number of errors encountered



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

- [ ] Closes: #xxx
<!-- - [ ] Closes: #yyy (add separate lines for additional resolved
issues) -->
- [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
This commit is contained in:
Jessica Dene Earley-Cha
2025-12-19 11:23:16 -08:00
committed by GitHub
parent 557a07589d
commit 37bd24db36
18 changed files with 397 additions and 20 deletions

View File

@@ -0,0 +1,56 @@
// 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.Diagnostics.CodeAnalysis;
using System.Diagnostics.Tracing;
using Microsoft.PowerToys.Telemetry;
using Microsoft.PowerToys.Telemetry.Events;
namespace Microsoft.CmdPal.UI.Events;
/// <summary>
/// Tracks extension usage with extension name and invocation details.
/// Purpose: Identify popular vs. unused plugins and track extension performance.
/// </summary>
[EventData]
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)]
public class CmdPalExtensionInvoked : EventBase, IEvent
{
/// <summary>
/// Gets or sets the unique identifier of the extension provider.
/// </summary>
public string ExtensionId { get; set; }
/// <summary>
/// Gets or sets the non-localized identifier of the command being invoked.
/// </summary>
public string CommandId { get; set; }
/// <summary>
/// Gets or sets the localized display name of the command being invoked.
/// </summary>
public string CommandName { get; set; }
/// <summary>
/// Gets or sets whether the command executed successfully.
/// </summary>
public bool Success { get; set; }
/// <summary>
/// Gets or sets the execution time in milliseconds.
/// </summary>
public ulong ExecutionTimeMs { get; set; }
public CmdPalExtensionInvoked(string extensionId, string commandId, string commandName, bool success, ulong executionTimeMs)
{
EventName = "CmdPal_ExtensionInvoked";
ExtensionId = extensionId;
CommandId = commandId;
CommandName = commandName;
Success = success;
ExecutionTimeMs = executionTimeMs;
}
public PartA_PrivTags PartA_PrivTags => PartA_PrivTags.ProductAndServiceUsage;
}

View File

@@ -18,6 +18,7 @@ public class CmdPalInvokeResult : EventBase, IEvent
public CmdPalInvokeResult(CommandResultKind resultKind)
{
EventName = "CmdPal_InvokeResult";
ResultKind = resultKind.ToString();
}

View File

@@ -0,0 +1,68 @@
// 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.Diagnostics.CodeAnalysis;
using System.Diagnostics.Tracing;
using Microsoft.PowerToys.Telemetry;
using Microsoft.PowerToys.Telemetry.Events;
namespace Microsoft.CmdPal.UI.Events;
/// <summary>
/// Tracks Command Palette session duration from launch to close.
/// Purpose: Understand user engagement patterns - quick actions vs. browsing behavior.
/// </summary>
[EventData]
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)]
public class CmdPalSessionDuration : EventBase, IEvent
{
/// <summary>
/// Gets or sets the session duration in milliseconds.
/// </summary>
public ulong DurationMs { get; set; }
/// <summary>
/// Gets or sets the number of commands executed during the session.
/// </summary>
public int CommandsExecuted { get; set; }
/// <summary>
/// Gets or sets the number of pages visited during the session.
/// </summary>
public int PagesVisited { get; set; }
/// <summary>
/// Gets or sets the reason for dismissal (Escape, LostFocus, Command, etc.).
/// </summary>
public string DismissalReason { get; set; }
/// <summary>
/// Gets or sets the number of search queries executed during the session.
/// </summary>
public int SearchQueriesCount { get; set; }
/// <summary>
/// Gets or sets the maximum navigation depth reached during the session.
/// </summary>
public int MaxNavigationDepth { get; set; }
/// <summary>
/// Gets or sets the number of errors encountered during the session.
/// </summary>
public int ErrorCount { get; set; }
public CmdPalSessionDuration(ulong durationMs, int commandsExecuted, int pagesVisited, string dismissalReason, int searchQueriesCount, int maxNavigationDepth, int errorCount)
{
EventName = "CmdPal_SessionDuration";
DurationMs = durationMs;
CommandsExecuted = commandsExecuted;
PagesVisited = pagesVisited;
DismissalReason = dismissalReason;
SearchQueriesCount = searchQueriesCount;
MaxNavigationDepth = maxNavigationDepth;
ErrorCount = errorCount;
}
public PartA_PrivTags PartA_PrivTags => PartA_PrivTags.ProductAndServiceUsage;
}