[PT Run] Service Plugin (#8076)

* PT Run service plugin

* icon, localization and fixes

* basic toast notification

* service start mode

* improved keys

* fixed setup

* improvements

* added _ keyword
* better shortcuts
* action for open services.msc

* pt run service plugin dll signing

* renamed Microsoft.Plugin.Service

* changed output dir

* set ! action keyword

* launcher dll

Co-authored-by: Clint Rutkas <clint@rutkas.com>
This commit is contained in:
Davide Giacometti
2021-01-06 11:40:07 +01:00
committed by GitHub
parent f0600f1725
commit 3a87c4909c
18 changed files with 1071 additions and 4 deletions

View File

@@ -0,0 +1,215 @@
// 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.Globalization;
using System.Linq;
using System.Reflection;
using System.ServiceProcess;
using Microsoft.PowerToys.Run.Plugin.Service.Properties;
using Wox.Plugin;
using Wox.Plugin.Logger;
namespace Microsoft.PowerToys.Run.Plugin.Service.Helpers
{
public static class ServiceHelper
{
public static IEnumerable<Result> Search(string search, string icoPath)
{
var services = ServiceController.GetServices();
return services
.Where(s => s.DisplayName.StartsWith(search, StringComparison.OrdinalIgnoreCase) || s.ServiceName.StartsWith(search, StringComparison.OrdinalIgnoreCase))
.Select(s => new Result
{
Title = GetResultTitle(s),
SubTitle = GetResultSubTitle(s),
IcoPath = icoPath,
ContextData = new ServiceResult(s),
});
}
public static void ChangeStatus(ServiceResult serviceResult, Action action, IPublicAPI contextAPI)
{
if (serviceResult == null)
{
throw new ArgumentNullException(nameof(serviceResult));
}
if (contextAPI == null)
{
throw new ArgumentNullException(nameof(contextAPI));
}
try
{
var info = new ProcessStartInfo
{
FileName = "net",
Verb = "runas",
UseShellExecute = true,
WindowStyle = ProcessWindowStyle.Hidden,
};
if (action == Action.Start)
{
info.Arguments = string.Join(' ', "start", serviceResult.ServiceName);
}
else if (action == Action.Stop)
{
info.Arguments = string.Join(' ', "stop", serviceResult.ServiceName);
}
else if (action == Action.Restart)
{
info.FileName = "cmd";
info.Arguments = string.Join(' ', "/c net stop", serviceResult.ServiceName, "&&", "net start", serviceResult.ServiceName);
}
var process = Process.Start(info);
process.WaitForExit();
var exitCode = process.ExitCode;
if (exitCode == 0)
{
contextAPI.ShowNotification(GetLocalizedMessage(serviceResult, action));
}
else
{
contextAPI.ShowNotification("An error occurred");
Log.Error($"The command returned {exitCode}", MethodBase.GetCurrentMethod().DeclaringType);
}
}
catch (Win32Exception ex)
{
Log.Error(ex.Message, MethodBase.GetCurrentMethod().DeclaringType);
}
}
public static void OpenServices()
{
try
{
var info = new ProcessStartInfo
{
FileName = "services.msc",
UseShellExecute = true,
};
Process.Start(info);
}
catch (Win32Exception ex)
{
Log.Error(ex.Message, MethodBase.GetCurrentMethod().DeclaringType);
}
}
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)
{
throw new ArgumentNullException(nameof(serviceController));
}
return $"{Resources.wox_plugin_service_status}: {GetLocalizedStatus(serviceController.Status)} - {Resources.wox_plugin_service_startup}: {GetLocalizedStartType(serviceController.StartType)}";
}
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 if (status == ServiceControllerStatus.ContinuePending)
{
return Resources.wox_plugin_service_continue_pending;
}
else if (status == ServiceControllerStatus.PausePending)
{
return Resources.wox_plugin_service_pause_pending;
}
else if (status == ServiceControllerStatus.Paused)
{
return Resources.wox_plugin_service_paused;
}
else
{
return status.ToString();
}
}
private static string GetLocalizedStartType(ServiceStartMode startMode)
{
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 if (startMode == ServiceStartMode.Automatic)
{
return Resources.wox_plugin_service_start_mode_automatic;
}
else if (startMode == ServiceStartMode.Manual)
{
return Resources.wox_plugin_service_start_mode_manual;
}
else if (startMode == ServiceStartMode.Disabled)
{
return Resources.wox_plugin_service_start_mode_disabled;
}
else
{
return startMode.ToString();
}
}
private static string GetLocalizedMessage(ServiceResult serviceResult, Action action)
{
if (action == Action.Start)
{
return string.Format(CultureInfo.CurrentCulture, Resources.wox_plugin_service_started_notification, serviceResult.DisplayName);
}
else if (action == Action.Stop)
{
return string.Format(CultureInfo.CurrentCulture, Resources.wox_plugin_service_stopped_notification, serviceResult.DisplayName);
}
else if (action == Action.Restart)
{
return string.Format(CultureInfo.CurrentCulture, Resources.wox_plugin_service_restarted_notification, serviceResult.DisplayName);
}
else
{
return string.Empty;
}
}
}
}