Skip to content

Commit eec29d2

Browse files
committed
So very many docs
1 parent f8cbcf5 commit eec29d2

File tree

4 files changed

+251
-31
lines changed

4 files changed

+251
-31
lines changed
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
---
2+
title: Add top-level commands to your extension
3+
description: Learn how to add new top-level commands to your Command Palette extension.
4+
ms.date: 3/23/2025
5+
ms.topic: concept-article
6+
no-loc: [PowerToys, Windows, Insider]
7+
# Customer intent: As a Windows developer, I want to learn how to develop an extension for the Command Palette.
8+
---
9+
10+
# Adding top-level commands
11+
12+
**Previous**: [Command Results](command-results.md)
13+
14+
So far, we've only added commands to a single page, within your extension. You can also add more commands directly to the top-level list of commands too.
15+
16+
To do that, head on over to the `ExtensionNameCommandsProvider.cs` file. This file is where you'll add commands that should be shown at the top-level of the Command Palette. As you can see, there's currently only a single item there:
17+
18+
```csharp
19+
public ExtensionNameCommandsProvider()
20+
{
21+
DisplayName = "My sample extension";
22+
Icon = IconHelpers.FromRelativePath("Assets\\StoreLogo.png");
23+
_commands = [
24+
new CommandItem(new ExtensionNamePage()) { Title = DisplayName },
25+
];
26+
}
27+
28+
public override ICommandItem[] TopLevelCommands()
29+
{
30+
return _commands;
31+
}
32+
```
33+
34+
In this very simple extension, we're simply creating a list of commands when the extension is created, and then returning that list whenever we're asked for the top-level commands. This prevents us from re-creating the list of commands every time we're asked for the top-level commands, which can be a performance optimization.
35+
36+
If we want to add another command to the top-level list of commands, we just need to add another `CommandItem`:
37+
38+
```csharp
39+
public ExtensionNameCommandsProvider()
40+
{
41+
DisplayName = "My sample extension";
42+
Icon = IconHelpers.FromRelativePath("Assets\\StoreLogo.png");
43+
_commands = [
44+
new CommandItem(new ExtensionNamePage()) { Title = DisplayName },
45+
new CommandItem(new ShowMessageCommand()) { Title = "Send a message" },
46+
];
47+
}
48+
```
49+
50+
There you have it. Now you can add additional top-level commands to your extension.
51+
52+
If you'd like to update the list of top-level commands dynamically, you can do so in the same way as you would updating a list page. This can be useful for cases like an extension that might first require the user to log in, before showing certain commands. In that case, you can show the "log in" command at the top level initially. Then, once the user logs in successfully, you can update the list of top-level commands to include the commands that required authentication.
53+
54+
Once you've determined that you need to change the top level list, call [`RaiseItemsChanged()`](../microsoft-commandpalette-extensions-toolkit/commandprovider-raiseitemschanged.md) on your `CommandProvider`. Command Palette will then ask for the top-level commands via `TopLevelCommands()` again, and you can return the updated list.
55+
56+
57+
> [!TIP]
58+
> Create the `CommandItem`s for the top-level commands before calling `RaiseItemsChanged()`. This will ensure that the new commands are available when Command Palette asks for the top-level commands. This will help keep the work being done in call to `TopLevelCommands()` method to a minimum.
59+
60+
### Next up: [Display markdown content](using-markdown-content.md)
61+
62+
## Related content
63+
64+
- [PowerToys Command Palette utility](overview.md)
65+
- [Extensibility overview](extensibility-overview.md)
66+
- [Extension samples](samples.md)
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
---
2+
title: Adding commands
3+
description: Learn how to add new commands to your Command Palette extension.
4+
ms.date: 3/23/2025
5+
ms.topic: concept-article
6+
no-loc: [PowerToys, Windows, Insider]
7+
# Customer intent: As a Windows developer, I want to learn how to develop an extension for the Command Palette.
8+
---
9+
10+
# Adding commands
11+
12+
**Previous**: [Creating an extension](creating-an-extension.md). We'll be starting with the project created in that article.
13+
14+
Now that you've created your extension, it's time to add some commands to it. We can start by navigating to the `ExtensionNamePage.cs` file. This file is the [`ListPage`](./microsoft-commandpalette-extensions-toolkit/listpage.md) that will be displayed when the user selects your extension. In there you should see:
15+
16+
```csharp
17+
public DocsSamplePage()
18+
{
19+
Icon = IconHelpers.FromRelativePath("Assets\\StoreLogo.png");
20+
Title = "My sample extension";
21+
Name = "Open";
22+
}
23+
public override IListItem[] GetItems()
24+
{
25+
return [
26+
new ListItem(new NoOpCommand()) { Title = "TODO: Implement your extension here" }
27+
];
28+
}
29+
```
30+
31+
Here you can see that we've set the icon for the page, the title, and the name that's shown at the top-level when you have the command selected. The `GetItems` method is where you'll return the list of commands that you want to show on this page. Right now, that's just returning a single command that does nothing. Let's instead try making that command open _this_ page in the user's default web browser.
32+
33+
We can change the implementation of `GetItems()` to the following:
34+
35+
```csharp
36+
public override IListItem[] GetItems()
37+
{
38+
var command = new OpenUrlCommand("https://learn.microsoft.com/windows/powertoys/command-palette/adding-commands");
39+
return [
40+
new ListItem(command)
41+
{
42+
Title = "Open the Command Palette documentation",
43+
}
44+
];
45+
}
46+
```
47+
48+
Re-deploy your app, run the "reload" command to refresh the extensions in the palette, and head to your extension. You should see that the command now opens the Command Palette documentation.
49+
50+
The `OpenUrlCommand` is a helper for just opening a URL in the user's default web browser. You can also just implement an extension however you want. Let's instead make a new command, that shows a MessageBox. To do that, we need to create a new class that implements `IInvokableCommand`
51+
52+
```csharp
53+
using System.Runtime.InteropServices;
54+
55+
namespace ExtensionName;
56+
57+
internal sealed partial class ShowMessageCommand : InvokableCommand
58+
{
59+
public override string Name => "Show message";
60+
public override IconInfo Icon => new("\uE8A7");
61+
62+
public override CommandResult Invoke()
63+
{
64+
// 0x00001000 is MB_SYSTEMMODAL, which will display the message box on top of other windows.
65+
_ = MessageBox(0, "I came from the Command Palette", "What's up?", 0x00001000);
66+
return CommandResult.KeepOpen();
67+
}
68+
69+
70+
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
71+
public static extern int MessageBox(IntPtr hWnd, string text, string caption, uint type);
72+
}
73+
```
74+
75+
Now we can add this command to the list of commands in the `ExtensionNamePage.cs` file:
76+
77+
```csharp
78+
public override IListItem[] GetItems()
79+
{
80+
var command = new OpenUrlCommand("https://learn.microsoft.com/windows/powertoys/command-palette/creating-an-extension");
81+
var showMessageCommand = new ShowMessageCommand();
82+
return [
83+
new ListItem(command)
84+
{
85+
Title = "Open the Command Palette documentation",
86+
},
87+
new ListItem(showMessageCommand),
88+
];
89+
}
90+
```
91+
92+
Deploy and reload, and presto - a command to show a message box!
93+
94+
> [!TIP]
95+
> At about this point, you'll probably want to initialize a git repo / {other source control method of your choice} for your project. This will make it easier to track changes, and to share your extension with others.
96+
>
97+
> We recommend using GitHub, as it's easy to collaborate on your extension with others, and get feedback, and share it with the world.
98+
99+
## Adding more pages
100+
101+
So far, we've only worked with commands that "do something". However, you can also add commands that show additional pages withing the Command Palette. There are basically two types of "Commands" in the Palette:
102+
* `IInvokableCommand` - These are commands that **do something**.
103+
* `IPage` - These are commands that **show something**.
104+
105+
Because `IPage`s are just `ICommand`s, you can use them anywhere you can use commands. This means you can add them to the top-level list of commands, or to a list of commands on a page, the context menu on an item, etc.
106+
107+
There are two different kinds of pages you can show:
108+
* [`ListPage`](./microsoft-commandpalette-extensions-toolkit/listpage.md) - This is a page that shows a list of commands. This is what we've been working with so far.
109+
* [`ContentPage`](./microsoft-commandpalette-extensions-toolkit/contentpage.md) - This is a page that shows rich content to the user. This allows you to specify abstract content, and let Command Palette worry about rendering the content in a native experience. There are two different types of content supported so far:
110+
* [Markdown content](./using-markdown-content.md) - This is content that's written in Markdown, and is rendered in the Command Palette. See [`MarkdownContent`](./microsoft-commandpalette-extensions-toolkit/markdowncontent.md) for details.
111+
* [Form content](./using-form-pages.md) - This is content that shows a form to the user, and then returns the results of that form to the extension. These are powered by [Adaptive Cards](aka.ms/adaptive-cards) This is useful for getting user input, or displaying more complex layouts of information. See [`FormContent`](./microsoft-commandpalette-extensions-toolkit/formcontent.md) for details.
112+
113+
114+
We'll start by adding a new page that shows a list of commands. We can create a new class that implements `ListPage`:
115+
116+
```csharp
117+
using Microsoft.CommandPalette.Extensions.Toolkit;
118+
using System.Linq;
119+
120+
namespace ExtensionName;
121+
122+
internal sealed partial class MySecondPage : ListPage
123+
{
124+
public MySecondPage()
125+
{
126+
Icon = new("\uF147"); // Dial2
127+
Title = "My second page";
128+
Name = "Open";
129+
}
130+
131+
public override IListItem[] GetItems()
132+
{
133+
// Return 100 CopyText commands
134+
return Enumerable
135+
.Range(0, 100)
136+
.Select(i => new ListItem(new CopyTextCommand($"{i}"))
137+
{
138+
Title = $"Copy text {i}"
139+
}).ToArray();
140+
}
141+
}
142+
```
143+
144+
Then we go update our `ExtensionNamePage.cs` to include this new page:
145+
146+
```diff
147+
public override IListItem[] GetItems()
148+
{
149+
OpenUrlCommand command = new("https://learn.microsoft.com/windows/powertoys/command-palette/creating-an-extension");
150+
return [
151+
new ListItem(command)
152+
{
153+
Title = "Open the Command Palette documentation",
154+
},
155+
new ListItem(new ShowMessageCommand()),
156+
+ new ListItem(new MySecondPage()) { Title = "My second page", Subtitle = "A second page of commands" },
157+
];
158+
}
159+
```
160+
161+
Deploy, reload, and you should now see a new page in your extension that shows 100 commands that copy a number to the clipboard.
162+
163+
### Next up: [Update a list of commands](update-a-list-of-commands.md)
164+
165+
## Related content
166+
167+
- [PowerToys Command Palette utility](overview.md)
168+
- [Extensibility overview](extensibility-overview.md)
169+
- [Extension samples](samples.md)

hub/powertoys/command-palette/creating-an-extension.md

Lines changed: 11 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
2-
title: Command Palette Extensibility
3-
description: The Command Palette provides a full extension model, allowing you to create custom experiences for the palette. Learn how to create an extension and publish it.
4-
ms.date: 2/28/2025
2+
title: Creating an extension
3+
description: The Command Palette provides a full extension model, allowing you to create custom experiences for the palette. Learn how to create an extension
4+
ms.date: 3/23/2025
55
ms.topic: concept-article
66
no-loc: [PowerToys, Windows, Insider]
77
# Customer intent: As a Windows developer, I want to learn how to develop an extension for the Command Palette.
@@ -55,6 +55,12 @@ From here, you can immediately build the project and run it. Once your package i
5555
5656
> [!WARNING]
5757
> Running "ExtensionName (Unpackaged)" from Visual Studio will not **deploy** your app package.
58+
>
59+
> If you're using `git` for source control, and you used the standard `.gitignore` file for C#, you'll want to remove the
60+
> ```
61+
> **/Properties/launchSettings.json
62+
> ```
63+
> line from your `.gitignore` file. This file is used by WinAppSdk to deploy your app as a package. Without it, anyone who clones your repo won't be able to deploy your extension.
5864
5965
You should be able to see your extension in the Command Palette at the end of the list of commands. Entering that command should take you to the page for your command, and you should see a single command that says "TODO: Implement your extension here".
6066
@@ -64,31 +70,10 @@ Congrats! You've made your first extension! Now let's go ahead and actually add
6470
6571
When you make changes to your extension, you can rebuild your project and deploy it again. Command Palette will **not** notice changes to packages that are re-ran through Visual Studio, so you'll need to manually run the "**Reload**" command to force Command Palette to re-instantiate your extension.
6672
67-
Let's make that command do something.
68-
69-
We can start by navigating to the `ExtensionNamePage.cs` file. This file is the [`ListPage`](./microsoft-commandpalette-extensions-toolkit/listpage.md) that will be displayed when the user selects your extension. In there you should see:
70-
71-
```csharp
72-
public DocsSamplePage()
73-
{
74-
Icon = IconHelpers.FromRelativePath("Assets\\StoreLogo.png");
75-
Title = "My sample extension";
76-
Name = "Open";
77-
}
78-
public override IListItem[] GetItems()
79-
{
80-
return [
81-
new ListItem(new NoOpCommand()) { Title = "TODO: Implement your extension here" }
82-
];
83-
}
84-
```
85-
86-
https://learn.microsoft.com/windows/powertoys/command-palette/overview
87-
88-
89-
### Next up: [Update a list of commands](update-a-list-of-commands.md)
73+
### Next up: [Add commands to your extension](adding-commands.md)
9074
9175
## Related content
9276
9377
- [PowerToys Command Palette utility](overview.md)
78+
- [Extensibility overview](extensibility-overview.md)
9479
- [Extension samples](samples.md)
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
---
2-
title: CommandProvider.RaiseItemsChanged(Int) Method
2+
title: CommandProvider.RaiseItemsChanged() Method
33
description: The RaiseItemsChanged method raises the ItemsChanged event with the number of items specified.
44
ms.date: 2/25/2025
55
ms.topic: reference
66
no-loc: [PowerToys, Windows, Insider]
77
---
88

9-
# CommandProvider.RaiseItemsChanged(Int) Method
9+
# CommandProvider.RaiseItemsChanged() Method
1010

1111
## Definition
1212

1313
Namespace: [Microsoft.CommandPalette.Extensions.Toolkit](microsoft-commandpalette-extensions-toolkit.md)
1414

15-
The **RaiseItemsChanged** method raises the **ItemsChanged** event with the specified change type. This method is typically used to notify the command palette of changes in the command provider's items, such as when new commands are added or existing commands are removed.
15+
The **RaiseItemsChanged** method raises the **ItemsChanged** event with the specified change type. This method is typically used to notify the Command Palette of changes in the command provider's items, such as when new commands are added or existing commands are removed.
1616

17-
## Parameters
17+
<!-- ## Parameters
1818
1919
*totalItems* **Int**
2020
21-
The total number of items in the command provider. This value is used to update the command palette with the current state of the command provider's items.
21+
The total number of items in the command provider. This value is used to update the command palette with the current state of the command provider's items. -->

0 commit comments

Comments
 (0)