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>();
|
||||
registrationService.RegisterInputProvider();
|
||||
registrationService.RegisterProcessWatchers();
|
||||
registrationService.RegisterControllers();
|
||||
|
||||
// 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.InputProviders;
|
||||
using Artemis.UI.Ninject;
|
||||
using Artemis.UI.ProcessWatchers;
|
||||
using Artemis.UI.Shared.Services;
|
||||
using Serilog;
|
||||
|
||||
@ -20,6 +21,7 @@ namespace Artemis.UI.Services
|
||||
private readonly IPluginManagementService _pluginManagementService;
|
||||
private readonly IInputService _inputService;
|
||||
private readonly IWebServerService _webServerService;
|
||||
private readonly IProcessMonitorService _processMonitorService;
|
||||
private bool _registeredBuiltInDataModelDisplays;
|
||||
private bool _registeredBuiltInDataModelInputs;
|
||||
private bool _registeredBuiltInPropertyEditors;
|
||||
@ -29,7 +31,8 @@ namespace Artemis.UI.Services
|
||||
IProfileEditorService profileEditorService,
|
||||
IPluginManagementService pluginManagementService,
|
||||
IInputService inputService,
|
||||
IWebServerService webServerService)
|
||||
IWebServerService webServerService,
|
||||
IProcessMonitorService processMonitorService)
|
||||
{
|
||||
_logger = logger;
|
||||
_dataModelUIService = dataModelUIService;
|
||||
@ -37,6 +40,7 @@ namespace Artemis.UI.Services
|
||||
_pluginManagementService = pluginManagementService;
|
||||
_inputService = inputService;
|
||||
_webServerService = webServerService;
|
||||
_processMonitorService = processMonitorService;
|
||||
|
||||
LoadPluginModules();
|
||||
pluginManagementService.PluginEnabling += PluginServiceOnPluginEnabling;
|
||||
@ -92,6 +96,11 @@ namespace Artemis.UI.Services
|
||||
_inputService.AddInputProvider(new NativeWindowInputProvider(_logger, _inputService));
|
||||
}
|
||||
|
||||
public void RegisterProcessWatchers()
|
||||
{
|
||||
_processMonitorService.AddProcessWatcher(new PollingProcessWatcher(_logger));
|
||||
}
|
||||
|
||||
public void RegisterControllers()
|
||||
{
|
||||
_webServerService.AddController<RemoteController>();
|
||||
@ -115,6 +124,7 @@ namespace Artemis.UI.Services
|
||||
void RegisterBuiltInDataModelInputs();
|
||||
void RegisterBuiltInPropertyEditors();
|
||||
void RegisterInputProvider();
|
||||
void RegisterProcessWatchers();
|
||||
void RegisterControllers();
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user