winmr-api/Services/ProcessMonitor.cs
2025-07-03 15:22:40 +03:00

100 lines
3.3 KiB
C#

// File: Services/ProcessMonitor.cs
using Microsoft.Extensions.Options;
using System.Runtime.Versioning;
using WebmrAPI.Configuration;
using WebmrAPI.Exceptions;
using WebmrAPI.Models;
using WebmrAPI.Services.Scanners;
using WebmrAPI.Utils;
namespace WebmrAPI.Services
{
[SupportedOSPlatform("windows")]
public class ProcessMonitor : IHostedService, IDisposable
{
private Timer? _timer;
private readonly ILogger<ProcessMonitor> _logger;
private readonly MonitoringSettings _config;
private LazyConcurrentContainer<ProcessInfo> _processes = new();
private ScanProvider _provider;
public ILogger<ProcessMonitor> Logger { get => _logger; }
public MonitoringSettings Config { get => _config; }
public LazyConcurrentContainer<ProcessInfo> Processes { get => _processes; }
public IEnumerable<ProcessBaseInfo>? GetBufferedProcesses()
{
return _processes.Values;
}
public ProcessInfo? GetProcessDetails(int pid, ScanTarget target = ScanTarget.ProcessDetails)
{
if (_processes.Container != null && _processes.Container.TryGetValue(pid, out var info))
{
try
{
_provider.CreateScanTask(info, target).Scan();
_logger.LogInformation($"Scan details of the process {info.Name} (PID: {info.PID}) was completed.");
return info;
}
catch (ProcessMonitorException ex)
{
_logger.LogWarning(ex.Message);
}
catch (Exception ex)
{
_logger.LogError($"Unhandled error during scanning of the process {info.Name} (PID: {info.PID}): {ex.Message}");
}
}
return null;
}
public ProcessMonitor(ILogger<ProcessMonitor> logger, IOptions<AppSettings> settings)
{
_logger = logger;
_config = settings.Value.Monitoring;
_provider = new(this);
}
public Task StartAsync(CancellationToken cancellationToken)
{
_logger.LogInformation($"ProcessMonitor started. Scan interval: {_config.ProcessScanInterval} seconds.");
_timer = new Timer(DoWork, null, TimeSpan.Zero, TimeSpan.FromSeconds(_config.ProcessScanInterval));
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("ProcessMonitor is stopping.");
_timer?.Change(Timeout.Infinite, 0);
return Task.CompletedTask;
}
private void DoWork(object? state)
{
_logger.LogDebug("Initiating process scan...");
try
{
_provider.CreateScanTask().Scan();
_logger.LogInformation($"Process buffer updated, contains {Processes.Container?.Count} processes.");
}
catch (ProcessMonitorException ex)
{
_logger.LogWarning(ex.Message);
}
catch (Exception ex)
{
_logger.LogError($"Unhandled error during process monitoring cycle: {ex.Message}");
}
}
public void Dispose()
{
_timer?.Dispose();
}
}
}