Rename the [Ee]xts dir to ext (#38852)

**WARNING:** This PR will probably blow up all in-flight PRs

at some point in the early days of CmdPal, two of us created seperate
`Exts` and `exts` dirs. Depending on what the casing was on the branch
that you checked one of those out from, it'd get stuck like that on your
PC forever.

Windows didn't care, so we never noticed.

But GitHub does care, and now browsing the source on GitHub is basically
impossible.

Closes #38081
This commit is contained in:
Mike Griese
2025-04-15 06:07:22 -05:00
committed by GitHub
parent 60f50d853b
commit 2b5181b4c9
379 changed files with 35 additions and 35 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 432 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 637 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 456 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1,78 @@
<?xml version="1.0" encoding="utf-8"?>
<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3"
xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10"
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
IgnorableNamespaces="uap uap3 rescap">
<Identity
Name="ProcessMonitorExtension"
Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US"
Version="1.0.0.0" />
<Properties>
<DisplayName>Process Monitor Sample Extension</DisplayName>
<PublisherDisplayName>Microsoft Corporation</PublisherDisplayName>
<Logo>Assets\StoreLogo.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.19041.0" MaxVersionTested="10.0.19041.0" />
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.19041.0" MaxVersionTested="10.0.19041.0" />
</Dependencies>
<Resources>
<Resource Language="x-generate"/>
</Resources>
<Applications>
<Application Id="App"
Executable="$targetnametoken$.exe"
EntryPoint="$targetentrypoint$">
<uap:VisualElements
DisplayName="Process Monitor Sample Extension"
Description="Process Monitor Sample Extension"
BackgroundColor="transparent"
Square150x150Logo="Assets\Square150x150Logo.png"
Square44x44Logo="Assets\Square44x44Logo.png">
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" />
<uap:SplashScreen Image="Assets\SplashScreen.png" />
</uap:VisualElements>
<Extensions>
<com:Extension Category="windows.comServer">
<com:ComServer>
<com:ExeServer Executable="ProcessMonitorExtension.exe" Arguments="-RegisterProcessAsComServer" DisplayName="ProcessMonitorExtension">
<com:Class Id="8BD7A6C4-7185-4426-AE8D-61E438A3E740" DisplayName="ProcessMonitorExtension" />
</com:ExeServer>
</com:ComServer>
</com:Extension>
<uap3:Extension Category="windows.appExtension">
<uap3:AppExtension Name="com.microsoft.commandpalette"
Id="ID"
PublicFolder="Public"
DisplayName="Process Monitor Extension Sample"
Description="A sample Process Monitor Extension for CmdPal">
<uap3:Properties>
<CmdPalProvider>
<Activation>
<CreateInstance ClassId="8BD7A6C4-7185-4426-AE8D-61E438A3E740" />
</Activation>
<SupportedInterfaces>
<Commands/>
</SupportedInterfaces>
</CmdPalProvider>
</uap3:Properties>
</uap3:AppExtension>
</uap3:Extension>
</Extensions>
</Application>
</Applications>
<Capabilities>
<Capability Name="internetClient" />
<rescap:Capability Name="runFullTrust" />
</Capabilities>
</Package>

View File

@@ -0,0 +1,22 @@
// 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;
namespace ProcessMonitorExtension;
internal sealed class ProcessItem
{
internal Process Process { get; init; }
internal int ProcessId { get; init; }
internal string Name { get; init; }
internal string ExePath { get; init; }
internal long Memory { get; init; }
internal long CPU { get; init; }
}

View File

@@ -0,0 +1,71 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;
namespace ProcessMonitorExtension;
internal sealed partial class ProcessListPage : ListPage
{
public ProcessListPage()
{
this.Icon = new IconInfo("\ue9d9");
this.Name = "Process Monitor";
}
public override IListItem[] GetItems() => DoGetItems();
internal void UpdateItems() => this.RaiseItemsChanged(-1);
private IListItem[] DoGetItems()
{
var items = GetRunningProcesses();
this.IsLoading = false;
var s = items
.OrderByDescending(p => p.Memory)
.Select((process) => new ListItem(new SwitchToProcess(process))
{
Title = process.Name,
Subtitle = $"PID: {process.ProcessId}",
MoreCommands = [
new CommandContextItem(new TerminateProcess(process, this))
],
}).ToArray();
return s;
}
private static IEnumerable<ProcessItem> GetRunningProcesses()
{
return Process.GetProcesses()
.Select(p =>
{
var exePath = string.Empty;
try
{
exePath = p.MainModule.FileName;
}
catch
{
// Handle cases where the icon extraction or file path retrieval fails
}
return new ProcessItem
{
Process = p,
ProcessId = p.Id,
Name = p.ProcessName,
ExePath = exePath,
Memory = p.WorkingSet64,
// oh no CPU is not trivial to get
};
});
}
}

View File

@@ -0,0 +1,29 @@
// 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 Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;
namespace ProcessMonitorExtension;
internal sealed partial class ProcessMonitorCommandProvider : CommandProvider
{
public ProcessMonitorCommandProvider()
{
DisplayName = "Process Monitor Commands";
}
private readonly ICommandItem[] _commands = [
new CommandItem(new ProcessListPage())
{
Title = "Process Manager",
Subtitle = "Kill processes",
},
];
public override ICommandItem[] TopLevelCommands()
{
return _commands;
}
}

View File

@@ -0,0 +1,51 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\..\Common.Dotnet.CsWinRT.props" />
<PropertyGroup>
<OutputType>WinExe</OutputType>
<RootNamespace>ProcessMonitorExtension</RootNamespace>
<ApplicationManifest>app.manifest</ApplicationManifest>
<PublishProfile>win-$(Platform).pubxml</PublishProfile>
<UseWinUI>false</UseWinUI>
<EnableMsixTooling>true</EnableMsixTooling>
<OutputPath>$(SolutionDir)$(Platform)\$(Configuration)\WinUI3Apps\CmdPalExtensions\$(RootNamespace)</OutputPath>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
</PropertyGroup>
<ItemGroup>
<Content Include="Assets\SplashScreen.scale-200.png" />
<Content Include="Assets\LockScreenLogo.scale-200.png" />
<Content Include="Assets\Square150x150Logo.scale-200.png" />
<Content Include="Assets\Square44x44Logo.scale-200.png" />
<Content Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png" />
<Content Include="Assets\StoreLogo.png" />
<Content Include="Assets\Wide310x150Logo.scale-200.png" />
</ItemGroup>
<ItemGroup>
<Manifest Include="$(ApplicationManifest)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\extensionsdk\Microsoft.CommandPalette.Extensions.Toolkit\Microsoft.CommandPalette.Extensions.Toolkit.csproj">
</ProjectReference>
</ItemGroup>
<!--
Defining the "Msix" ProjectCapability here allows the Single-project MSIX Packaging
Tools extension to be activated for this project even if the Windows App SDK Nuget
package has not yet been restored.
-->
<ItemGroup Condition="'$(DisableMsixProjectCapabilityAddedByProject)'!='true' and '$(EnableMsixTooling)'=='true'">
<ProjectCapability Include="Msix" />
</ItemGroup>
<!--
Defining the "HasPackageAndPublishMenuAddedByProject" property here allows the Solution
Explorer "Package and Publish" context menu entry to be enabled for this project even if
the Windows App SDK Nuget package has not yet been restored.
-->
<PropertyGroup Condition="'$(DisableHasPackageAndPublishMenuAddedByProject)'!='true' and '$(EnableMsixTooling)'=='true'">
<HasPackageAndPublishMenu>true</HasPackageAndPublishMenu>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,36 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Threading;
using Microsoft.CommandPalette.Extensions;
namespace ProcessMonitorExtension;
public class Program
{
[MTAThread]
public static void Main(string[] args)
{
if (args.Length > 0 && args[0] == "-RegisterProcessAsComServer")
{
using ExtensionServer server = new();
var extensionDisposedEvent = new ManualResetEvent(false);
var extensionInstance = new SampleExtension(extensionDisposedEvent);
// We are instantiating an extension instance once above, and returning it every time the callback in RegisterExtension below is called.
// This makes sure that only one instance of SampleExtension is alive, which is returned every time the host asks for the IExtension object.
// If you want to instantiate a new instance each time the host asks, create the new instance inside the delegate.
server.RegisterExtension(() => extensionInstance);
// This will make the main thread wait until the event is signalled by the extension class.
// Since we have single instance of the extension object, we exit as soon as it is disposed.
extensionDisposedEvent.WaitOne();
}
else
{
Console.WriteLine("Not being launched as a Extension... exiting.");
}
}
}

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<PublishProtocol>FileSystem</PublishProtocol>
<Platform>ARM64</Platform>
<RuntimeIdentifier>win-arm64</RuntimeIdentifier>
<PublishDir>bin\$(Configuration)\$(TargetFramework)\$(RuntimeIdentifier)\publish\</PublishDir>
<SelfContained>true</SelfContained>
<PublishSingleFile>False</PublishSingleFile>
<PublishReadyToRun Condition="'$(Configuration)' == 'Debug'">False</PublishReadyToRun>
<PublishReadyToRun Condition="'$(Configuration)' != 'Debug'">True</PublishReadyToRun>
<PublishTrimmed Condition="'$(Configuration)' == 'Debug'">False</PublishTrimmed>
<PublishTrimmed Condition="'$(Configuration)' != 'Debug'">False</PublishTrimmed>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<PublishProtocol>FileSystem</PublishProtocol>
<Platform>x64</Platform>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<PublishDir>bin\$(Configuration)\$(TargetFramework)\$(RuntimeIdentifier)\publish\</PublishDir>
<SelfContained>true</SelfContained>
<PublishSingleFile>False</PublishSingleFile>
<PublishReadyToRun Condition="'$(Configuration)' == 'Debug'">False</PublishReadyToRun>
<PublishReadyToRun Condition="'$(Configuration)' != 'Debug'">True</PublishReadyToRun>
<PublishTrimmed Condition="'$(Configuration)' == 'Debug'">False</PublishTrimmed>
<PublishTrimmed Condition="'$(Configuration)' != 'Debug'">False</PublishTrimmed>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,11 @@
{
"profiles": {
"ProcessMonitorExtension (Package)": {
"commandName": "MsixPackage",
"doNotLaunchApp": true
},
"ProcessMonitorExtension (Unpackaged)": {
"commandName": "Project"
}
}
}

View File

@@ -0,0 +1,41 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Runtime.InteropServices;
using System.Threading;
using Microsoft.CommandPalette.Extensions;
namespace ProcessMonitorExtension;
[ComVisible(true)]
[Guid("8BD7A6C4-7185-4426-AE8D-61E438A3E740")]
[ComDefaultInterface(typeof(IExtension))]
public sealed partial class SampleExtension : IExtension, IDisposable
{
private readonly ManualResetEvent _extensionDisposedEvent;
private readonly ProcessMonitorCommandProvider _provider = new();
public SampleExtension(ManualResetEvent extensionDisposedEvent)
{
this._extensionDisposedEvent = extensionDisposedEvent;
}
public object GetProvider(ProviderType providerType)
{
switch (providerType)
{
case ProviderType.Commands:
return _provider;
default:
return null;
}
}
public void Dispose()
{
this._extensionDisposedEvent.Set();
}
}

View File

@@ -0,0 +1,30 @@
// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Runtime.InteropServices;
using Microsoft.CommandPalette.Extensions.Toolkit;
namespace ProcessMonitorExtension;
internal sealed partial class SwitchToProcess : InvokableCommand
{
[DllImport("user32.dll")]
public static extern void SwitchToThisWindow(IntPtr hWnd, bool fAltTab);
private readonly ProcessItem process;
public SwitchToProcess(ProcessItem process)
{
this.process = process;
this.Icon = new IconInfo(process.ExePath == string.Empty ? "\uE7B8" : process.ExePath);
this.Name = "Switch to";
}
public override CommandResult Invoke()
{
SwitchToThisWindow(process.Process.MainWindowHandle, true);
return CommandResult.KeepOpen();
}
}

View File

@@ -0,0 +1,30 @@
// 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;
using Microsoft.CommandPalette.Extensions.Toolkit;
namespace ProcessMonitorExtension;
internal sealed partial class TerminateProcess : InvokableCommand
{
private readonly ProcessItem _process;
private readonly ProcessListPage _owner;
public TerminateProcess(ProcessItem process, ProcessListPage owner)
{
_process = process;
_owner = owner;
Icon = new IconInfo("\ue74d");
Name = "End task";
}
public override CommandResult Invoke()
{
var process = Process.GetProcessById(_process.ProcessId);
process.Kill();
_owner.UpdateItems();
return CommandResult.KeepOpen();
}
}

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="KillProcessExtension.app"/>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- The ID below informs the system that this application is compatible with OS features first introduced in Windows 10.
It is necessary to support features in unpackaged applications, for example the custom titlebar implementation.
For more info see https://docs.microsoft.com/windows/apps/windows-app-sdk/use-windows-app-sdk-run-time#declare-os-compatibility-in-your-application-manifest -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
</application>
</compatibility>
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
</windowsSettings>
</application>
</assembly>