using Insight.Agent.Interfaces; using Insight.Agent.Messages; using System.Management; using System.Runtime.Versioning; using System.ServiceProcess; namespace Insight.Agent.Network.Handlers { [SupportedOSPlatform("windows")] public class ServiceHandler : IAgentMessageHandler { public async ValueTask HandleAsync(AgentSession sender, TMessage message, CancellationToken cancellationToken) where TMessage : IAgentMessage { if (message is GetInventory) { var result = new ServiceList(); result.AddRange(GetServices()); await sender.SendAsync(result, cancellationToken); } } private static List GetServices() { var services = new List(); 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(); using (collection) { foreach (ManagementObject @object in collection.Cast()) { var service2 = new Service(); var properties = @object.GetPropertyHashes(); service2.Name = @object.GetValue(properties, "name")?.Trim(); service2.ProcessId = @object.GetValue(properties, "processid"); service2.Description = @object.GetValue(properties, "description")?.Trim(); service2.PathName = @object.GetValue(properties, "pathname")?.Trim(); service2.Account = @object.GetValue(properties, "startname")?.Trim(); service2.Delay = @object.GetValue(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(); } } }