mirror of
https://github.com/Maassoft/ColorControl.git
synced 2026-10-22 00:22:18 -05:00
fix scaling issue after .NET 8 update
This commit is contained in:
1 parent
f08dcb7661
commit
ab2ca92827
21 files changed
+331
-345
No files matched your search
@@ -18,8 +18,8 @@
|
||||
<PublisherName>Maassoft</PublisherName>
|
||||
<Company>Maassoft</Company>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>9.8.2.0</ApplicationVersion>
|
||||
<Version>9.8.2.0</Version>
|
||||
<ApplicationVersion>9.8.2.1</ApplicationVersion>
|
||||
<Version>9.8.2.1</Version>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<PublishWizardCompleted>true</PublishWizardCompleted>
|
||||
<BootstrapperEnabled>false</BootstrapperEnabled>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
using ColorControl.Forms;
|
||||
using ColorControl.Services.AMD;
|
||||
using ColorControl.Services.Common;
|
||||
using ColorControl.Services.EventDispatcher;
|
||||
using ColorControl.Services.GameLauncher;
|
||||
using ColorControl.Services.LG;
|
||||
using ColorControl.Services.NVIDIA;
|
||||
using ColorControl.Services.Samsung;
|
||||
using ColorControl.Shared.Common;
|
||||
using ColorControl.Shared.Contracts;
|
||||
using ColorControl.Shared.EventDispatcher;
|
||||
using ColorControl.Shared.Forms;
|
||||
using ColorControl.Shared.Native;
|
||||
using ColorControl.Shared.Services;
|
||||
|
||||
+13
-10
@@ -1,12 +1,12 @@
|
||||
using ColorControl.Forms;
|
||||
using ColorControl.Services.Common;
|
||||
using ColorControl.Services.EventDispatcher;
|
||||
using ColorControl.Services.GameLauncher;
|
||||
using ColorControl.Services.LG;
|
||||
using ColorControl.Services.NVIDIA;
|
||||
using ColorControl.Services.Samsung;
|
||||
using ColorControl.Shared.Common;
|
||||
using ColorControl.Shared.Contracts;
|
||||
using ColorControl.Shared.EventDispatcher;
|
||||
using ColorControl.Shared.Native;
|
||||
using ColorControl.Shared.Services;
|
||||
using ColorControl.Svc;
|
||||
@@ -73,11 +73,6 @@ namespace ColorControl
|
||||
return;
|
||||
}
|
||||
|
||||
var host = CreateHostBuilder().Build();
|
||||
ServiceProvider = host.Services;
|
||||
|
||||
var mutexId = $"Global\\{typeof(MainForm).GUID}";
|
||||
|
||||
var currentDomain = AppDomain.CurrentDomain;
|
||||
// Handler for unhandled exceptions.
|
||||
currentDomain.UnhandledException += GlobalUnhandledExceptionHandler;
|
||||
@@ -86,16 +81,24 @@ namespace ColorControl
|
||||
|
||||
LoadConfig();
|
||||
|
||||
if (Config.UseGdiScaling)
|
||||
{
|
||||
var result = Application.SetHighDpiMode(HighDpiMode.DpiUnawareGdiScaled);
|
||||
|
||||
Logger.Debug($"Result of setting SetHighDpiMode: {result}");
|
||||
}
|
||||
|
||||
var host = CreateHostBuilder().Build();
|
||||
ServiceProvider = host.Services;
|
||||
|
||||
var mutexId = $"Global\\{typeof(MainForm).GUID}";
|
||||
|
||||
var appContextProvider = ServiceProvider.GetRequiredService<AppContextProvider>();
|
||||
var startUpParams = StartUpParams.Parse(args);
|
||||
|
||||
AppContext = new GlobalContext(Config, startUpParams, DataDir, _loggingRule, mutexId);
|
||||
appContextProvider.SetAppContext(AppContext);
|
||||
|
||||
if (Config.UseGdiScaling)
|
||||
{
|
||||
Application.SetHighDpiMode(HighDpiMode.DpiUnawareGdiScaled);
|
||||
}
|
||||
|
||||
var existingProcess = Utils.GetProcessByName("ColorControl");
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using ColorControl.Services.EventDispatcher;
|
||||
using ColorControl.Shared.Common;
|
||||
using ColorControl.Shared.Common;
|
||||
using ColorControl.Shared.Contracts;
|
||||
using ColorControl.Shared.EventDispatcher;
|
||||
using NStandard;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using ColorControl.Services.EventDispatcher;
|
||||
using ColorControl.Shared.EventDispatcher;
|
||||
using ColorControl.Shared.Native;
|
||||
using ColorControl.Shared.Services;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ColorControl.Services.EventDispatcher
|
||||
{
|
||||
public static class EventExtensions
|
||||
{
|
||||
public delegate Task AsyncEventHandler<TEventArgs>(object sender, TEventArgs e, CancellationToken token);
|
||||
|
||||
public static Task InvokeAsync<TArgs>(this AsyncEventHandler<TArgs> func, object sender, TArgs e)
|
||||
{
|
||||
return func == null ? Task.CompletedTask
|
||||
: Task.WhenAll(func.GetInvocationList().Cast<AsyncEventHandler<TArgs>>().Select(f => f(sender, e, CancellationToken.None)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
using Microsoft.Win32;
|
||||
using NWin32;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ColorControl.Services.EventDispatcher
|
||||
{
|
||||
public enum PowerOnOffState
|
||||
{
|
||||
None = 0,
|
||||
StartUp = 1,
|
||||
Resume = 2,
|
||||
ScreenSaver = 3,
|
||||
ShutDown = 4,
|
||||
StandBy = 5,
|
||||
MonitorOff = 6,
|
||||
MonitorOn = 7
|
||||
}
|
||||
|
||||
internal enum WindowsMonitorPowerSetting
|
||||
{
|
||||
Off = 0,
|
||||
On = 1,
|
||||
Dimmed = 2
|
||||
}
|
||||
|
||||
public class PowerStateChangedEventArgs : EventArgs
|
||||
{
|
||||
public PowerOnOffState State { get; private set; }
|
||||
|
||||
public PowerStateChangedEventArgs(PowerOnOffState state)
|
||||
{
|
||||
State = state;
|
||||
}
|
||||
}
|
||||
|
||||
public class PowerEventDispatcher : EventDispatcher<PowerStateChangedEventArgs>
|
||||
{
|
||||
public const string Event_Suspend = "Suspend";
|
||||
public const string Event_Resume = "Resume";
|
||||
public const string Event_Startup = "Startup";
|
||||
public const string Event_Shutdown = "Shutdown";
|
||||
public const string Event_MonitorOff = "MonitorOff";
|
||||
public const string Event_MonitorOn = "MonitorOn";
|
||||
|
||||
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
|
||||
public PowerEventDispatcher()
|
||||
{
|
||||
SystemEvents.PowerModeChanged += OnPowerModeChanged;
|
||||
}
|
||||
|
||||
public void SendEvent(string eventName)
|
||||
{
|
||||
var state = eventName switch
|
||||
{
|
||||
Event_Shutdown => PowerOnOffState.ShutDown,
|
||||
Event_Startup => PowerOnOffState.StartUp,
|
||||
Event_MonitorOff => PowerOnOffState.MonitorOff,
|
||||
Event_MonitorOn => PowerOnOffState.MonitorOn,
|
||||
_ => PowerOnOffState.None
|
||||
};
|
||||
|
||||
if (state == PowerOnOffState.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (state == PowerOnOffState.ShutDown)
|
||||
{
|
||||
DispatchEventWithExecutionState(Event_Shutdown, PowerOnOffState.ShutDown);
|
||||
return;
|
||||
}
|
||||
|
||||
DispatchEvent(eventName, new PowerStateChangedEventArgs(state));
|
||||
}
|
||||
|
||||
public async Task SendEventAsync(string eventName)
|
||||
{
|
||||
var state = eventName switch
|
||||
{
|
||||
Event_Startup => PowerOnOffState.StartUp,
|
||||
_ => PowerOnOffState.None
|
||||
};
|
||||
|
||||
await DispatchEventAsync(eventName, new PowerStateChangedEventArgs(state));
|
||||
}
|
||||
|
||||
private async void OnPowerModeChanged(object sender, PowerModeChangedEventArgs e)
|
||||
{
|
||||
if (e.Mode == PowerModes.Suspend)
|
||||
{
|
||||
DispatchEventWithExecutionState(Event_Suspend, PowerOnOffState.StandBy);
|
||||
}
|
||||
else if (e.Mode == PowerModes.Resume)
|
||||
{
|
||||
await DispatchEventAsync(Event_Resume, new PowerStateChangedEventArgs(PowerOnOffState.Resume));
|
||||
DispatchEvent(Event_Resume, new PowerStateChangedEventArgs(PowerOnOffState.Resume));
|
||||
}
|
||||
}
|
||||
|
||||
private void DispatchEventWithExecutionState(string eventName, PowerOnOffState powerState)
|
||||
{
|
||||
var error = NativeMethods.SetThreadExecutionState(NativeConstants.ES_CONTINUOUS | NativeConstants.ES_SYSTEM_REQUIRED | NativeConstants.ES_AWAYMODE_REQUIRED);
|
||||
try
|
||||
{
|
||||
Logger.Debug($"SetThreadExecutionState: {error}, Thread#: {Environment.CurrentManagedThreadId}");
|
||||
DispatchEvent(eventName, new PowerStateChangedEventArgs(powerState));
|
||||
}
|
||||
finally
|
||||
{
|
||||
var error2 = NativeMethods.SetThreadExecutionState(NativeConstants.ES_CONTINUOUS);
|
||||
Logger.Debug($"SetThreadExecutionState (reset): {error2}, Thread#: {Environment.CurrentManagedThreadId}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,141 +0,0 @@
|
||||
using ColorControl.Shared.Common;
|
||||
using ColorControl.Shared.Forms;
|
||||
using ColorControl.Shared.Services;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Management;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ColorControl.Services.EventDispatcher
|
||||
{
|
||||
public enum ScreenSaverTransitionState
|
||||
{
|
||||
None = 0,
|
||||
Started = 1,
|
||||
Running = 2,
|
||||
Stopped = 3
|
||||
}
|
||||
|
||||
public class ProcessChangedEventArgs : EventArgs
|
||||
{
|
||||
public IList<Process> StartedProcesses { get; set; }
|
||||
public IList<Process> StoppedProcesses { get; set; }
|
||||
public IList<Process> RunningProcesses { get; set; }
|
||||
public bool IsNotificationDisabled { get; set; }
|
||||
public Process ForegroundProcess { get; set; }
|
||||
public bool ForegroundProcessIsFullScreen { get; set; }
|
||||
public string LastFullScreenProcessName = string.Empty;
|
||||
public bool StoppedFullScreen { get; set; }
|
||||
public bool IsScreenSaverActive { get; set; }
|
||||
public ScreenSaverTransitionState ScreenSaverTransitionState { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class ProcessEventDispatcher : EventDispatcher<ProcessChangedEventArgs>
|
||||
{
|
||||
public const string Event_ProcessChanged = "ProcessChanged";
|
||||
public bool IsRunning { get; set; }
|
||||
public ProcessChangedEventArgs MonitorContext { get; private set; }
|
||||
|
||||
protected static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
|
||||
private AppContextProvider _appContextProvider { get; }
|
||||
|
||||
public ProcessEventDispatcher(AppContextProvider appContextProvider)
|
||||
{
|
||||
_appContextProvider = appContextProvider;
|
||||
|
||||
IsRunning = true;
|
||||
|
||||
//Task.Run(async () => await CheckProcesses());
|
||||
|
||||
var _ = CheckProcesses();
|
||||
}
|
||||
|
||||
private async Task CheckProcesses()
|
||||
{
|
||||
await Task.Delay(2000);
|
||||
|
||||
//var startWatch = new ManagementEventWatcher("SELECT * FROM Win32_ProcessStartTrace");
|
||||
//startWatch.EventArrived += startWatch_EventArrived;
|
||||
//startWatch.Start();
|
||||
|
||||
MonitorContext ??= new ProcessChangedEventArgs();
|
||||
|
||||
while (IsRunning)
|
||||
{
|
||||
await Task.Delay(_appContextProvider.GetAppContext().Config.ProcessMonitorPollingInterval);
|
||||
|
||||
if (!HasHandlers(Event_ProcessChanged))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
FillContext(MonitorContext);
|
||||
|
||||
// Ignore if own process has the foreground
|
||||
if (MonitorContext.ForegroundProcess?.Id == Environment.ProcessId)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
await DispatchEventAsync(Event_ProcessChanged, MonitorContext);
|
||||
DispatchEvent(Event_ProcessChanged, MonitorContext);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error("CheckProcesses: " + ex.ToLogString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void FillContext(ProcessChangedEventArgs context)
|
||||
{
|
||||
var processes = Process.GetProcesses();
|
||||
|
||||
context.StartedProcesses = processes.Where(p => context.RunningProcesses?.Any(rp => rp.Id == p.Id) == false).ToList();
|
||||
context.StoppedProcesses = context.RunningProcesses?.Where(p => processes.Any(rp => rp.Id == p.Id) == false).ToList();
|
||||
context.RunningProcesses = processes;
|
||||
|
||||
context.IsNotificationDisabled = FormUtils.IsNotificationDisabled();
|
||||
|
||||
var (processId, isFullScreen) = FormUtils.GetForegroundProcessIdAndIfFullScreen();
|
||||
|
||||
if (processId > 0)
|
||||
{
|
||||
var process = context.RunningProcesses.FirstOrDefault(p => p.Id == processId);
|
||||
|
||||
var screenSaverActive = process?.ProcessName?.Contains(".scr") == true;
|
||||
|
||||
context.IsScreenSaverActive = screenSaverActive;
|
||||
context.ScreenSaverTransitionState = screenSaverActive ?
|
||||
context.ScreenSaverTransitionState == ScreenSaverTransitionState.None ? ScreenSaverTransitionState.Started : ScreenSaverTransitionState.Running :
|
||||
context.ScreenSaverTransitionState == ScreenSaverTransitionState.Running ? ScreenSaverTransitionState.Stopped : ScreenSaverTransitionState.None;
|
||||
context.ForegroundProcess = process;
|
||||
context.ForegroundProcessIsFullScreen = isFullScreen;
|
||||
|
||||
if (isFullScreen)
|
||||
{
|
||||
context.LastFullScreenProcessName = context.ForegroundProcess.ProcessName;
|
||||
//Logger.Debug($"Foreground fullscreen app detected: {context.ForegroundProcess.ProcessName}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
context.StoppedFullScreen = context.ForegroundProcessIsFullScreen;
|
||||
context.ForegroundProcess = null;
|
||||
context.ForegroundProcessIsFullScreen = false;
|
||||
context.LastFullScreenProcessName = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
private void startWatch_EventArrived(object sender, EventArrivedEventArgs e)
|
||||
{
|
||||
//Logger.Debug("Process started: " + e.NewEvent.Properties["ProcessName"].Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace ColorControl.Services.EventDispatcher
|
||||
{
|
||||
public class SessionSwitchDispatcher : EventDispatcher<SessionSwitchEventArgs>
|
||||
{
|
||||
public const string Event_SessionSwitch = "SessionSwitch";
|
||||
|
||||
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
|
||||
public bool UserLocalSession { get; private set; } = true;
|
||||
public SessionSwitchReason LastSessionSwitchReason { get; private set; } = 0;
|
||||
|
||||
public SessionSwitchDispatcher()
|
||||
{
|
||||
SystemEvents.SessionSwitch += SessionSwitchHandler;
|
||||
}
|
||||
|
||||
public void SessionSwitchHandler(object sender, SessionSwitchEventArgs evt)
|
||||
{
|
||||
if (evt.Reason == SessionSwitchReason.ConsoleDisconnect)
|
||||
{
|
||||
Logger.Debug("Detected a disconnect from the console");
|
||||
UserLocalSession = false;
|
||||
|
||||
DispatchEvent(Event_SessionSwitch, evt);
|
||||
}
|
||||
else if (evt.Reason == SessionSwitchReason.ConsoleConnect)
|
||||
{
|
||||
Logger.Debug("Detected a connect to the console");
|
||||
if (!UserLocalSession)
|
||||
{
|
||||
Logger.Debug("Session state switched to local");
|
||||
UserLocalSession = true;
|
||||
DispatchEvent(Event_SessionSwitch, evt);
|
||||
}
|
||||
}
|
||||
LastSessionSwitchReason = evt.Reason;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
using ColorControl.Services.Common;
|
||||
using ColorControl.Services.EventDispatcher;
|
||||
using ColorControl.Shared.Common;
|
||||
using ColorControl.Shared.EventDispatcher;
|
||||
using ColorControl.Shared.Services;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
using ColorControl.Services.AMD;
|
||||
using ColorControl.Services.Common;
|
||||
using ColorControl.Services.EventDispatcher;
|
||||
using ColorControl.Services.NVIDIA;
|
||||
using ColorControl.Shared.Common;
|
||||
using ColorControl.Shared.Contracts;
|
||||
using ColorControl.Shared.EventDispatcher;
|
||||
using ColorControl.Shared.Forms;
|
||||
using ColorControl.Shared.Native;
|
||||
using LgTv;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using ColorControl.Services.Common;
|
||||
using ColorControl.Services.EventDispatcher;
|
||||
using ColorControl.Shared.Common;
|
||||
using ColorControl.Shared.Contracts;
|
||||
using ColorControl.Shared.EventDispatcher;
|
||||
using ColorControl.Shared.Native;
|
||||
using ColorControl.Shared.Services;
|
||||
using LgTv;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using ColorControl.Services.Common;
|
||||
using ColorControl.Services.EventDispatcher;
|
||||
using ColorControl.Shared.Common;
|
||||
using ColorControl.Shared.Contracts;
|
||||
using ColorControl.Shared.Contracts.NVIDIA;
|
||||
using ColorControl.Shared.EventDispatcher;
|
||||
using ColorControl.Shared.Forms;
|
||||
using ColorControl.Shared.Native;
|
||||
using ColorControl.Shared.Services;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
using ColorControl.Services.AMD;
|
||||
using ColorControl.Services.Common;
|
||||
using ColorControl.Services.EventDispatcher;
|
||||
using ColorControl.Services.NVIDIA;
|
||||
using ColorControl.Shared.Common;
|
||||
using ColorControl.Shared.Contracts;
|
||||
using ColorControl.Shared.EventDispatcher;
|
||||
using ColorControl.Shared.Forms;
|
||||
using ColorControl.Shared.Native;
|
||||
using NLog;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using ColorControl.Services.Common;
|
||||
using ColorControl.Services.EventDispatcher;
|
||||
using ColorControl.Shared.Common;
|
||||
using ColorControl.Shared.EventDispatcher;
|
||||
using ColorControl.Shared.Native;
|
||||
using ColorControl.Shared.Services;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using ColorControl.Services.EventDispatcher;
|
||||
using ColorControl.Services.LG;
|
||||
using ColorControl.Services.LG;
|
||||
using ColorControl.Shared.Common;
|
||||
using ColorControl.Shared.Contracts;
|
||||
using ColorControl.Shared.EventDispatcher;
|
||||
using ColorControl.Shared.Services;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
+2
-5
@@ -1,9 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using static ColorControl.Services.EventDispatcher.EventExtensions;
|
||||
using static ColorControl.Shared.EventDispatcher.EventExtensions;
|
||||
|
||||
namespace ColorControl.Services.EventDispatcher;
|
||||
namespace ColorControl.Shared.EventDispatcher;
|
||||
|
||||
public class EventDispatcher<T> where T : EventArgs
|
||||
{
|
||||
@@ -0,0 +1,12 @@
|
||||
namespace ColorControl.Shared.EventDispatcher;
|
||||
|
||||
public static class EventExtensions
|
||||
{
|
||||
public delegate Task AsyncEventHandler<TEventArgs>(object sender, TEventArgs e, CancellationToken token);
|
||||
|
||||
public static Task InvokeAsync<TArgs>(this AsyncEventHandler<TArgs> func, object sender, TArgs e)
|
||||
{
|
||||
return func == null ? Task.CompletedTask
|
||||
: Task.WhenAll(func.GetInvocationList().Cast<AsyncEventHandler<TArgs>>().Select(f => f(sender, e, CancellationToken.None)));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
using Microsoft.Win32;
|
||||
using NWin32;
|
||||
|
||||
namespace ColorControl.Shared.EventDispatcher;
|
||||
|
||||
public enum PowerOnOffState
|
||||
{
|
||||
None = 0,
|
||||
StartUp = 1,
|
||||
Resume = 2,
|
||||
ScreenSaver = 3,
|
||||
ShutDown = 4,
|
||||
StandBy = 5,
|
||||
MonitorOff = 6,
|
||||
MonitorOn = 7
|
||||
}
|
||||
|
||||
public enum WindowsMonitorPowerSetting
|
||||
{
|
||||
Off = 0,
|
||||
On = 1,
|
||||
Dimmed = 2
|
||||
}
|
||||
|
||||
public class PowerStateChangedEventArgs : EventArgs
|
||||
{
|
||||
public PowerOnOffState State { get; private set; }
|
||||
|
||||
public PowerStateChangedEventArgs(PowerOnOffState state)
|
||||
{
|
||||
State = state;
|
||||
}
|
||||
}
|
||||
|
||||
public class PowerEventDispatcher : EventDispatcher<PowerStateChangedEventArgs>
|
||||
{
|
||||
public const string Event_Suspend = "Suspend";
|
||||
public const string Event_Resume = "Resume";
|
||||
public const string Event_Startup = "Startup";
|
||||
public const string Event_Shutdown = "Shutdown";
|
||||
public const string Event_MonitorOff = "MonitorOff";
|
||||
public const string Event_MonitorOn = "MonitorOn";
|
||||
|
||||
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
|
||||
public PowerEventDispatcher()
|
||||
{
|
||||
SystemEvents.PowerModeChanged += OnPowerModeChanged;
|
||||
}
|
||||
|
||||
public void SendEvent(string eventName)
|
||||
{
|
||||
var state = eventName switch
|
||||
{
|
||||
Event_Shutdown => PowerOnOffState.ShutDown,
|
||||
Event_Startup => PowerOnOffState.StartUp,
|
||||
Event_MonitorOff => PowerOnOffState.MonitorOff,
|
||||
Event_MonitorOn => PowerOnOffState.MonitorOn,
|
||||
_ => PowerOnOffState.None
|
||||
};
|
||||
|
||||
if (state == PowerOnOffState.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (state == PowerOnOffState.ShutDown)
|
||||
{
|
||||
DispatchEventWithExecutionState(Event_Shutdown, PowerOnOffState.ShutDown);
|
||||
return;
|
||||
}
|
||||
|
||||
DispatchEvent(eventName, new PowerStateChangedEventArgs(state));
|
||||
}
|
||||
|
||||
public async Task SendEventAsync(string eventName)
|
||||
{
|
||||
var state = eventName switch
|
||||
{
|
||||
Event_Startup => PowerOnOffState.StartUp,
|
||||
_ => PowerOnOffState.None
|
||||
};
|
||||
|
||||
await DispatchEventAsync(eventName, new PowerStateChangedEventArgs(state));
|
||||
}
|
||||
|
||||
private async void OnPowerModeChanged(object sender, PowerModeChangedEventArgs e)
|
||||
{
|
||||
if (e.Mode == PowerModes.Suspend)
|
||||
{
|
||||
DispatchEventWithExecutionState(Event_Suspend, PowerOnOffState.StandBy);
|
||||
}
|
||||
else if (e.Mode == PowerModes.Resume)
|
||||
{
|
||||
await DispatchEventAsync(Event_Resume, new PowerStateChangedEventArgs(PowerOnOffState.Resume));
|
||||
DispatchEvent(Event_Resume, new PowerStateChangedEventArgs(PowerOnOffState.Resume));
|
||||
}
|
||||
}
|
||||
|
||||
private void DispatchEventWithExecutionState(string eventName, PowerOnOffState powerState)
|
||||
{
|
||||
var error = NativeMethods.SetThreadExecutionState(NativeConstants.ES_CONTINUOUS | NativeConstants.ES_SYSTEM_REQUIRED | NativeConstants.ES_AWAYMODE_REQUIRED);
|
||||
try
|
||||
{
|
||||
Logger.Debug($"SetThreadExecutionState: {error}, Thread#: {Environment.CurrentManagedThreadId}");
|
||||
DispatchEvent(eventName, new PowerStateChangedEventArgs(powerState));
|
||||
}
|
||||
finally
|
||||
{
|
||||
var error2 = NativeMethods.SetThreadExecutionState(NativeConstants.ES_CONTINUOUS);
|
||||
Logger.Debug($"SetThreadExecutionState (reset): {error2}, Thread#: {Environment.CurrentManagedThreadId}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
using ColorControl.Shared.Common;
|
||||
using ColorControl.Shared.Forms;
|
||||
using ColorControl.Shared.Services;
|
||||
using System.Diagnostics;
|
||||
using System.Management;
|
||||
|
||||
namespace ColorControl.Shared.EventDispatcher;
|
||||
|
||||
public enum ScreenSaverTransitionState
|
||||
{
|
||||
None = 0,
|
||||
Started = 1,
|
||||
Running = 2,
|
||||
Stopped = 3
|
||||
}
|
||||
|
||||
public class ProcessChangedEventArgs : EventArgs
|
||||
{
|
||||
public IList<Process> StartedProcesses { get; set; }
|
||||
public IList<Process> StoppedProcesses { get; set; }
|
||||
public IList<Process> RunningProcesses { get; set; }
|
||||
public bool IsNotificationDisabled { get; set; }
|
||||
public Process ForegroundProcess { get; set; }
|
||||
public bool ForegroundProcessIsFullScreen { get; set; }
|
||||
public string LastFullScreenProcessName = string.Empty;
|
||||
public bool StoppedFullScreen { get; set; }
|
||||
public bool IsScreenSaverActive { get; set; }
|
||||
public ScreenSaverTransitionState ScreenSaverTransitionState { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class ProcessEventDispatcher : EventDispatcher<ProcessChangedEventArgs>
|
||||
{
|
||||
public const string Event_ProcessChanged = "ProcessChanged";
|
||||
public bool IsRunning { get; set; }
|
||||
public ProcessChangedEventArgs MonitorContext { get; private set; }
|
||||
|
||||
protected static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
|
||||
private AppContextProvider _appContextProvider { get; }
|
||||
|
||||
public ProcessEventDispatcher(AppContextProvider appContextProvider)
|
||||
{
|
||||
_appContextProvider = appContextProvider;
|
||||
|
||||
IsRunning = true;
|
||||
|
||||
//Task.Run(async () => await CheckProcesses());
|
||||
|
||||
var _ = CheckProcesses();
|
||||
}
|
||||
|
||||
private async Task CheckProcesses()
|
||||
{
|
||||
await Task.Delay(2000);
|
||||
|
||||
//var startWatch = new ManagementEventWatcher("SELECT * FROM Win32_ProcessStartTrace");
|
||||
//startWatch.EventArrived += startWatch_EventArrived;
|
||||
//startWatch.Start();
|
||||
|
||||
MonitorContext ??= new ProcessChangedEventArgs();
|
||||
|
||||
while (IsRunning)
|
||||
{
|
||||
await Task.Delay(_appContextProvider.GetAppContext().Config.ProcessMonitorPollingInterval);
|
||||
|
||||
if (!HasHandlers(Event_ProcessChanged))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
FillContext(MonitorContext);
|
||||
|
||||
// Ignore if own process has the foreground
|
||||
if (MonitorContext.ForegroundProcess?.Id == Environment.ProcessId)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
await DispatchEventAsync(Event_ProcessChanged, MonitorContext);
|
||||
DispatchEvent(Event_ProcessChanged, MonitorContext);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error("CheckProcesses: " + ex.ToLogString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void FillContext(ProcessChangedEventArgs context)
|
||||
{
|
||||
var processes = Process.GetProcesses();
|
||||
|
||||
context.StartedProcesses = processes.Where(p => context.RunningProcesses?.Any(rp => rp.Id == p.Id) == false).ToList();
|
||||
context.StoppedProcesses = context.RunningProcesses?.Where(p => processes.Any(rp => rp.Id == p.Id) == false).ToList();
|
||||
context.RunningProcesses = processes;
|
||||
|
||||
context.IsNotificationDisabled = FormUtils.IsNotificationDisabled();
|
||||
|
||||
var (processId, isFullScreen) = FormUtils.GetForegroundProcessIdAndIfFullScreen();
|
||||
|
||||
if (processId > 0)
|
||||
{
|
||||
var process = context.RunningProcesses.FirstOrDefault(p => p.Id == processId);
|
||||
|
||||
var screenSaverActive = process?.ProcessName?.Contains(".scr") == true;
|
||||
|
||||
context.IsScreenSaverActive = screenSaverActive;
|
||||
context.ScreenSaverTransitionState = screenSaverActive ?
|
||||
context.ScreenSaverTransitionState == ScreenSaverTransitionState.None ? ScreenSaverTransitionState.Started : ScreenSaverTransitionState.Running :
|
||||
context.ScreenSaverTransitionState == ScreenSaverTransitionState.Running ? ScreenSaverTransitionState.Stopped : ScreenSaverTransitionState.None;
|
||||
context.ForegroundProcess = process;
|
||||
context.ForegroundProcessIsFullScreen = isFullScreen;
|
||||
|
||||
if (isFullScreen)
|
||||
{
|
||||
context.LastFullScreenProcessName = context.ForegroundProcess.ProcessName;
|
||||
//Logger.Debug($"Foreground fullscreen app detected: {context.ForegroundProcess.ProcessName}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
context.StoppedFullScreen = context.ForegroundProcessIsFullScreen;
|
||||
context.ForegroundProcess = null;
|
||||
context.ForegroundProcessIsFullScreen = false;
|
||||
context.LastFullScreenProcessName = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
private void startWatch_EventArrived(object sender, EventArrivedEventArgs e)
|
||||
{
|
||||
//Logger.Debug("Process started: " + e.NewEvent.Properties["ProcessName"].Value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace ColorControl.Shared.EventDispatcher;
|
||||
|
||||
public class SessionSwitchDispatcher : EventDispatcher<SessionSwitchEventArgs>
|
||||
{
|
||||
public const string Event_SessionSwitch = "SessionSwitch";
|
||||
|
||||
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
|
||||
public bool UserLocalSession { get; private set; } = true;
|
||||
public SessionSwitchReason LastSessionSwitchReason { get; private set; } = 0;
|
||||
|
||||
public SessionSwitchDispatcher()
|
||||
{
|
||||
SystemEvents.SessionSwitch += SessionSwitchHandler;
|
||||
}
|
||||
|
||||
public void SessionSwitchHandler(object sender, SessionSwitchEventArgs evt)
|
||||
{
|
||||
if (evt.Reason == SessionSwitchReason.ConsoleDisconnect)
|
||||
{
|
||||
Logger.Debug("Detected a disconnect from the console");
|
||||
UserLocalSession = false;
|
||||
|
||||
DispatchEvent(Event_SessionSwitch, evt);
|
||||
}
|
||||
else if (evt.Reason == SessionSwitchReason.ConsoleConnect)
|
||||
{
|
||||
Logger.Debug("Detected a connect to the console");
|
||||
if (!UserLocalSession)
|
||||
{
|
||||
Logger.Debug("Session state switched to local");
|
||||
UserLocalSession = true;
|
||||
DispatchEvent(Event_SessionSwitch, evt);
|
||||
}
|
||||
}
|
||||
LastSessionSwitchReason = evt.Reason;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user