From 741457ffa53c470c7867ab0a4a452737d8a1118a Mon Sep 17 00:00:00 2001 From: Heiko <61519853+htcfreek@users.noreply.github.com> Date: Tue, 10 May 2022 18:07:39 +0200 Subject: [PATCH] [PT Run] Services plugin: Various improvements (#17985) * search for contains too * fix startup types & new filter * fix spelling * small fixes * fix spacing * Improve order and layout * clean up * switch to nullable int32 --- .github/actions/spell-check/expect.txt | 1 + .../Helpers/ServiceHelper.cs | 103 ++++++++++-------- .../Properties/Resources.Designer.cs | 20 +++- .../Properties/Resources.resx | 6 + 4 files changed, 85 insertions(+), 45 deletions(-) diff --git a/.github/actions/spell-check/expect.txt b/.github/actions/spell-check/expect.txt index f0c4633ea5..b4435be2ba 100644 --- a/.github/actions/spell-check/expect.txt +++ b/.github/actions/spell-check/expect.txt @@ -122,6 +122,7 @@ autogenerated AUTOHIDE AUTOMATIONPROPERTIES Autorun +Autostart AUTOUPDATE AValid Avanc diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Service/Helpers/ServiceHelper.cs b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Service/Helpers/ServiceHelper.cs index c28df66658..40fb5b1774 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Service/Helpers/ServiceHelper.cs +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Service/Helpers/ServiceHelper.cs @@ -11,6 +11,7 @@ using System.Reflection; using System.ServiceProcess; using System.Threading.Tasks; using Microsoft.PowerToys.Run.Plugin.Service.Properties; +using Microsoft.Win32; using Wox.Infrastructure; using Wox.Plugin; using Wox.Plugin.Logger; @@ -21,40 +22,60 @@ namespace Microsoft.PowerToys.Run.Plugin.Service.Helpers { public static IEnumerable Search(string search, string icoPath, PluginInitContext context) { - var services = ServiceController.GetServices(); + var services = ServiceController.GetServices().OrderBy(s => s.DisplayName); + IEnumerable serviceList = new List(); - return services - .Where(s => s.DisplayName.StartsWith(search, StringComparison.OrdinalIgnoreCase) || s.ServiceName.StartsWith(search, StringComparison.OrdinalIgnoreCase) || GetResultTitle(s).StartsWith(search, StringComparison.OrdinalIgnoreCase)) - .Select(s => + 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); + } + + return serviceList.Select(s => + { + ServiceResult serviceResult = new ServiceResult(s); + Func serviceAction; + if (serviceResult.IsRunning) { - ServiceResult serviceResult = new ServiceResult(s); - Func serviceAction; - if (serviceResult.IsRunning) + serviceAction = _ => { - serviceAction = _ => - { - Task.Run(() => ServiceHelper.ChangeStatus(serviceResult, Action.Stop, context.API)); - return true; - }; - } - else - { - serviceAction = _ => - { - Task.Run(() => ServiceHelper.ChangeStatus(serviceResult, Action.Start, context.API)); - return true; - }; - } - - return new Result - { - Title = ServiceHelper.GetResultTitle(s), - SubTitle = ServiceHelper.GetResultSubTitle(s), - IcoPath = icoPath, - ContextData = serviceResult, - Action = serviceAction, + Task.Run(() => ServiceHelper.ChangeStatus(serviceResult, Action.Stop, context.API)); + return true; }; - }); + } + else + { + serviceAction = _ => + { + Task.Run(() => ServiceHelper.ChangeStatus(serviceResult, Action.Start, context.API)); + return true; + }; + } + + return new Result + { + Title = s.DisplayName, + SubTitle = ServiceHelper.GetResultSubTitle(s), + ToolTipData = new ToolTipData(serviceResult.DisplayName, serviceResult.ServiceName), + IcoPath = icoPath, + ContextData = serviceResult, + Action = serviceAction, + }; + }); } public static void ChangeStatus(ServiceResult serviceResult, Action action, IPublicAPI contextAPI) @@ -118,17 +139,6 @@ namespace Microsoft.PowerToys.Run.Plugin.Service.Helpers Helper.OpenInShell("services.msc"); } - private static string GetResultTitle(ServiceController serviceController) - { - if (serviceController == null) - { - throw new ArgumentNullException(nameof(serviceController)); - } - - var suffix = $"({serviceController.ServiceName})"; - return serviceController.DisplayName.EndsWith(suffix, StringComparison.CurrentCulture) ? serviceController.DisplayName : $"{serviceController.DisplayName} {suffix}"; - } - private static string GetResultSubTitle(ServiceController serviceController) { if (serviceController == null) @@ -136,7 +146,7 @@ namespace Microsoft.PowerToys.Run.Plugin.Service.Helpers throw new ArgumentNullException(nameof(serviceController)); } - return $"{Resources.wox_plugin_service_status}: {GetLocalizedStatus(serviceController.Status)} - {Resources.wox_plugin_service_startup}: {GetLocalizedStartType(serviceController.StartType)}"; + 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) @@ -175,7 +185,7 @@ namespace Microsoft.PowerToys.Run.Plugin.Service.Helpers } } - private static string GetLocalizedStartType(ServiceStartMode startMode) + private static string GetLocalizedStartType(ServiceStartMode startMode, string serviceName) { if (startMode == ServiceStartMode.Boot) { @@ -187,7 +197,7 @@ namespace Microsoft.PowerToys.Run.Plugin.Service.Helpers } else if (startMode == ServiceStartMode.Automatic) { - return Resources.wox_plugin_service_start_mode_automatic; + return !IsDelayedStart(serviceName) ? Resources.wox_plugin_service_start_mode_automatic : Resources.wox_plugin_service_start_mode_automaticDelayed; } else if (startMode == ServiceStartMode.Manual) { @@ -242,5 +252,10 @@ namespace Microsoft.PowerToys.Run.Plugin.Service.Helpers return string.Empty; } } + + private static bool IsDelayedStart(string serviceName) + { + return (int?)Registry.LocalMachine.OpenSubKey(@"System\CurrentControlSet\Services\" + serviceName, false)?.GetValue("DelayedAutostart", 0, RegistryValueOptions.None) == 1; + } } } diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Service/Properties/Resources.Designer.cs b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Service/Properties/Resources.Designer.cs index c20f760c02..6380120ff3 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Service/Properties/Resources.Designer.cs +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Service/Properties/Resources.Designer.cs @@ -19,7 +19,7 @@ namespace Microsoft.PowerToys.Run.Plugin.Service.Properties { // 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", "16.0.0.0")] + [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 { @@ -69,6 +69,15 @@ namespace Microsoft.PowerToys.Run.Plugin.Service.Properties { } } + /// + /// Looks up a localized string similar to Name. + /// + internal static string wox_plugin_service_name { + get { + return ResourceManager.GetString("wox_plugin_service_name", resourceCulture); + } + } + /// /// Looks up a localized string similar to Open services (Ctrl+O). /// @@ -177,6 +186,15 @@ namespace Microsoft.PowerToys.Run.Plugin.Service.Properties { } } + /// + /// Looks up a localized string similar to Automatic (Delayed Start). + /// + internal static string wox_plugin_service_start_mode_automaticDelayed { + get { + return ResourceManager.GetString("wox_plugin_service_start_mode_automaticDelayed", resourceCulture); + } + } + /// /// Looks up a localized string similar to Boot. /// diff --git a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Service/Properties/Resources.resx b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Service/Properties/Resources.resx index 9114d7bcba..f5a899fd13 100644 --- a/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Service/Properties/Resources.resx +++ b/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Service/Properties/Resources.resx @@ -120,6 +120,9 @@ Continue + + Name + Open services (Ctrl+O) @@ -165,6 +168,9 @@ Automatic + + Automatic (Delayed Start) + Boot