insight/src/Agent/Insight.Agent/Network/Handlers/ServiceHandler.cs

118 lines
4.5 KiB
C#
Raw Normal View History

2023-09-21 22:10:55 +02:00
using Insight.Domain.Interfaces;
using Insight.Domain.Messages;
using Insight.Domain.Messages.Agent;
2023-09-21 18:58:32 +02:00
using System.Management;
using System.Runtime.Versioning;
using System.ServiceProcess;
2023-09-21 22:10:55 +02:00
namespace Insight.Agent.Network.Handlers;
[SupportedOSPlatform("windows")]
public class ServiceHandler : IMessageHandler<AgentSession>
2023-09-21 18:58:32 +02:00
{
2023-09-21 22:10:55 +02:00
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
2023-09-21 18:58:32 +02:00
{
2023-09-21 22:10:55 +02:00
if (message is InventoryRequest)
2023-09-21 18:58:32 +02:00
{
2023-09-21 22:10:55 +02:00
var result = new ServiceList();
result.AddRange(GetServices());
2023-09-21 18:58:32 +02:00
2023-09-21 22:10:55 +02:00
await sender.SendAsync(result, cancellationToken);
2023-09-21 18:58:32 +02:00
}
2023-09-21 22:10:55 +02:00
}
2023-09-21 18:58:32 +02:00
2023-09-21 22:10:55 +02:00
private static List<Service> GetServices()
{
var services = new List<Service>();
2023-09-21 18:58:32 +02:00
2023-09-21 22:10:55 +02:00
var serviceControllers = ServiceController.GetServices()?.OrderBy(s => s.DisplayName)?.ToList();
if (serviceControllers is null || serviceControllers.Any() is false) throw new InvalidOperationException("SERVICE Collection NULL");
2023-09-21 18:58:32 +02:00
2023-09-21 22:10:55 +02:00
foreach (var sc in serviceControllers)
{
var status = sc.Status switch
2023-09-21 18:58:32 +02:00
{
2023-09-21 22:10:55 +02:00
ServiceControllerStatus.Stopped => Service.ServiceStatus.Stopped,
ServiceControllerStatus.StartPending => Service.ServiceStatus.StartPending,
ServiceControllerStatus.StopPending => Service.ServiceStatus.StopPending,
ServiceControllerStatus.Running => Service.ServiceStatus.Running,
ServiceControllerStatus.ContinuePending => Service.ServiceStatus.ContinuePending,
ServiceControllerStatus.PausePending => Service.ServiceStatus.PausePending,
ServiceControllerStatus.Paused => Service.ServiceStatus.Paused,
_ => Service.ServiceStatus.Unknown
};
2023-09-21 18:58:32 +02:00
2023-09-21 22:10:55 +02:00
var mode = sc.StartType switch
2023-09-21 18:58:32 +02:00
{
2023-09-21 22:10:55 +02:00
ServiceStartMode.Boot => Service.ServiceMode.Boot,
ServiceStartMode.System => Service.ServiceMode.System,
ServiceStartMode.Automatic => Service.ServiceMode.Automatic,
ServiceStartMode.Manual => Service.ServiceMode.Manual,
ServiceStartMode.Disabled => Service.ServiceMode.Disabled,
_ => Service.ServiceMode.Unknown,
2023-09-21 18:58:32 +02:00
};
2023-09-21 22:10:55 +02:00
var service = new Service
2023-09-21 18:58:32 +02:00
{
2023-09-21 22:10:55 +02:00
Name = sc.ServiceName?.Trim(),
Display = sc.DisplayName?.Trim(),
Status = status,
StartMode = mode
};
2023-09-21 18:58:32 +02:00
2023-09-21 22:10:55 +02:00
services.Add(service);
}
2023-09-21 18:58:32 +02:00
2023-09-21 22:10:55 +02:00
// additional infos
using var searcher = new ManagementObjectSearcher
{
Scope = new ManagementScope(@"root\cimv2"),
Query = new ObjectQuery("SELECT processid, name, description, pathname, startname, delayedautostart from win32_service")
};
2023-09-21 18:58:32 +02:00
2023-09-21 22:10:55 +02:00
if (searcher.TryGet(out var collection) is false)
{
searcher.Query = new ObjectQuery("select * from win32_service");
if (searcher.TryGet(out collection) is false) throw new InvalidOperationException("WMI Collection NULL");
}
var services2 = new List<Service>();
using (collection)
{
foreach (ManagementObject @object in collection.Cast<ManagementObject>())
2023-09-21 18:58:32 +02:00
{
2023-09-21 22:10:55 +02:00
var service2 = new Service();
2023-09-21 18:58:32 +02:00
2023-09-21 22:10:55 +02:00
var properties = @object.GetPropertyHashes();
2023-09-21 18:58:32 +02:00
2023-09-21 22:10:55 +02:00
service2.Name = @object.GetValue<string>(properties, "name")?.Trim();
service2.ProcessId = @object.GetValue<uint>(properties, "processid");
service2.Description = @object.GetValue<string>(properties, "description")?.Trim();
service2.PathName = @object.GetValue<string>(properties, "pathname")?.Trim();
service2.Account = @object.GetValue<string>(properties, "startname")?.Trim();
service2.Delay = @object.GetValue<bool>(properties, "delayedautostart");
2023-09-21 18:58:32 +02:00
2023-09-21 22:10:55 +02:00
services2.Add(service2);
2023-09-21 18:58:32 +02:00
}
2023-09-21 22:10:55 +02:00
}
2023-09-21 18:58:32 +02:00
2023-09-21 22:10:55 +02:00
if (services2.Any() is false) return services;
2023-09-21 18:58:32 +02:00
2023-09-21 22:10:55 +02:00
foreach (var svc in services)
{
var map = services2.Where(p => p.Name == svc.Name).FirstOrDefault();
2023-09-21 18:58:32 +02:00
2023-09-21 22:10:55 +02:00
if (map is null) continue;
2023-09-21 18:58:32 +02:00
2023-09-21 22:10:55 +02:00
svc.ProcessId = map.ProcessId;
svc.Description = map.Description;
svc.PathName = map.PathName;
svc.Account = map.Account;
svc.Delay = map.Delay;
2023-09-21 18:58:32 +02:00
}
2023-09-21 22:10:55 +02:00
return services.OrderBy(x => x.Name).ToList();
2023-09-21 18:58:32 +02:00
}
}