Skip to content
This repository has been archived by the owner on Sep 3, 2024. It is now read-only.

fix: company software check all platforms and non-admin #59

Merged
merged 1 commit into from
Dec 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions EasyGUI/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="clr-namespace:EasyGUI.Controls"
Closing="MainWindow_OnClosing"
mc:Ignorable="d"
KeyDown="MainWindow_OnKeyDown"
Title="EasySave" Height="720" Width="1280" Icon="/Assets/easysave-logo.ico">
Expand Down
7 changes: 7 additions & 0 deletions EasyGUI/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Input;
using EasyGUI.Events;
Expand Down Expand Up @@ -173,4 +174,10 @@ private void SettingsPopup_OnReloadConfig(object? sender, EventArgs e)
{
_jobManager.ReloadConfig();
}

private void MainWindow_OnClosing(object? sender, CancelEventArgs e)
{
// destroy job manager
_jobManager.StopCheck();
}
}
87 changes: 64 additions & 23 deletions EasyLib/Events/ProcessStartEvent.cs
Original file line number Diff line number Diff line change
@@ -1,68 +1,109 @@
using System.Management;
using System.Diagnostics;
using System.Management;
using System.Security.Principal;

namespace EasyLib.Events;

public class ProcessStartEvent
{
public static long NumberOfRunningProcesses;
private readonly JobManager _jobManager;
private readonly ManagementEventWatcher _processStartEvent;
private readonly ManagementEventWatcher _processStopEvent;
private int _numberOfRunningProcesses;
private readonly ManagementEventWatcher? _processStartEvent;
private readonly ManagementEventWatcher? _processStopEvent;
private CancellationTokenSource _cancellationTokenSource;

/// <summary>
/// create the start and stop event for a process and bind the event to the job manager
/// </summary>
/// <param name="processName"></param>
/// <param name="jobManager"></param>
public ProcessStartEvent(string? processName, JobManager jobManager)

Check warning on line 20 in EasyLib/Events/ProcessStartEvent.cs

View workflow job for this annotation

GitHub Actions / Tests

Non-nullable field '_cancellationTokenSource' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.

Check warning on line 20 in EasyLib/Events/ProcessStartEvent.cs

View workflow job for this annotation

GitHub Actions / Tests

Non-nullable field '_cancellationTokenSource' must contain a non-null value when exiting constructor. Consider declaring the field as nullable.
{
// check if system is running Windows
_jobManager = jobManager;
if ((Environment.OSVersion.Platform == PlatformID.Win32NT) &&
IsAdministrator) // only on Windows can run this feature
{
#pragma warning disable CA1416
_processStartEvent =
new ManagementEventWatcher(
new WqlEventQuery($"SELECT * FROM Win32_ProcessStartTrace WHERE ProcessName = '{processName}'"));
_processStartEvent.EventArrived += ProcessStarted;
// on stop
_processStopEvent = new ManagementEventWatcher(new WqlEventQuery(
$"SELECT * FROM Win32_ProcessStopTrace WHERE ProcessName = '{processName}'"));
_processStopEvent.EventArrived += ProcessStopped;
_processStartEvent.Start();
_processStopEvent.Start();
#pragma warning restore CA1416
_processStartEvent =
new ManagementEventWatcher(
new WqlEventQuery($"SELECT * FROM Win32_ProcessStartTrace WHERE ProcessName = '{processName}'"));
_processStartEvent.EventArrived += ProcessStarted;
// on stop
_processStopEvent = new ManagementEventWatcher(new WqlEventQuery(
$"SELECT * FROM Win32_ProcessStopTrace WHERE ProcessName = '{processName}'"));
_processStopEvent.EventArrived += ProcessStopped;
_processStartEvent.Start();
_processStopEvent.Start();
#pragma warning disable CA1416
}
else
{
_cancellationTokenSource = new CancellationTokenSource();
var newThread = new Thread(() => _checkProcesses(processName));

Check warning on line 43 in EasyLib/Events/ProcessStartEvent.cs

View workflow job for this annotation

GitHub Actions / Tests

Possible null reference argument for parameter 'processName' in 'void ProcessStartEvent._checkProcesses(string processName)'.

Check warning on line 43 in EasyLib/Events/ProcessStartEvent.cs

View workflow job for this annotation

GitHub Actions / Tests

Possible null reference argument for parameter 'processName' in 'void ProcessStartEvent._checkProcesses(string processName)'.
newThread.Start();
}
}

public static bool IsAdministrator =>
new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator);

private void ProcessStarted(object sender, EventArrivedEventArgs e)
{
if (_numberOfRunningProcesses == 0)
if (NumberOfRunningProcesses == 0)
{
_jobManager.PauseAllJobs();
Interlocked.Increment(ref _numberOfRunningProcesses);
Interlocked.Increment(ref NumberOfRunningProcesses);
}
else
{
Interlocked.Increment(ref _numberOfRunningProcesses);
Interlocked.Increment(ref NumberOfRunningProcesses);
}
}

private void ProcessStopped(object sender, EventArrivedEventArgs e)
{
if (_numberOfRunningProcesses == 1)
if (NumberOfRunningProcesses == 1)
{
_jobManager.ResumeAllJobs();
Interlocked.Decrement(ref _numberOfRunningProcesses);
Interlocked.Decrement(ref NumberOfRunningProcesses);
}
else
{
Interlocked.Decrement(ref _numberOfRunningProcesses);
Interlocked.Decrement(ref NumberOfRunningProcesses);
}
}

public void Stop()
{
#pragma warning disable CA1416
_processStopEvent.Stop();
_processStartEvent.Stop();
if (_processStartEvent != null && _processStopEvent != null)
{
_processStopEvent.Stop();
_processStartEvent.Stop();
}
else
{
_cancellationTokenSource.Cancel();
}
#pragma warning restore CA1416
}

private void _checkProcesses(string processName)
{
while (true)
{
if (Process.GetProcessesByName(processName).Length > Interlocked.Read(ref NumberOfRunningProcesses))
{
ProcessStarted(null, null);

Check warning on line 98 in EasyLib/Events/ProcessStartEvent.cs

View workflow job for this annotation

GitHub Actions / Tests

Cannot convert null literal to non-nullable reference type.

Check warning on line 98 in EasyLib/Events/ProcessStartEvent.cs

View workflow job for this annotation

GitHub Actions / Tests

Cannot convert null literal to non-nullable reference type.
}
else if (Process.GetProcessesByName(processName).Length < Interlocked.Read(ref NumberOfRunningProcesses))
{
ProcessStopped(null, null);

Check warning on line 102 in EasyLib/Events/ProcessStartEvent.cs

View workflow job for this annotation

GitHub Actions / Tests

Cannot convert null literal to non-nullable reference type.

Check warning on line 102 in EasyLib/Events/ProcessStartEvent.cs

View workflow job for this annotation

GitHub Actions / Tests

Cannot convert null literal to non-nullable reference type.
}

Thread.Sleep(100);
if (_cancellationTokenSource.IsCancellationRequested) return;
}
}
}
17 changes: 8 additions & 9 deletions EasyLib/JobManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,11 @@ public void OnJobStateChange(JobState state, Job.Job job)
StateManager.Instance.WriteJobs(_jobs);
}

public void StopCheck()
{
_pauseJobEvent.Stop();
}

[GeneratedRegex(@"^\d+-\d+$", RegexOptions.NonBacktracking)]
private static partial Regex JobIndexRangeRegex();

Expand Down Expand Up @@ -362,15 +367,9 @@ public void ResumeAllJobs()
}
}

public bool ReloadConfig()
public void ReloadConfig()
{
if (Environment.OSVersion.Platform == PlatformID.Win32NT) // only on Windows can run this feature
{
_pauseJobEvent.Stop();
_pauseJobEvent = new ProcessStartEvent(ConfigManager.Instance.CompanySoftwareProcessPath, this);
return true;
}

return false;
_pauseJobEvent.Stop();
_pauseJobEvent = new ProcessStartEvent(ConfigManager.Instance.CompanySoftwareProcessPath, this);
}
}
Loading