258 lines
7.9 KiB
C#
258 lines
7.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Linq;
|
|
using System.ServiceProcess;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using System.Windows;
|
|
using System.Windows.Threading;
|
|
using AxCopilot.SDK;
|
|
using AxCopilot.Services;
|
|
|
|
namespace AxCopilot.Handlers;
|
|
|
|
public class ServiceHandler : IActionHandler
|
|
{
|
|
private readonly ClipboardHistoryService? _clipboardService;
|
|
|
|
public string? Prefix => "svc";
|
|
|
|
public PluginMetadata Metadata => new PluginMetadata("Service", "Windows 서비스 관리 — svc", "1.0", "AX");
|
|
|
|
public ServiceHandler(ClipboardHistoryService? clipboardService = null)
|
|
{
|
|
_clipboardService = clipboardService;
|
|
}
|
|
|
|
public Task<IEnumerable<LauncherItem>> GetItemsAsync(string query, CancellationToken ct)
|
|
{
|
|
string q = query.Trim();
|
|
List<LauncherItem> list = new List<LauncherItem>();
|
|
if (q.Equals("restart clipboard", StringComparison.OrdinalIgnoreCase) || q.Equals("클립보드 재시작", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
list.Add(new LauncherItem("AX 클립보드 히스토리 서비스 재시작", "클립보드 감지가 작동하지 않을 때 사용 · Enter로 실행", null, "__RESTART_CLIPBOARD__", null, "\ue777"));
|
|
return Task.FromResult((IEnumerable<LauncherItem>)list);
|
|
}
|
|
if (q.StartsWith("start ", StringComparison.OrdinalIgnoreCase) || q.StartsWith("stop ", StringComparison.OrdinalIgnoreCase) || q.StartsWith("restart ", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
string[] array = q.Split(' ', 2, StringSplitOptions.TrimEntries);
|
|
string text = array[0].ToLowerInvariant();
|
|
string svcName = ((array.Length > 1) ? array[1] : "");
|
|
if (!string.IsNullOrWhiteSpace(svcName))
|
|
{
|
|
try
|
|
{
|
|
ServiceController serviceController = ServiceController.GetServices().FirstOrDefault((ServiceController s) => s.ServiceName.Contains(svcName, StringComparison.OrdinalIgnoreCase) || s.DisplayName.Contains(svcName, StringComparison.OrdinalIgnoreCase));
|
|
if (serviceController != null)
|
|
{
|
|
if (1 == 0)
|
|
{
|
|
}
|
|
string text2 = text switch
|
|
{
|
|
"start" => "시작",
|
|
"stop" => "중지",
|
|
"restart" => "재시작",
|
|
_ => text,
|
|
};
|
|
if (1 == 0)
|
|
{
|
|
}
|
|
string text3 = text2;
|
|
list.Add(new LauncherItem("[" + text3 + "] " + serviceController.DisplayName, $"서비스명: {serviceController.ServiceName} · 현재 상태: {StatusText(serviceController.Status)} · Enter로 실행", null, ("__" + text.ToUpperInvariant() + "__", serviceController.ServiceName), null, (text == "stop") ? "\uea39" : "\ue777"));
|
|
}
|
|
else
|
|
{
|
|
list.Add(new LauncherItem("'" + svcName + "' 서비스를 찾을 수 없습니다", "서비스 이름 또는 표시 이름으로 검색", null, null, null, "\ue7ba"));
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
list.Add(new LauncherItem("서비스 조회 실패", ex.Message, null, null, null, "\uea39"));
|
|
}
|
|
return Task.FromResult((IEnumerable<LauncherItem>)list);
|
|
}
|
|
}
|
|
try
|
|
{
|
|
ServiceController[] services = ServiceController.GetServices();
|
|
IEnumerable<ServiceController> enumerable = (string.IsNullOrWhiteSpace(q) ? (from s in services
|
|
where s.Status == ServiceControllerStatus.Running
|
|
orderby s.DisplayName
|
|
select s).Take(20) : (from s in services
|
|
where s.ServiceName.Contains(q, StringComparison.OrdinalIgnoreCase) || s.DisplayName.Contains(q, StringComparison.OrdinalIgnoreCase)
|
|
orderby s.DisplayName
|
|
select s).Take(20));
|
|
list.Add(new LauncherItem("AX 클립보드 히스토리 서비스 재시작", "svc restart clipboard · 클립보드 감지 문제 시 사용", null, "__RESTART_CLIPBOARD__", null, "\ue777"));
|
|
foreach (ServiceController item in enumerable)
|
|
{
|
|
string text4 = StatusText(item.Status);
|
|
string symbol = ((item.Status == ServiceControllerStatus.Running) ? "\ue73e" : "\ue711");
|
|
list.Add(new LauncherItem("[" + text4 + "] " + item.DisplayName, item.ServiceName + " · svc start/stop/restart " + item.ServiceName, null, item.ServiceName, null, symbol));
|
|
}
|
|
}
|
|
catch (Exception ex2)
|
|
{
|
|
list.Add(new LauncherItem("서비스 조회 실패", ex2.Message, null, null, null, "\uea39"));
|
|
}
|
|
return Task.FromResult((IEnumerable<LauncherItem>)list);
|
|
}
|
|
|
|
public Task ExecuteAsync(LauncherItem item, CancellationToken ct)
|
|
{
|
|
if (item.Data is string text && text == "__RESTART_CLIPBOARD__")
|
|
{
|
|
RestartClipboardService();
|
|
return Task.CompletedTask;
|
|
}
|
|
if (!(item.Data is (string, string) tuple))
|
|
{
|
|
object data = item.Data;
|
|
string name = data as string;
|
|
if (name != null)
|
|
{
|
|
try
|
|
{
|
|
Application current = Application.Current;
|
|
if (current != null)
|
|
{
|
|
((DispatcherObject)current).Dispatcher.Invoke((Action)delegate
|
|
{
|
|
Clipboard.SetText(name);
|
|
});
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
}
|
|
return Task.CompletedTask;
|
|
}
|
|
var (action, svcName) = tuple;
|
|
return ExecuteServiceAction(action, svcName);
|
|
}
|
|
|
|
private void RestartClipboardService()
|
|
{
|
|
try
|
|
{
|
|
if (_clipboardService == null)
|
|
{
|
|
NotificationService.Notify("AX Copilot", "클립보드 서비스 참조를 찾을 수 없습니다.");
|
|
return;
|
|
}
|
|
_clipboardService.Dispose();
|
|
Application current = Application.Current;
|
|
if (current == null)
|
|
{
|
|
return;
|
|
}
|
|
((DispatcherObject)current).Dispatcher.BeginInvoke((Delegate)(Action)delegate
|
|
{
|
|
try
|
|
{
|
|
_clipboardService.Reinitialize();
|
|
NotificationService.Notify("AX Copilot", "클립보드 히스토리 서비스가 재시작되었습니다.");
|
|
LogService.Info("클립보드 히스토리 서비스 강제 재시작 완료");
|
|
}
|
|
catch (Exception ex2)
|
|
{
|
|
NotificationService.Notify("AX Copilot", "클립보드 재시작 실패: " + ex2.Message);
|
|
LogService.Error("클립보드 재시작 실패: " + ex2.Message);
|
|
}
|
|
}, (DispatcherPriority)4, Array.Empty<object>());
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
NotificationService.Notify("AX Copilot", "클립보드 재시작 실패: " + ex.Message);
|
|
}
|
|
}
|
|
|
|
private static async Task ExecuteServiceAction(string action, string svcName)
|
|
{
|
|
try
|
|
{
|
|
if (1 == 0)
|
|
{
|
|
}
|
|
string text = action switch
|
|
{
|
|
"__START__" => "start",
|
|
"__STOP__" => "stop",
|
|
"__RESTART__" => "stop",
|
|
_ => null,
|
|
};
|
|
if (1 == 0)
|
|
{
|
|
}
|
|
string verb = text;
|
|
if (verb != null)
|
|
{
|
|
ProcessStartInfo psi = new ProcessStartInfo("sc.exe", verb + " \"" + svcName + "\"")
|
|
{
|
|
Verb = "runas",
|
|
UseShellExecute = true,
|
|
CreateNoWindow = true,
|
|
WindowStyle = ProcessWindowStyle.Hidden
|
|
};
|
|
Process.Start(psi)?.WaitForExit(5000);
|
|
if (action == "__RESTART__")
|
|
{
|
|
await Task.Delay(1000);
|
|
ProcessStartInfo startPsi = new ProcessStartInfo("sc.exe", "start \"" + svcName + "\"")
|
|
{
|
|
Verb = "runas",
|
|
UseShellExecute = true,
|
|
CreateNoWindow = true,
|
|
WindowStyle = ProcessWindowStyle.Hidden
|
|
};
|
|
Process.Start(startPsi)?.WaitForExit(5000);
|
|
}
|
|
if (1 == 0)
|
|
{
|
|
}
|
|
text = action switch
|
|
{
|
|
"__START__" => "시작",
|
|
"__STOP__" => "중지",
|
|
"__RESTART__" => "재시작",
|
|
_ => action,
|
|
};
|
|
if (1 == 0)
|
|
{
|
|
}
|
|
string label = text;
|
|
NotificationService.Notify("서비스 관리", svcName + " " + label + " 요청 완료");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Exception ex2 = ex;
|
|
NotificationService.Notify("AX Copilot", "서비스 제어 실패: " + ex2.Message);
|
|
}
|
|
}
|
|
|
|
private static string StatusText(ServiceControllerStatus status)
|
|
{
|
|
if (1 == 0)
|
|
{
|
|
}
|
|
string result = status switch
|
|
{
|
|
ServiceControllerStatus.Running => "실행 중",
|
|
ServiceControllerStatus.Stopped => "중지됨",
|
|
ServiceControllerStatus.StartPending => "시작 중",
|
|
ServiceControllerStatus.StopPending => "중지 중",
|
|
ServiceControllerStatus.Paused => "일시 중지",
|
|
ServiceControllerStatus.ContinuePending => "재개 중",
|
|
ServiceControllerStatus.PausePending => "일시 중지 중",
|
|
_ => status.ToString(),
|
|
};
|
|
if (1 == 0)
|
|
{
|
|
}
|
|
return result;
|
|
}
|
|
}
|