mirror of
https://github.com/Artemis-RGB/Artemis
synced 2025-12-13 05:48:35 +00:00
Process Monitor - initial POC implementation
This is probably overengineered. The same could be done cross platform only using Processes.GetProcesses. I did it this way because initially i wanted to use Wmi events for process start and stop. This requires admin though, so i decided to not use it.
This commit is contained in:
parent
fa26e6b7da
commit
c9ee37ece8
@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Artemis.Core.Services
|
||||||
|
{
|
||||||
|
public class ProcessEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public string ProcessName { get; }
|
||||||
|
|
||||||
|
public ProcessEventArgs(string name)
|
||||||
|
{
|
||||||
|
ProcessName = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Artemis.Core.Services
|
||||||
|
{
|
||||||
|
public interface IProcessMonitorService : IArtemisService
|
||||||
|
{
|
||||||
|
void AddProcessWatcher(ProcessWatcher provider);
|
||||||
|
void RemoveProcessWatcher(ProcessWatcher provider);
|
||||||
|
|
||||||
|
IEnumerable<string> GetRunningProcesses();
|
||||||
|
|
||||||
|
event EventHandler<ProcessEventArgs> ProcessStarted;
|
||||||
|
|
||||||
|
event EventHandler<ProcessEventArgs> ProcessStopped;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,46 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Artemis.Core.Services
|
||||||
|
{
|
||||||
|
public class ProcessMonitorService : IProcessMonitorService
|
||||||
|
{
|
||||||
|
private readonly List<ProcessWatcher> _watchers = new List<ProcessWatcher>();
|
||||||
|
public event EventHandler<ProcessEventArgs> ProcessStarted;
|
||||||
|
public event EventHandler<ProcessEventArgs> ProcessStopped;
|
||||||
|
|
||||||
|
public void AddProcessWatcher(ProcessWatcher watcher)
|
||||||
|
{
|
||||||
|
watcher.ProcessStarted += ProviderOnProcessStarted;
|
||||||
|
watcher.ProcessStopped += ProviderOnProcessStopped;
|
||||||
|
_watchers.Add(watcher);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveProcessWatcher(ProcessWatcher watcher)
|
||||||
|
{
|
||||||
|
if (!_watchers.Contains(watcher))
|
||||||
|
return;
|
||||||
|
|
||||||
|
_watchers.Remove(watcher);
|
||||||
|
watcher.ProcessStarted -= ProviderOnProcessStarted;
|
||||||
|
watcher.ProcessStopped -= ProviderOnProcessStopped;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<string> GetRunningProcesses()
|
||||||
|
{
|
||||||
|
return _watchers.SelectMany(w => w.GetRunningProcesses());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ProviderOnProcessStopped(object? sender, ProcessEventArgs e)
|
||||||
|
{
|
||||||
|
ProcessStopped?.Invoke(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ProviderOnProcessStarted(object? sender, ProcessEventArgs e)
|
||||||
|
{
|
||||||
|
ProcessStarted?.Invoke(this, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
26
src/Artemis.Core/Services/ProcessMonitor/ProcessWatcher.cs
Normal file
26
src/Artemis.Core/Services/ProcessMonitor/ProcessWatcher.cs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Artemis.Core.Services
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Class that provides info on running processes, including events on event start and stop
|
||||||
|
/// </summary>
|
||||||
|
public abstract class ProcessWatcher
|
||||||
|
{
|
||||||
|
public event EventHandler<ProcessEventArgs> ProcessStarted;
|
||||||
|
public event EventHandler<ProcessEventArgs> ProcessStopped;
|
||||||
|
|
||||||
|
public abstract IEnumerable<string> GetRunningProcesses();
|
||||||
|
|
||||||
|
public virtual void OnProcessStarted(string processName)
|
||||||
|
{
|
||||||
|
ProcessStarted?.Invoke(this, new ProcessEventArgs(processName));
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void OnProcessStopped(string processName)
|
||||||
|
{
|
||||||
|
ProcessStopped?.Invoke(this, new ProcessEventArgs(processName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -89,6 +89,7 @@ namespace Artemis.UI
|
|||||||
|
|
||||||
IRegistrationService registrationService = Kernel.Get<IRegistrationService>();
|
IRegistrationService registrationService = Kernel.Get<IRegistrationService>();
|
||||||
registrationService.RegisterInputProvider();
|
registrationService.RegisterInputProvider();
|
||||||
|
registrationService.RegisterProcessWatchers();
|
||||||
registrationService.RegisterControllers();
|
registrationService.RegisterControllers();
|
||||||
|
|
||||||
// Initialize background services
|
// Initialize background services
|
||||||
|
|||||||
52
src/Artemis.UI/ProcessWatchers/PollingProcessWatcher.cs
Normal file
52
src/Artemis.UI/ProcessWatchers/PollingProcessWatcher.cs
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
using Artemis.Core.Services;
|
||||||
|
using Serilog;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Management;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Timers;
|
||||||
|
|
||||||
|
namespace Artemis.UI.ProcessWatchers
|
||||||
|
{
|
||||||
|
public class PollingProcessWatcher : ProcessWatcher
|
||||||
|
{
|
||||||
|
private readonly ILogger _logger;
|
||||||
|
private readonly Timer _processScanTimer;
|
||||||
|
private IEnumerable<string> _lastScannedProcesses;
|
||||||
|
|
||||||
|
public PollingProcessWatcher(ILogger logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
_lastScannedProcesses = Process.GetProcesses().Select(p => p.ProcessName).Distinct().ToArray();
|
||||||
|
_processScanTimer = new Timer(100);
|
||||||
|
_processScanTimer.Elapsed += OnTimerElapsed;
|
||||||
|
_processScanTimer.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnTimerElapsed(object sender, ElapsedEventArgs e)
|
||||||
|
{
|
||||||
|
var newProcesses = Process.GetProcesses().Select(p => p.ProcessName).Distinct();
|
||||||
|
foreach (var startedProcess in newProcesses.Except(_lastScannedProcesses))
|
||||||
|
{
|
||||||
|
OnProcessStarted(startedProcess);
|
||||||
|
_logger.Information($"Started Process!: {startedProcess}");
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var stoppedProcess in _lastScannedProcesses.Except(newProcesses))
|
||||||
|
{
|
||||||
|
OnProcessStopped(stoppedProcess);
|
||||||
|
_logger.Information($"Stopped Process!: {stoppedProcess}");
|
||||||
|
}
|
||||||
|
|
||||||
|
_lastScannedProcesses = newProcesses.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IEnumerable<string> GetRunningProcesses()
|
||||||
|
{
|
||||||
|
return _lastScannedProcesses;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -7,6 +7,7 @@ using Artemis.UI.DefaultTypes.DataModel.Input;
|
|||||||
using Artemis.UI.DefaultTypes.PropertyInput;
|
using Artemis.UI.DefaultTypes.PropertyInput;
|
||||||
using Artemis.UI.InputProviders;
|
using Artemis.UI.InputProviders;
|
||||||
using Artemis.UI.Ninject;
|
using Artemis.UI.Ninject;
|
||||||
|
using Artemis.UI.ProcessWatchers;
|
||||||
using Artemis.UI.Shared.Services;
|
using Artemis.UI.Shared.Services;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
|
||||||
@ -20,6 +21,7 @@ namespace Artemis.UI.Services
|
|||||||
private readonly IPluginManagementService _pluginManagementService;
|
private readonly IPluginManagementService _pluginManagementService;
|
||||||
private readonly IInputService _inputService;
|
private readonly IInputService _inputService;
|
||||||
private readonly IWebServerService _webServerService;
|
private readonly IWebServerService _webServerService;
|
||||||
|
private readonly IProcessMonitorService _processMonitorService;
|
||||||
private bool _registeredBuiltInDataModelDisplays;
|
private bool _registeredBuiltInDataModelDisplays;
|
||||||
private bool _registeredBuiltInDataModelInputs;
|
private bool _registeredBuiltInDataModelInputs;
|
||||||
private bool _registeredBuiltInPropertyEditors;
|
private bool _registeredBuiltInPropertyEditors;
|
||||||
@ -29,7 +31,8 @@ namespace Artemis.UI.Services
|
|||||||
IProfileEditorService profileEditorService,
|
IProfileEditorService profileEditorService,
|
||||||
IPluginManagementService pluginManagementService,
|
IPluginManagementService pluginManagementService,
|
||||||
IInputService inputService,
|
IInputService inputService,
|
||||||
IWebServerService webServerService)
|
IWebServerService webServerService,
|
||||||
|
IProcessMonitorService processMonitorService)
|
||||||
{
|
{
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_dataModelUIService = dataModelUIService;
|
_dataModelUIService = dataModelUIService;
|
||||||
@ -37,6 +40,7 @@ namespace Artemis.UI.Services
|
|||||||
_pluginManagementService = pluginManagementService;
|
_pluginManagementService = pluginManagementService;
|
||||||
_inputService = inputService;
|
_inputService = inputService;
|
||||||
_webServerService = webServerService;
|
_webServerService = webServerService;
|
||||||
|
_processMonitorService = processMonitorService;
|
||||||
|
|
||||||
LoadPluginModules();
|
LoadPluginModules();
|
||||||
pluginManagementService.PluginEnabling += PluginServiceOnPluginEnabling;
|
pluginManagementService.PluginEnabling += PluginServiceOnPluginEnabling;
|
||||||
@ -92,6 +96,11 @@ namespace Artemis.UI.Services
|
|||||||
_inputService.AddInputProvider(new NativeWindowInputProvider(_logger, _inputService));
|
_inputService.AddInputProvider(new NativeWindowInputProvider(_logger, _inputService));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void RegisterProcessWatchers()
|
||||||
|
{
|
||||||
|
_processMonitorService.AddProcessWatcher(new PollingProcessWatcher(_logger));
|
||||||
|
}
|
||||||
|
|
||||||
public void RegisterControllers()
|
public void RegisterControllers()
|
||||||
{
|
{
|
||||||
_webServerService.AddController<RemoteController>();
|
_webServerService.AddController<RemoteController>();
|
||||||
@ -115,6 +124,7 @@ namespace Artemis.UI.Services
|
|||||||
void RegisterBuiltInDataModelInputs();
|
void RegisterBuiltInDataModelInputs();
|
||||||
void RegisterBuiltInPropertyEditors();
|
void RegisterBuiltInPropertyEditors();
|
||||||
void RegisterInputProvider();
|
void RegisterInputProvider();
|
||||||
|
void RegisterProcessWatchers();
|
||||||
void RegisterControllers();
|
void RegisterControllers();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user