diff --git a/src/Artemis.Core/Services/ProcessMonitor/Events/ProcessEventArgs.cs b/src/Artemis.Core/Services/ProcessMonitor/Events/ProcessEventArgs.cs
new file mode 100644
index 000000000..dca403a13
--- /dev/null
+++ b/src/Artemis.Core/Services/ProcessMonitor/Events/ProcessEventArgs.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Diagnostics;
+
+namespace Artemis.Core.Services
+{
+ ///
+ /// Contains data for the ProcessMonitor process events
+ ///
+ public class ProcessEventArgs : EventArgs
+ {
+ ///
+ /// Gets the process related to the event
+ ///
+ public Process Process { get; }
+
+ internal ProcessEventArgs(Process process)
+ {
+ Process = process;
+ }
+ }
+}
diff --git a/src/Artemis.Core/Services/ProcessMonitor/Interfaces/IProcessMonitorService.cs b/src/Artemis.Core/Services/ProcessMonitor/Interfaces/IProcessMonitorService.cs
new file mode 100644
index 000000000..b26376b37
--- /dev/null
+++ b/src/Artemis.Core/Services/ProcessMonitor/Interfaces/IProcessMonitorService.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Artemis.Core.Services
+{
+ ///
+ /// A service that provides events for started and stopped processes and a list of all running processes.
+ ///
+ public interface IProcessMonitorService : IArtemisService
+ {
+ ///
+ /// Occurs when a process starts.
+ ///
+ event EventHandler ProcessStarted;
+
+ ///
+ /// Occurs when a process stops.
+ ///
+ event EventHandler ProcessStopped;
+
+ ///
+ /// Returns an enumerable with the processes running on the system.
+ ///
+ IEnumerable GetRunningProcesses();
+ }
+}
diff --git a/src/Artemis.Core/Services/ProcessMonitor/ProcessMonitorService.cs b/src/Artemis.Core/Services/ProcessMonitor/ProcessMonitorService.cs
new file mode 100644
index 000000000..86f38e0a1
--- /dev/null
+++ b/src/Artemis.Core/Services/ProcessMonitor/ProcessMonitorService.cs
@@ -0,0 +1,70 @@
+using Serilog;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Timers;
+
+namespace Artemis.Core.Services
+{
+ internal class ProcessMonitorService : IProcessMonitorService
+ {
+ private readonly ILogger _logger;
+ private readonly Timer _processScanTimer;
+ private readonly ProcessComparer _comparer;
+ private Process[] _lastScannedProcesses;
+
+ public ProcessMonitorService(ILogger logger)
+ {
+ _logger = logger;
+ _lastScannedProcesses = Process.GetProcesses();
+ _processScanTimer = new Timer(1000);
+ _processScanTimer.Elapsed += OnTimerElapsed;
+ _processScanTimer.Start();
+ _comparer = new ProcessComparer();
+ }
+
+ public event EventHandler? ProcessStarted;
+
+ public event EventHandler? ProcessStopped;
+
+ public IEnumerable GetRunningProcesses()
+ {
+ return _lastScannedProcesses;
+ }
+
+ private void OnTimerElapsed(object sender, ElapsedEventArgs e)
+ {
+ Process[] newProcesses = Process.GetProcesses();
+ foreach (Process startedProcess in newProcesses.Except(_lastScannedProcesses, _comparer))
+ {
+ ProcessStarted?.Invoke(this, new ProcessEventArgs(startedProcess));
+ _logger.Debug("Started Process: {startedProcess}", startedProcess.ProcessName);
+ }
+
+ foreach (Process stoppedProcess in _lastScannedProcesses.Except(newProcesses, _comparer))
+ {
+ ProcessStopped?.Invoke(this, new ProcessEventArgs(stoppedProcess));
+ _logger.Debug("Stopped Process: {stoppedProcess}", stoppedProcess.ProcessName);
+ }
+
+ _lastScannedProcesses = newProcesses;
+ }
+ }
+
+ internal class ProcessComparer : IEqualityComparer
+ {
+ public bool Equals(Process? x, Process? y)
+ {
+ if (x == null && y == null) return true;
+ if (x == null || y == null) return false;
+ return x.Id == y.Id && x.ProcessName == y.ProcessName && x.SessionId == y.SessionId;
+ }
+
+ public int GetHashCode(Process obj)
+ {
+ if (obj == null) return 0;
+ return obj.Id;
+ }
+ }
+}