Skip to content
Snippets Groups Projects
Commit caf448b5 authored by Philipp Müller's avatar Philipp Müller
Browse files

Merge branch 'ProcessMonitoringFix' into 'develop'

process monitoring fixes and calculate distraction stage

See merge request borst/procrastinator!6
parents 74ed0ae0 13e802f6
No related branches found
No related tags found
1 merge request!6process monitoring fixes and calculate distraction stage
Showing
with 134 additions and 52 deletions
No preview for this file type
No preview for this file type
No preview for this file type
......@@ -17,7 +17,7 @@ namespace InnoLabProjektDektopApp
/// </summary>
public partial class Overview : Window
{
private ProcessMonitor processMonitor = new ProcessMonitor();
private ProcessMonitor processMonitor;
public Overview()
{
InitializeComponent();
......@@ -25,6 +25,7 @@ namespace InnoLabProjektDektopApp
}
private void Option1_Click(object sender, RoutedEventArgs e)
{
this.processMonitor = new ProcessMonitor();
processMonitor.StartMonitoring();
//this.Content = new AnotherWindow().Content;
}
......
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Management;
using Newtonsoft.Json;
using System.Diagnostics;
using System.Windows;
using Newtonsoft.Json;
namespace InnoLabProjektDektopApp.Services
{
public class ProcessInfo
public class ProcessInfo(string processName, DateTime startTime, DateTime endTime)
{
public string ProcessName { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public ProcessInfo(string processName, DateTime startTime, DateTime endTime)
{
ProcessName = processName;
StartTime = startTime;
EndTime = endTime;
}
public string ProcessName { get; set; } = processName;
public DateTime StartTime { get; set; } = startTime;
public DateTime EndTime { get; set; } = endTime;
}
class ProcessMonitor
{
private readonly Dictionary<string, DateTime> processStartTimes = [];
private static List<string> blockedProcesses = [];
private readonly Dictionary<string, DateTime> processStartTimes = new Dictionary<string, DateTime>();
private static List<string> blockedProcesses = new List<string>();
private bool isMonitoring = false;
private readonly List<ProcessInfo> processInfoList = new();
private readonly List<ProcessInfo> processInfoList = new List<ProcessInfo>();
private DateTime startTime;
public ProcessMonitor()
{
blockedProcesses = LoadBlockedProcesses();
}
public async void StartMonitoring()
{
startTime = DateTime.Now;
Debug.WriteLine("Started Process Monitoring");
var query = new WqlEventQuery("__InstanceCreationEvent", new TimeSpan(0, 0, 1),
"TargetInstance isa \"Win32_Process\"");
......@@ -49,8 +41,10 @@ namespace InnoLabProjektDektopApp.Services
{
while (isMonitoring)
{
// this wait is here to prevent another event from being triggered before the previous one is handled
var e = watcher.WaitForNextEvent();
Task.Run(() => HandleNewProcess(e));
Task.Delay(100).Wait();
}
});
}
......@@ -58,18 +52,25 @@ namespace InnoLabProjektDektopApp.Services
public void StopMonitoring()
{
Debug.WriteLine("Stopping Process Monitoring");
CalculateCurrentDistractionStage(DateTime.Now);
isMonitoring = false;
}
// make sure, that all processes have been tracked (it may take up to 100ms)
Task.Delay(200).Wait();
public void CalculateCurrentDistractionStage(DateTime endTime)
{
TimeSpan totalDistractionTime = CalculateTotalDistractionTime();
Debug.WriteLine("Total distraction time: {0}", totalDistractionTime);
double totalMinutes = (endTime - startTime).TotalMinutes;
double distractedMinutes = totalDistractionTime.TotalMinutes;
double distractionFraction = (distractedMinutes / totalMinutes);
int stage = (int)Math.Ceiling(distractionFraction * 7);
Debug.WriteLine($"Distraction stage: {stage}");
}
private void HandleNewProcess(ManagementBaseObject e)
{
var processName = Path.GetFileNameWithoutExtension((string)((ManagementBaseObject)e["TargetInstance"])["Name"]);
if (processStartTimes.TryGetValue(processName, out _))
{
return;
......@@ -143,7 +144,7 @@ namespace InnoLabProjektDektopApp.Services
{
Debug.WriteLine($"Start monitoring the {processName} process");
Process? process = GetRunningProcessList().TryGetValue(processName, out List<Process>? processes) ? processes[0] : null;
Process? process = GetRunningProcessList().TryGetValue(processName, out List<Process>? processes) ? processes[0] : null;
if (process == null)
{
......@@ -154,8 +155,13 @@ namespace InnoLabProjektDektopApp.Services
// Token to handle task cancellation
using var cts = new CancellationTokenSource();
var token = cts.Token;
// Task to wait for the process to exit
var waitForExitTask = Task.Run(() => process.WaitForExit(), token);
var waitForExitTask = Task.Run(() =>
{
process.WaitForExit();
SaveTrackedData(processName, startTime);
}, token);
// Task to monitor the isMonitoring flag
var monitorTask = Task.Run(async () =>
......@@ -164,19 +170,22 @@ namespace InnoLabProjektDektopApp.Services
{
await Task.Delay(100); // Check every 100ms
}
cts.Cancel(); // Cancel the waitForExitTask if isMonitoring becomes false
});
}, token);
try
{
// Await the completion of either the waitForExitTask or the monitorTask
await Task.WhenAny(waitForExitTask, monitorTask);
cts.Cancel();
}
catch (OperationCanceledException)
{
Debug.WriteLine("Process monitoring was canceled.");
}
}
private void SaveTrackedData(String processName, DateTime startTime)
{
processStartTimes.Remove(processName);
var endTime = DateTime.Now;
processInfoList.Add(new ProcessInfo(processName, startTime, endTime));
......@@ -187,7 +196,19 @@ namespace InnoLabProjektDektopApp.Services
public TimeSpan CalculateTotalDistractionTime()
{
var intervals = processInfoList
var tempProcessInfoList = new List<ProcessInfo>();
// Add the earliest start time entry from processStartTimes to tempProcessInfoList
if (processStartTimes.Count > 0)
{
var earliestProcess = processStartTimes.OrderBy(p => p.Value).First();
tempProcessInfoList.Add(new ProcessInfo(earliestProcess.Key, earliestProcess.Value, DateTime.Now));
}
// Add all entries from processInfoList to tempProcessInfoList
tempProcessInfoList.AddRange(processInfoList);
var intervals = tempProcessInfoList
.OrderBy(p => p.StartTime)
.Select(p => (p.StartTime, p.EndTime))
.ToList();
......@@ -202,7 +223,7 @@ namespace InnoLabProjektDektopApp.Services
var last = mergedIntervals.Last();
if (interval.StartTime <= last.End)
{
mergedIntervals[mergedIntervals.Count - 1] = (last.Start, new DateTime(Math.Max(last.End.Ticks, interval.EndTime.Ticks)));
mergedIntervals[^1] = (last.Start, new DateTime(Math.Max(last.End.Ticks, interval.EndTime.Ticks)));
}
else
{
......
No preview for this file type
No preview for this file type
No preview for this file type
#pragma checksum "..\..\..\App.xaml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "0A1B60D7CD93D3C1273996782FA59B3F1310A4BA"
//------------------------------------------------------------------------------
// <auto-generated>
// Dieser Code wurde von einem Tool generiert.
// Laufzeitversion:4.0.30319.42000
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
// der Code erneut generiert wird.
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
......

//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace XamlGeneratedNamespace {
/// <summary>
/// GeneratedInternalTypeHelper
/// </summary>
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "9.0.0.0")]
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
public sealed class GeneratedInternalTypeHelper : System.Windows.Markup.InternalTypeHelper {
/// <summary>
/// CreateInstance
/// </summary>
protected override object CreateInstance(System.Type type, System.Globalization.CultureInfo culture) {
return System.Activator.CreateInstance(type, ((System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic)
| (System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.CreateInstance)), null, null, culture);
}
/// <summary>
/// GetPropertyValue
/// </summary>
protected override object GetPropertyValue(System.Reflection.PropertyInfo propertyInfo, object target, System.Globalization.CultureInfo culture) {
return propertyInfo.GetValue(target, System.Reflection.BindingFlags.Default, null, null, culture);
}
/// <summary>
/// SetPropertyValue
/// </summary>
protected override void SetPropertyValue(System.Reflection.PropertyInfo propertyInfo, object target, object value, System.Globalization.CultureInfo culture) {
propertyInfo.SetValue(target, value, System.Reflection.BindingFlags.Default, null, null, culture);
}
/// <summary>
/// CreateDelegate
/// </summary>
protected override System.Delegate CreateDelegate(System.Type delegateType, object target, string handler) {
return ((System.Delegate)(target.GetType().InvokeMember("_CreateDelegate", (System.Reflection.BindingFlags.InvokeMethod
| (System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)), null, target, new object[] {
delegateType,
handler}, null)));
}
/// <summary>
/// AddEventHandler
/// </summary>
protected override void AddEventHandler(System.Reflection.EventInfo eventInfo, object target, System.Delegate handler) {
eventInfo.AddEventHandler(target, handler);
}
}
}
//------------------------------------------------------------------------------
// <auto-generated>
// Dieser Code wurde von einem Tool generiert.
// Laufzeitversion:4.0.30319.42000
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
// der Code erneut generiert wird.
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
......
//------------------------------------------------------------------------------
// <auto-generated>
// Dieser Code wurde von einem Tool generiert.
// Laufzeitversion:4.0.30319.42000
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
// der Code erneut generiert wird.
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
......@@ -14,12 +14,12 @@ using System.Reflection;
[assembly: System.Reflection.AssemblyCompanyAttribute("InnoLabProjektDektopApp")]
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+f5a847cc0e68f4d96b3f87df63b03625068e413d")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+1279a6a20f29b94169b01dda2bba1b6ba3a99b7f")]
[assembly: System.Reflection.AssemblyProductAttribute("InnoLabProjektDektopApp")]
[assembly: System.Reflection.AssemblyTitleAttribute("InnoLabProjektDektopApp")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
[assembly: System.Runtime.Versioning.TargetPlatformAttribute("Windows7.0")]
[assembly: System.Runtime.Versioning.SupportedOSPlatformAttribute("Windows7.0")]
// Von der MSBuild WriteCodeFragment-Klasse generiert.
// Generated by the MSBuild WriteCodeFragment class.
2bc99a707fcdc1d95b7db6e6fb5b27c7d14562229930b28b04423b7b1b55f4c4
d27c4a470f56efd22e39a9a7c9d052460bcaa0b7a20d18ec493487def2860ef4
......@@ -8,7 +8,7 @@ build_property.PlatformNeutralAssembly =
build_property.EnforceExtendedAnalyzerRules =
build_property._SupportedPlatformList = Linux,macOS,Windows
build_property.RootNamespace = InnoLabProjektDektopApp
build_property.ProjectDir = F:\Dokumente\Schule\Studium\InoLab\procrastinator\InnoLabProjektDektopApp\InnoLabProjektDektopApp\
build_property.ProjectDir = C:\Users\Phili\Source\Repos\procrastinator\InnoLabProjektDektopApp\InnoLabProjektDektopApp\
build_property.EnableComHosting =
build_property.EnableGeneratedComInterfaceComImportInterop =
build_property.CsWinRTUseWindowsUIXamlProjections = false
......
8622e40855c6c5138c36971444b62029feb64296201f1b9efcc5b2f0b76d1f95
9af08545ab1b8741cee3e7cdb921df1eef56c5b94fbccc10f8b4a6addb260a1b
......@@ -12,8 +12,8 @@
}
],
"additionalProbingPaths": [
"C:\\Users\\Marcel\\.dotnet\\store\\|arch|\\|tfm|",
"C:\\Users\\Marcel\\.nuget\\packages",
"C:\\Users\\Phili\\.dotnet\\store\\|arch|\\|tfm|",
"C:\\Users\\Phili\\.nuget\\packages",
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages"
],
"configProperties": {
......
No preview for this file type
8362ec0b167bf0f7023f32c3a10afc771ca2dcdf54428830009afec105581327
8b30959f60e78cb2491c4b4353099be658cf355f614bfbe934c1b7b007cb1ff6
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment