insight/src/Agent/Insight.Agent/Network/Handlers/ServiceHandler.cs
2023-11-17 17:12:41 +01:00

122 lines
No EOL
4.6 KiB
C#

using Insight.Domain.Interfaces;
using Insight.Domain.Network;
using Insight.Domain.Network.Agent.Messages;
using System.Management;
using System.Runtime.Versioning;
using System.ServiceProcess;
namespace Insight.Agent.Network.Handlers;
[SupportedOSPlatform("windows")]
public class ServiceHandler : IMessageHandler<AgentSession>
{
public async ValueTask HandleAsync<TMessage>(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IMessage
{
switch (message)
{
case InventoryRequest:
{
var result = new Collection<Service>();
result.AddRange(GetServices());
await sender.SendAsync(result, cancellationToken);
break;
}
}
}
private static List<Service> GetServices()
{
var services = new List<Service>();
var serviceControllers = ServiceController.GetServices()?.OrderBy(s => s.DisplayName)?.ToList();
if (serviceControllers is null || serviceControllers.Any() is false) throw new InvalidOperationException("SERVICE Collection NULL");
foreach (var sc in serviceControllers)
{
var status = sc.Status switch
{
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
};
var mode = sc.StartType switch
{
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,
};
var service = new Service
{
Name = sc.ServiceName?.Trim(),
Display = sc.DisplayName?.Trim(),
Status = status,
StartMode = mode
};
services.Add(service);
}
// 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")
};
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>())
{
var service2 = new Service();
var properties = @object.GetPropertyHashes();
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");
services2.Add(service2);
}
}
if (services2.Any() is false) return services;
foreach (var svc in services)
{
var map = services2.Where(p => p.Name == svc.Name).FirstOrDefault();
if (map is null) continue;
svc.ProcessId = map.ProcessId;
svc.Description = map.Description;
svc.PathName = map.PathName;
svc.Account = map.Account;
svc.Delay = map.Delay;
}
return services.OrderBy(x => x.Name).ToList();
}
}