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

View File

@@ -0,0 +1,12 @@
// 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.
namespace Microsoft.CmdPal.Ext.WindowsServices;
public enum Action
{
Start,
Stop,
Restart,
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@@ -0,0 +1,19 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1909_18132)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.69797 0.156184C7.77288 0.031333 7.89773 -0.0186073 8.02258 0.031333C8.34719 0.156184 8.64683 0.281034 8.97144 0.505765C9.27109 0.680556 9.57073 0.880318 9.82043 1.10505C9.92031 1.20493 9.94527 1.35475 9.87036 1.45463C9.52078 2.05391 9.49581 2.80302 9.87036 3.45224C10.2449 4.10146 10.9191 4.45104 11.6183 4.45104C11.7681 4.45104 11.868 4.55092 11.893 4.67577C12.0178 5.34997 12.0428 6.04913 11.9179 6.72332C11.9179 6.84817 11.7931 6.94806 11.6682 6.94806C10.9691 6.94806 10.2949 7.29764 9.92031 7.94686C9.54575 8.57111 9.5957 9.34519 9.94528 9.94447C10.0202 10.0443 9.99522 10.1942 9.89534 10.2691C9.37097 10.7185 8.77168 11.0681 8.12245 11.2929C7.9976 11.3178 7.87276 11.2679 7.79785 11.168C7.44826 10.5437 6.79904 10.1442 6.04994 10.1442C5.30083 10.1442 4.65161 10.5438 4.30203 11.143C4.22712 11.2679 4.10227 11.3178 3.97742 11.2679C3.65281 11.143 3.3282 10.9932 3.02856 10.8184C2.72892 10.6436 2.42927 10.4439 2.17957 10.2191C2.07969 10.1193 2.05472 9.96944 2.12963 9.86956C2.47922 9.27028 2.50419 8.52117 2.12963 7.87195C1.75508 7.22273 1.08089 6.87314 0.381727 6.87314C0.231906 6.87314 0.132024 6.77326 0.107054 6.64841C-0.0177965 5.97422 -0.0427681 5.27506 0.0820824 4.60086C0.0820824 4.47601 0.206933 4.37613 0.331784 4.37613C1.03095 4.37613 1.70514 4.02655 2.07969 3.37733C2.45424 2.75308 2.4043 1.979 2.05472 1.37972C1.97981 1.25487 2.00478 1.10505 2.10466 1.03014C2.62904 0.580676 3.22832 0.231094 3.87754 0.00636323C4.00239 -0.0186069 4.12724 0.0313334 4.20215 0.131214C4.55173 0.755467 5.20096 1.15499 5.95006 1.15499C6.69916 1.15499 7.34838 0.755466 7.69797 0.156184ZM8.25 5.625C8.25 6.86764 7.24264 7.875 6 7.875C4.75736 7.875 3.75 6.86764 3.75 5.625C3.75 4.38236 4.75736 3.375 6 3.375C7.24264 3.375 8.25 4.38236 8.25 5.625Z" fill="url(#paint0_linear_1909_18132)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.5724 14.505C14.6177 14.5866 14.6054 14.672 14.5376 14.7254C14.3641 14.8657 14.1986 14.9922 13.9695 15.1005C13.7763 15.2109 13.5691 15.3133 13.3641 15.38C13.2766 15.4034 13.1853 15.3692 13.1539 15.2956C12.933 14.909 12.5247 14.6548 12.0438 14.6547C11.5629 14.6545 11.1523 14.917 10.928 15.3055C10.8799 15.3888 10.7924 15.4122 10.715 15.3861C10.3003 15.2391 9.90374 15.0287 9.56915 14.743C9.49977 14.703 9.48433 14.6015 9.52438 14.5322C9.7487 14.1436 9.77074 13.6568 9.53014 13.2404C9.30341 12.832 8.85723 12.6114 8.41206 12.6134C8.33252 12.623 8.25728 12.561 8.2477 12.4815C8.16617 12.0459 8.16418 11.6007 8.24759 11.1679C8.27377 11.0905 8.34158 11.0371 8.42111 11.0275C8.88016 11.0335 9.31047 10.801 9.5508 10.3847C9.79114 9.96841 9.77741 9.47946 9.55655 9.09293C9.51121 9.01125 9.52351 8.92585 9.59132 8.87249C9.76484 8.73216 9.95224 8.59985 10.1455 8.48942C10.3388 8.37899 10.5459 8.27656 10.7509 8.20991C10.8385 8.18645 10.9297 8.22064 10.9612 8.29431C11.1821 8.68084 11.5903 8.93505 12.0713 8.93521C12.5522 8.93536 12.9628 8.67287 13.1871 8.28435C13.2351 8.2011 13.3227 8.17764 13.4001 8.20382C13.8148 8.35074 14.2113 8.56118 14.5459 8.84686C14.6153 8.88691 14.6307 8.98834 14.5907 9.05772C14.3664 9.44624 14.3443 9.93304 14.5849 10.3495C14.8116 10.7579 15.2578 10.9785 15.703 10.9765C15.7964 10.9749 15.8716 11.0369 15.8812 11.1164C15.9628 11.552 15.9647 11.9972 15.8813 12.43C15.8552 12.5074 15.7873 12.5608 15.7078 12.5704C15.2488 12.5643 14.8185 12.7969 14.5781 13.2132C14.3378 13.6295 14.3515 14.1184 14.5724 14.505ZM11.3563 13.0572C10.6657 12.6585 10.4291 11.7755 10.8278 11.085C11.2265 10.3944 12.1095 10.1579 12.8 10.5565C13.4905 10.9552 13.7271 11.8382 13.3285 12.5287C12.9298 13.2192 12.0468 13.4558 11.3563 13.0572Z" fill="url(#paint1_linear_1909_18132)"/>
</g>
<defs>
<linearGradient id="paint0_linear_1909_18132" x1="8.9717" y1="10.8245" x2="2.97903" y2="0.444546" gradientUnits="userSpaceOnUse">
<stop stop-color="#626F7A"/>
<stop offset="1" stop-color="#8B9299"/>
</linearGradient>
<linearGradient id="paint1_linear_1909_18132" x1="8.23537" y1="11.79" x2="15.9261" y2="11.7902" gradientUnits="userSpaceOnUse">
<stop stop-color="#626F7A"/>
<stop offset="1" stop-color="#8B9299"/>
</linearGradient>
<clipPath id="clip0_1909_18132">
<rect width="16" height="16" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@@ -0,0 +1,37 @@
// 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.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Resources;
using System.Text;
using System.Threading.Tasks;
using Microsoft.CmdPal.Ext.WindowsServices.Helpers;
using Microsoft.CmdPal.Ext.WindowsServices.Properties;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;
using Windows.UI;
namespace Microsoft.CmdPal.Ext.WindowsServices.Commands;
internal sealed partial class OpenServicesCommand : InvokableCommand
{
private readonly ServiceResult _serviceResult;
internal OpenServicesCommand(ServiceResult serviceResult)
{
_serviceResult = serviceResult;
Name = Resources.wox_plugin_service_open_services;
Icon = new IconInfo("\xE8A7"); // OpenInNewWindow icon
}
public override CommandResult Invoke()
{
Task.Run(() => ServiceHelper.OpenServices());
return CommandResult.Dismiss();
}
}

View File

@@ -0,0 +1,37 @@
// 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.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Resources;
using System.Text;
using System.Threading.Tasks;
using Microsoft.CmdPal.Ext.WindowsServices.Helpers;
using Microsoft.CmdPal.Ext.WindowsServices.Properties;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;
using Windows.UI;
namespace Microsoft.CmdPal.Ext.WindowsServices.Commands;
internal sealed partial class RestartServiceCommand : InvokableCommand
{
private readonly ServiceResult _serviceResult;
internal RestartServiceCommand(ServiceResult serviceResult)
{
_serviceResult = serviceResult;
Name = Resources.wox_plugin_service_restart;
Icon = new IconInfo("\xE72C"); // Refresh icon
}
public override CommandResult Invoke()
{
Task.Run(() => ServiceHelper.ChangeStatus(_serviceResult, Action.Restart));
return CommandResult.KeepOpen();
}
}

View File

@@ -0,0 +1,45 @@
// 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.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Resources;
using System.Text;
using System.Threading.Tasks;
using Microsoft.CmdPal.Ext.WindowsServices.Helpers;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;
using Windows.UI;
namespace Microsoft.CmdPal.Ext.WindowsServices.Commands;
internal sealed partial class ServiceCommand : InvokableCommand
{
private readonly ServiceResult _serviceResult;
private readonly Action _action;
internal ServiceCommand(ServiceResult serviceResult, Action action)
{
_serviceResult = serviceResult;
_action = action;
Name = action.ToString();
if (serviceResult.IsRunning)
{
Icon = new IconInfo("\xE71A"); // Stop icon
}
else
{
Icon = new IconInfo("\xEDB5"); // Playbadge12 icon
}
}
public override CommandResult Invoke()
{
Task.Run(() => ServiceHelper.ChangeStatus(_serviceResult, _action));
return CommandResult.KeepOpen();
}
}

View File

@@ -0,0 +1,253 @@
// 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.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using Microsoft.CmdPal.Ext.WindowsServices.Commands;
using Microsoft.CmdPal.Ext.WindowsServices.Properties;
using Microsoft.CommandPalette.Extensions.Toolkit;
using Microsoft.Win32;
using Windows.System;
namespace Microsoft.CmdPal.Ext.WindowsServices.Helpers;
public static class ServiceHelper
{
public static IEnumerable<ListItem> Search(string search)
{
var services = ServiceController.GetServices().OrderBy(s => s.DisplayName);
IEnumerable<ServiceController> serviceList = [];
if (search.StartsWith(Resources.wox_plugin_service_status + ":", StringComparison.CurrentCultureIgnoreCase))
{
// allows queries like 'status:running'
serviceList = services.Where(s => GetLocalizedStatus(s.Status).Contains(search.Split(':')[1], StringComparison.CurrentCultureIgnoreCase));
}
else if (search.StartsWith(Resources.wox_plugin_service_startup + ":", StringComparison.CurrentCultureIgnoreCase))
{
// allows queries like 'startup:automatic'
serviceList = services.Where(s => GetLocalizedStartType(s.StartType, s.ServiceName).Contains(search.Split(':')[1], StringComparison.CurrentCultureIgnoreCase));
}
else
{
// To show 'starts with' results first, we split the search into two steps and then concatenating the lists.
var servicesStartsWith = services
.Where(s => s.DisplayName.StartsWith(search, StringComparison.OrdinalIgnoreCase) || s.ServiceName.StartsWith(search, StringComparison.OrdinalIgnoreCase));
var servicesContains = services.Except(servicesStartsWith)
.Where(s => s.DisplayName.Contains(search, StringComparison.OrdinalIgnoreCase) || s.ServiceName.Contains(search, StringComparison.OrdinalIgnoreCase));
serviceList = servicesStartsWith.Concat(servicesContains);
}
var result = serviceList.Select(s =>
{
var serviceResult = ServiceResult.CreateServiceController(s);
if (serviceResult == null)
{
return null;
}
ServiceCommand serviceCommand;
CommandContextItem[] moreCommands;
if (serviceResult.IsRunning)
{
serviceCommand = new ServiceCommand(serviceResult, Action.Stop);
moreCommands = [
new CommandContextItem(new RestartServiceCommand(serviceResult)),
new CommandContextItem(new OpenServicesCommand(serviceResult))
{
RequestedShortcut = KeyChordHelpers.FromModifiers(true, false, false, false, (int)VirtualKey.O, 0),
},
];
}
else
{
serviceCommand = new ServiceCommand(serviceResult, Action.Start);
moreCommands = [
new CommandContextItem(new OpenServicesCommand(serviceResult)),
];
}
IconInfo icon = new("\U0001f7e2"); // unicode LARGE GREEN CIRCLE
switch (s.Status)
{
case ServiceControllerStatus.Stopped:
icon = new("\U0001F534"); // unicode LARGE RED CIRCLE
break;
case ServiceControllerStatus.Running:
break;
case ServiceControllerStatus.Paused:
icon = new("\u23F8"); // unicode DOUBLE VERTICAL BAR, aka, "Pause"
break;
}
return new ListItem(serviceCommand)
{
Title = s.DisplayName,
Subtitle = ServiceHelper.GetResultSubTitle(s),
MoreCommands = moreCommands,
Icon = icon,
// TODO GH #78 we need to improve the icon story
// TODO GH #126 investigate tooltip story
// ToolTipData = new ToolTipData(serviceResult.DisplayName, serviceResult.ServiceName),
// IcoPath = icoPath,
};
}).Where(s => s != null);
return result;
}
// TODO GH #118 IPublicAPI contextAPI isn't used anymore, but we need equivalent ways to show notifications and status
public static void ChangeStatus(ServiceResult serviceResult, Action action)
{
ArgumentNullException.ThrowIfNull(serviceResult);
// ArgumentNullException.ThrowIfNull(contextAPI);
try
{
var info = new ProcessStartInfo
{
FileName = "net",
Verb = "runas",
UseShellExecute = true,
WindowStyle = ProcessWindowStyle.Hidden,
};
if (action == Action.Start)
{
info.Arguments = $"start \"{serviceResult.ServiceName}\"";
}
else if (action == Action.Stop)
{
info.Arguments = $"stop \"{serviceResult.ServiceName}\"";
}
else if (action == Action.Restart)
{
info.FileName = "cmd";
info.Arguments = $"/c net stop \"{serviceResult.ServiceName}\" && net start \"{serviceResult.ServiceName}\"";
}
var process = Process.Start(info);
process.WaitForExit();
var exitCode = process.ExitCode;
#pragma warning disable IDE0059, CS0168, SA1005
if (exitCode == 0)
{
// TODO GH #118 feedback to users
// contextAPI.ShowNotification(GetLocalizedMessage(action), serviceResult.DisplayName);
}
else
{
// 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);
}
}
catch (Win32Exception ex)
{
// TODO GH #108 We need to figure out some logging
// Log.Error(ex.Message, MethodBase.GetCurrentMethod().DeclaringType);
}
}
#pragma warning restore IDE0059, CS0168, SA1005
public static void OpenServices()
{
try
{
var startInfo = new System.Diagnostics.ProcessStartInfo
{
FileName = "services.msc",
UseShellExecute = true,
};
System.Diagnostics.Process.Start(startInfo);
}
#pragma warning disable IDE0059, CS0168, SA1005
catch (Exception ex)
{
// TODO GH #108 We need to figure out some logging
}
}
#pragma warning restore IDE0059, CS0168, SA1005
private static string GetResultSubTitle(ServiceController serviceController)
{
ArgumentNullException.ThrowIfNull(serviceController);
return $"{Resources.wox_plugin_service_status}: {GetLocalizedStatus(serviceController.Status)} - {Resources.wox_plugin_service_startup}: {GetLocalizedStartType(serviceController.StartType, serviceController.ServiceName)} - {Resources.wox_plugin_service_name}: {serviceController.ServiceName}";
}
private static string GetLocalizedStatus(ServiceControllerStatus status)
{
if (status == ServiceControllerStatus.Stopped)
{
return Resources.wox_plugin_service_stopped;
}
else if (status == ServiceControllerStatus.StartPending)
{
return Resources.wox_plugin_service_start_pending;
}
else if (status == ServiceControllerStatus.StopPending)
{
return Resources.wox_plugin_service_stop_pending;
}
else if (status == ServiceControllerStatus.Running)
{
return Resources.wox_plugin_service_running;
}
else
{
return status == ServiceControllerStatus.ContinuePending
? Resources.wox_plugin_service_continue_pending
: status == ServiceControllerStatus.PausePending
? Resources.wox_plugin_service_pause_pending
: status == ServiceControllerStatus.Paused ? Resources.wox_plugin_service_paused : status.ToString();
}
}
private static string GetLocalizedStartType(ServiceStartMode startMode, string serviceName)
{
if (startMode == ServiceStartMode.Boot)
{
return Resources.wox_plugin_service_start_mode_boot;
}
else if (startMode == ServiceStartMode.System)
{
return Resources.wox_plugin_service_start_mode_system;
}
else
{
return startMode == ServiceStartMode.Automatic
? !IsDelayedStart(serviceName) ? Resources.wox_plugin_service_start_mode_automatic : Resources.wox_plugin_service_start_mode_automaticDelayed
: startMode == ServiceStartMode.Manual
? Resources.wox_plugin_service_start_mode_manual
: startMode == ServiceStartMode.Disabled ? Resources.wox_plugin_service_start_mode_disabled : startMode.ToString();
}
}
private static string GetLocalizedMessage(Action action)
{
return action == Action.Start
? Resources.wox_plugin_service_started_notification
: action == Action.Stop
? Resources.wox_plugin_service_stopped_notification
: action == Action.Restart ? Resources.wox_plugin_service_restarted_notification : string.Empty;
}
private static string GetLocalizedErrorMessage(Action action)
{
return action == Action.Start
? Resources.wox_plugin_service_start_error_notification
: action == Action.Stop
? Resources.wox_plugin_service_stop_error_notification
: action == Action.Restart ? Resources.wox_plugin_service_restart_error_notification : string.Empty;
}
private static bool IsDelayedStart(string serviceName) => (int?)Registry.LocalMachine.OpenSubKey(@"System\CurrentControlSet\Services\" + serviceName, false)?.GetValue("DelayedAutostart", 0, RegistryValueOptions.None) == 1;
}

View File

@@ -0,0 +1,42 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\..\Common.Dotnet.CsWinRT.props" />
<PropertyGroup>
<RootNamespace>Microsoft.CmdPal.Ext.WindowsServices</RootNamespace>
<OutputPath>$(SolutionDir)$(Platform)\$(Configuration)\WinUI3Apps\CmdPal</OutputPath>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
<!-- MRT from windows app sdk will search for a pri file with the same name of the module before defaulting to resources.pri -->
<ProjectPriFileName>Microsoft.CmdPal.Ext.WindowsServices.pri</ProjectPriFileName>
</PropertyGroup>
<ItemGroup>
<None Remove="Assets\Services.svg" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.ServiceProcess.ServiceController" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\extensionsdk\Microsoft.CommandPalette.Extensions.Toolkit\Microsoft.CommandPalette.Extensions.Toolkit.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<Content Update="Assets\Services.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Update="Assets\Services.svg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
</Project>

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 System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Microsoft.CmdPal.Ext.WindowsServices.Helpers;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;
namespace Microsoft.CmdPal.Ext.WindowsServices;
internal sealed partial class ServicesListPage : DynamicListPage
{
public ServicesListPage()
{
Icon = WindowsServicesCommandsProvider.ServicesIcon;
Name = "Windows Services";
}
public override void UpdateSearchText(string oldSearch, string newSearch) => RaiseItemsChanged(0);
public override IListItem[] GetItems()
{
var items = ServiceHelper.Search(SearchText).ToArray();
return items;
}
}

View File

@@ -0,0 +1,333 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Microsoft.CmdPal.Ext.WindowsServices.Properties {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.CmdPal.Ext.WindowsServices.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to Windows Services.
/// </summary>
internal static string WindowsServicesProvider_DisplayName {
get {
return ResourceManager.GetString("WindowsServicesProvider_DisplayName", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Continue.
/// </summary>
internal static string wox_plugin_service_continue_pending {
get {
return ResourceManager.GetString("wox_plugin_service_continue_pending", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Name.
/// </summary>
internal static string wox_plugin_service_name {
get {
return ResourceManager.GetString("wox_plugin_service_name", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Open services (Ctrl+O).
/// </summary>
internal static string wox_plugin_service_open_services {
get {
return ResourceManager.GetString("wox_plugin_service_open_services", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Pausing.
/// </summary>
internal static string wox_plugin_service_pause_pending {
get {
return ResourceManager.GetString("wox_plugin_service_pause_pending", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Paused.
/// </summary>
internal static string wox_plugin_service_paused {
get {
return ResourceManager.GetString("wox_plugin_service_paused", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Manages Windows services.
/// </summary>
internal static string wox_plugin_service_plugin_description {
get {
return ResourceManager.GetString("wox_plugin_service_plugin_description", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Service.
/// </summary>
internal static string wox_plugin_service_plugin_name {
get {
return ResourceManager.GetString("wox_plugin_service_plugin_name", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Restart (Ctrl+R).
/// </summary>
internal static string wox_plugin_service_restart {
get {
return ResourceManager.GetString("wox_plugin_service_restart", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to An error occurred while restarting the service.
/// </summary>
internal static string wox_plugin_service_restart_error_notification {
get {
return ResourceManager.GetString("wox_plugin_service_restart_error_notification", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The service has been restarted.
/// </summary>
internal static string wox_plugin_service_restarted_notification {
get {
return ResourceManager.GetString("wox_plugin_service_restarted_notification", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Running.
/// </summary>
internal static string wox_plugin_service_running {
get {
return ResourceManager.GetString("wox_plugin_service_running", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Start (Enter).
/// </summary>
internal static string wox_plugin_service_start {
get {
return ResourceManager.GetString("wox_plugin_service_start", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to An error occurred while starting the service.
/// </summary>
internal static string wox_plugin_service_start_error_notification {
get {
return ResourceManager.GetString("wox_plugin_service_start_error_notification", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Automatic.
/// </summary>
internal static string wox_plugin_service_start_mode_automatic {
get {
return ResourceManager.GetString("wox_plugin_service_start_mode_automatic", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Automatic (Delayed Start).
/// </summary>
internal static string wox_plugin_service_start_mode_automaticDelayed {
get {
return ResourceManager.GetString("wox_plugin_service_start_mode_automaticDelayed", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Boot.
/// </summary>
internal static string wox_plugin_service_start_mode_boot {
get {
return ResourceManager.GetString("wox_plugin_service_start_mode_boot", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Disabled.
/// </summary>
internal static string wox_plugin_service_start_mode_disabled {
get {
return ResourceManager.GetString("wox_plugin_service_start_mode_disabled", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Manual.
/// </summary>
internal static string wox_plugin_service_start_mode_manual {
get {
return ResourceManager.GetString("wox_plugin_service_start_mode_manual", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to System.
/// </summary>
internal static string wox_plugin_service_start_mode_system {
get {
return ResourceManager.GetString("wox_plugin_service_start_mode_system", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Starting.
/// </summary>
internal static string wox_plugin_service_start_pending {
get {
return ResourceManager.GetString("wox_plugin_service_start_pending", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Started.
/// </summary>
internal static string wox_plugin_service_started {
get {
return ResourceManager.GetString("wox_plugin_service_started", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The service has been started.
/// </summary>
internal static string wox_plugin_service_started_notification {
get {
return ResourceManager.GetString("wox_plugin_service_started_notification", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Startup.
/// </summary>
internal static string wox_plugin_service_startup {
get {
return ResourceManager.GetString("wox_plugin_service_startup", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Status.
/// </summary>
internal static string wox_plugin_service_status {
get {
return ResourceManager.GetString("wox_plugin_service_status", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Stop (Enter).
/// </summary>
internal static string wox_plugin_service_stop {
get {
return ResourceManager.GetString("wox_plugin_service_stop", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to An error occurred while stopping the service.
/// </summary>
internal static string wox_plugin_service_stop_error_notification {
get {
return ResourceManager.GetString("wox_plugin_service_stop_error_notification", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Stopping.
/// </summary>
internal static string wox_plugin_service_stop_pending {
get {
return ResourceManager.GetString("wox_plugin_service_stop_pending", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Stopped.
/// </summary>
internal static string wox_plugin_service_stopped {
get {
return ResourceManager.GetString("wox_plugin_service_stopped", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The service has been stopped.
/// </summary>
internal static string wox_plugin_service_stopped_notification {
get {
return ResourceManager.GetString("wox_plugin_service_stopped_notification", resourceCulture);
}
}
}
}

View File

@@ -0,0 +1,210 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="WindowsServicesProvider_DisplayName" xml:space="preserve">
<value>Windows Services</value>
</data>
<data name="wox_plugin_service_continue_pending" xml:space="preserve">
<value>Continue</value>
</data>
<data name="wox_plugin_service_name" xml:space="preserve">
<value>Name</value>
</data>
<data name="wox_plugin_service_open_services" xml:space="preserve">
<value>Open services</value>
</data>
<data name="wox_plugin_service_paused" xml:space="preserve">
<value>Paused</value>
</data>
<data name="wox_plugin_service_pause_pending" xml:space="preserve">
<value>Pausing</value>
</data>
<data name="wox_plugin_service_plugin_description" xml:space="preserve">
<value>Manages Windows services</value>
</data>
<data name="wox_plugin_service_plugin_name" xml:space="preserve">
<value>Service</value>
</data>
<data name="wox_plugin_service_restart" xml:space="preserve">
<value>Restart</value>
</data>
<data name="wox_plugin_service_restarted_notification" xml:space="preserve">
<value>The service has been restarted</value>
</data>
<data name="wox_plugin_service_restart_error_notification" xml:space="preserve">
<value>An error occurred while restarting the service</value>
</data>
<data name="wox_plugin_service_running" xml:space="preserve">
<value>Running</value>
</data>
<data name="wox_plugin_service_start" xml:space="preserve">
<value>Start (Enter)</value>
</data>
<data name="wox_plugin_service_started" xml:space="preserve">
<value>Started</value>
</data>
<data name="wox_plugin_service_started_notification" xml:space="preserve">
<value>The service has been started</value>
</data>
<data name="wox_plugin_service_startup" xml:space="preserve">
<value>Startup</value>
</data>
<data name="wox_plugin_service_start_error_notification" xml:space="preserve">
<value>An error occurred while starting the service</value>
</data>
<data name="wox_plugin_service_start_mode_automatic" xml:space="preserve">
<value>Automatic</value>
</data>
<data name="wox_plugin_service_start_mode_automaticDelayed" xml:space="preserve">
<value>Automatic (Delayed Start)</value>
</data>
<data name="wox_plugin_service_start_mode_boot" xml:space="preserve">
<value>Boot</value>
</data>
<data name="wox_plugin_service_start_mode_disabled" xml:space="preserve">
<value>Disabled</value>
</data>
<data name="wox_plugin_service_start_mode_manual" xml:space="preserve">
<value>Manual</value>
</data>
<data name="wox_plugin_service_start_mode_system" xml:space="preserve">
<value>System</value>
</data>
<data name="wox_plugin_service_start_pending" xml:space="preserve">
<value>Starting</value>
</data>
<data name="wox_plugin_service_status" xml:space="preserve">
<value>Status</value>
</data>
<data name="wox_plugin_service_stop" xml:space="preserve">
<value>Stop (Enter)</value>
</data>
<data name="wox_plugin_service_stopped" xml:space="preserve">
<value>Stopped</value>
</data>
<data name="wox_plugin_service_stopped_notification" xml:space="preserve">
<value>The service has been stopped</value>
</data>
<data name="wox_plugin_service_stop_error_notification" xml:space="preserve">
<value>An error occurred while stopping the service</value>
</data>
<data name="wox_plugin_service_stop_pending" xml:space="preserve">
<value>Stopping</value>
</data>
</root>

View File

@@ -0,0 +1,46 @@
// 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.ServiceProcess;
namespace Microsoft.CmdPal.Ext.WindowsServices;
public class ServiceResult
{
public string ServiceName { get; }
public string DisplayName { get; }
public ServiceStartMode StartMode { get; }
public bool IsRunning { get; }
private ServiceResult(ServiceController serviceController)
{
ArgumentNullException.ThrowIfNull(serviceController);
ServiceName = serviceController.ServiceName;
DisplayName = serviceController.DisplayName;
StartMode = serviceController.StartType;
IsRunning = serviceController.Status != ServiceControllerStatus.Stopped && serviceController.Status != ServiceControllerStatus.StopPending;
}
public static ServiceResult CreateServiceController(ServiceController serviceController)
{
try
{
var result = new ServiceResult(serviceController);
return result;
}
catch (Exception)
{
// try to log the exception in the future
// retrieve properties from serviceController will throw exception. Such as PlatformNotSupportedException.
}
return null;
}
}

View File

@@ -0,0 +1,33 @@
// 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.CmdPal.Ext.WindowsServices.Properties;
using Microsoft.CommandPalette.Extensions;
using Microsoft.CommandPalette.Extensions.Toolkit;
namespace Microsoft.CmdPal.Ext.WindowsServices;
public partial class WindowsServicesCommandsProvider : CommandProvider
{
// For giggles, "%windir%\\system32\\filemgmt.dll" also _just works_.
public static IconInfo ServicesIcon { get; } = IconHelpers.FromRelativePath("Assets\\Services.svg");
public WindowsServicesCommandsProvider()
{
Id = "Windows.Services";
DisplayName = Resources.WindowsServicesProvider_DisplayName;
Icon = ServicesIcon;
}
public override ICommandItem[] TopLevelCommands()
{
return [
new CommandItem(new ServicesListPage())
{
Title = "Windows Services",
Subtitle = "Manage Windows Services",
}
];
}
}