mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-10 13:35:31 +02:00
StyleCop enabled.
This commit is contained in:
@@ -2,13 +2,13 @@
|
|||||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
// See the LICENSE file in the project root for more information.
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
using Microsoft.Win32;
|
|
||||||
using NLog;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.Win32;
|
||||||
|
using NLog;
|
||||||
|
|
||||||
namespace Espresso.Shell.Core
|
namespace Espresso.Shell.Core
|
||||||
{
|
{
|
||||||
@@ -18,7 +18,7 @@ namespace Espresso.Shell.Core
|
|||||||
ES_AWAYMODE_REQUIRED = 0x00000040,
|
ES_AWAYMODE_REQUIRED = 0x00000040,
|
||||||
ES_CONTINUOUS = 0x80000000,
|
ES_CONTINUOUS = 0x80000000,
|
||||||
ES_DISPLAY_REQUIRED = 0x00000002,
|
ES_DISPLAY_REQUIRED = 0x00000002,
|
||||||
ES_SYSTEM_REQUIRED = 0x00000001
|
ES_SYSTEM_REQUIRED = 0x00000001,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -27,16 +27,15 @@ namespace Espresso.Shell.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class APIHelper
|
public class APIHelper
|
||||||
{
|
{
|
||||||
private const string BUILD_REGISTRY_LOCATION = @"SOFTWARE\Microsoft\Windows NT\CurrentVersion";
|
private const string BuildRegistryLocation = @"SOFTWARE\Microsoft\Windows NT\CurrentVersion";
|
||||||
|
|
||||||
private static CancellationTokenSource TokenSource;
|
private static readonly Logger _log;
|
||||||
private static CancellationToken ThreadToken;
|
private static CancellationTokenSource _tokenSource;
|
||||||
|
private static CancellationToken _threadToken;
|
||||||
private static readonly Logger log;
|
|
||||||
|
|
||||||
// More details about the API used: https://docs.microsoft.com/windows/win32/api/winbase/nf-winbase-setthreadexecutionstate
|
// More details about the API used: https://docs.microsoft.com/windows/win32/api/winbase/nf-winbase-setthreadexecutionstate
|
||||||
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||||
static extern EXECUTION_STATE SetThreadExecutionState(EXECUTION_STATE esFlags);
|
private static extern EXECUTION_STATE SetThreadExecutionState(EXECUTION_STATE esFlags);
|
||||||
|
|
||||||
// More details about the API used: https://docs.microsoft.com/windows/win32/api/shellapi/nf-shellapi-extracticonexw
|
// More details about the API used: https://docs.microsoft.com/windows/win32/api/shellapi/nf-shellapi-extracticonexw
|
||||||
[DllImport("Shell32.dll", EntryPoint = "ExtractIconExW", CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
|
[DllImport("Shell32.dll", EntryPoint = "ExtractIconExW", CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
|
||||||
@@ -44,8 +43,8 @@ namespace Espresso.Shell.Core
|
|||||||
|
|
||||||
static APIHelper()
|
static APIHelper()
|
||||||
{
|
{
|
||||||
log = LogManager.GetCurrentClassLogger();
|
_log = LogManager.GetCurrentClassLogger();
|
||||||
TokenSource = new CancellationTokenSource();
|
_tokenSource = new CancellationTokenSource();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -60,23 +59,14 @@ namespace Espresso.Shell.Core
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
var stateResult = SetThreadExecutionState(state);
|
var stateResult = SetThreadExecutionState(state);
|
||||||
bool stateSettingSucceeded = (stateResult != 0);
|
return stateResult != 0;
|
||||||
|
|
||||||
if (stateSettingSucceeded)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Attempts to reset the current machine state to one where Espresso doesn't try to keep it awake.
|
/// Attempts to reset the current machine state to one where Espresso doesn't try to keep it awake.
|
||||||
/// This does not interfere with the state that can be potentially set by other applications.
|
/// This does not interfere with the state that can be potentially set by other applications.
|
||||||
@@ -84,7 +74,7 @@ namespace Espresso.Shell.Core
|
|||||||
/// <returns>Status of the attempt. True is successful, false if not.</returns>
|
/// <returns>Status of the attempt. True is successful, false if not.</returns>
|
||||||
public static bool SetNormalKeepAwake()
|
public static bool SetNormalKeepAwake()
|
||||||
{
|
{
|
||||||
TokenSource.Cancel();
|
_tokenSource.Cancel();
|
||||||
return SetAwakeState(EXECUTION_STATE.ES_CONTINUOUS);
|
return SetAwakeState(EXECUTION_STATE.ES_CONTINUOUS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,18 +92,17 @@ namespace Espresso.Shell.Core
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
return SetAwakeState(EXECUTION_STATE.ES_SYSTEM_REQUIRED | EXECUTION_STATE.ES_CONTINUOUS);
|
return SetAwakeState(EXECUTION_STATE.ES_SYSTEM_REQUIRED | EXECUTION_STATE.ES_CONTINUOUS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SetTimedKeepAwake(long seconds, Action<bool> callback, Action failureCallback, bool keepDisplayOn = true)
|
public static void SetTimedKeepAwake(long seconds, Action<bool> callback, Action failureCallback, bool keepDisplayOn = true)
|
||||||
{
|
{
|
||||||
TokenSource = new CancellationTokenSource();
|
_tokenSource = new CancellationTokenSource();
|
||||||
ThreadToken = TokenSource.Token;
|
_threadToken = _tokenSource.Token;
|
||||||
|
|
||||||
Task.Run(() => RunTimedLoop(seconds, keepDisplayOn), ThreadToken)
|
Task.Run(() => RunTimedLoop(seconds, keepDisplayOn), _threadToken)
|
||||||
.ContinueWith((result) => callback(result.Result), TaskContinuationOptions.OnlyOnRanToCompletion)
|
.ContinueWith((result) => callback(result.Result), TaskContinuationOptions.OnlyOnRanToCompletion)
|
||||||
.ContinueWith((result) => failureCallback, TaskContinuationOptions.NotOnRanToCompletion); ;
|
.ContinueWith((result) => failureCallback, TaskContinuationOptions.NotOnRanToCompletion);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool RunTimedLoop(long seconds, bool keepDisplayOn = true)
|
private static bool RunTimedLoop(long seconds, bool keepDisplayOn = true)
|
||||||
@@ -121,7 +110,7 @@ namespace Espresso.Shell.Core
|
|||||||
bool success = false;
|
bool success = false;
|
||||||
|
|
||||||
// In case cancellation was already requested.
|
// In case cancellation was already requested.
|
||||||
ThreadToken.ThrowIfCancellationRequested();
|
_threadToken.ThrowIfCancellationRequested();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (keepDisplayOn)
|
if (keepDisplayOn)
|
||||||
@@ -129,20 +118,21 @@ namespace Espresso.Shell.Core
|
|||||||
success = SetAwakeState(EXECUTION_STATE.ES_SYSTEM_REQUIRED | EXECUTION_STATE.ES_DISPLAY_REQUIRED | EXECUTION_STATE.ES_CONTINUOUS);
|
success = SetAwakeState(EXECUTION_STATE.ES_SYSTEM_REQUIRED | EXECUTION_STATE.ES_DISPLAY_REQUIRED | EXECUTION_STATE.ES_CONTINUOUS);
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
log.Info("Timed keep-awake with display on.");
|
_log.Info("Timed keep-awake with display on.");
|
||||||
var startTime = DateTime.UtcNow;
|
var startTime = DateTime.UtcNow;
|
||||||
while (DateTime.UtcNow - startTime < TimeSpan.FromSeconds(seconds))
|
while (DateTime.UtcNow - startTime < TimeSpan.FromSeconds(seconds))
|
||||||
{
|
{
|
||||||
if (ThreadToken.IsCancellationRequested)
|
if (_threadToken.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
ThreadToken.ThrowIfCancellationRequested();
|
_threadToken.ThrowIfCancellationRequested();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
log.Info("Could not set up timed keep-awake with display on.");
|
_log.Info("Could not set up timed keep-awake with display on.");
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -151,20 +141,21 @@ namespace Espresso.Shell.Core
|
|||||||
success = SetAwakeState(EXECUTION_STATE.ES_SYSTEM_REQUIRED | EXECUTION_STATE.ES_CONTINUOUS);
|
success = SetAwakeState(EXECUTION_STATE.ES_SYSTEM_REQUIRED | EXECUTION_STATE.ES_CONTINUOUS);
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
log.Info("Timed keep-awake with display off.");
|
_log.Info("Timed keep-awake with display off.");
|
||||||
var startTime = DateTime.UtcNow;
|
var startTime = DateTime.UtcNow;
|
||||||
while (DateTime.UtcNow - startTime < TimeSpan.FromSeconds(seconds))
|
while (DateTime.UtcNow - startTime < TimeSpan.FromSeconds(seconds))
|
||||||
{
|
{
|
||||||
if (ThreadToken.IsCancellationRequested)
|
if (_threadToken.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
ThreadToken.ThrowIfCancellationRequested();
|
_threadToken.ThrowIfCancellationRequested();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
log.Info("Could not set up timed keep-awake with display off.");
|
_log.Info("Could not set up timed keep-awake with display off.");
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -172,7 +163,7 @@ namespace Espresso.Shell.Core
|
|||||||
catch (OperationCanceledException ex)
|
catch (OperationCanceledException ex)
|
||||||
{
|
{
|
||||||
// Task was clearly cancelled.
|
// Task was clearly cancelled.
|
||||||
log.Info($"Background thread termination. Message: {ex.Message}");
|
_log.Info($"Background thread termination. Message: {ex.Message}");
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -182,7 +173,7 @@ namespace Espresso.Shell.Core
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type.
|
#pragma warning disable CS8600 // Converting null literal or possible null value to non-nullable type.
|
||||||
RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(BUILD_REGISTRY_LOCATION);
|
RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(BuildRegistryLocation);
|
||||||
#pragma warning restore CS8600 // Converting null literal or possible null value to non-nullable type.
|
#pragma warning restore CS8600 // Converting null literal or possible null value to non-nullable type.
|
||||||
|
|
||||||
if (registryKey != null)
|
if (registryKey != null)
|
||||||
@@ -192,18 +183,17 @@ namespace Espresso.Shell.Core
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
log.Debug("Registry key acquisition for OS failed.");
|
_log.Debug("Registry key acquisition for OS failed.");
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
log.Debug($"Could not get registry key for the build number. Error: {ex.Message}");
|
_log.Debug($"Could not get registry key for the build number. Error: {ex.Message}");
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static Icon? Extract(string file, int number, bool largeIcon)
|
public static Icon? Extract(string file, int number, bool largeIcon)
|
||||||
{
|
{
|
||||||
ExtractIconEx(file, number, out IntPtr large, out IntPtr small, 1);
|
ExtractIconEx(file, number, out IntPtr large, out IntPtr small, 1);
|
||||||
@@ -215,8 +205,6 @@ namespace Espresso.Shell.Core
|
|||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,11 @@
|
|||||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
// See the LICENSE file in the project root for more information.
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
using Microsoft.PowerToys.Settings.UI.Library;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
using Microsoft.PowerToys.Settings.UI.Library;
|
||||||
|
|
||||||
#pragma warning disable CS8602 // Dereference of a possibly null reference.
|
#pragma warning disable CS8602 // Dereference of a possibly null reference.
|
||||||
#pragma warning disable CS8603 // Possible null reference return.
|
#pragma warning disable CS8603 // Possible null reference return.
|
||||||
@@ -15,10 +15,12 @@ namespace Espresso.Shell.Core
|
|||||||
{
|
{
|
||||||
internal static class TrayHelper
|
internal static class TrayHelper
|
||||||
{
|
{
|
||||||
static NotifyIcon? trayIcon;
|
private static NotifyIcon? trayIcon;
|
||||||
|
|
||||||
private static NotifyIcon TrayIcon { get => trayIcon; set => trayIcon = value; }
|
private static NotifyIcon TrayIcon { get => trayIcon; set => trayIcon = value; }
|
||||||
|
|
||||||
static SettingsUtils? moduleSettings;
|
private static SettingsUtils? moduleSettings;
|
||||||
|
|
||||||
private static SettingsUtils ModuleSettings { get => moduleSettings; set => moduleSettings = value; }
|
private static SettingsUtils ModuleSettings { get => moduleSettings; set => moduleSettings = value; }
|
||||||
|
|
||||||
static TrayHelper()
|
static TrayHelper()
|
||||||
@@ -29,7 +31,8 @@ namespace Espresso.Shell.Core
|
|||||||
|
|
||||||
public static void InitializeTray(string text, Icon icon, ContextMenuStrip? contextMenu = null)
|
public static void InitializeTray(string text, Icon icon, ContextMenuStrip? contextMenu = null)
|
||||||
{
|
{
|
||||||
System.Threading.Tasks.Task.Factory.StartNew((tray) =>
|
System.Threading.Tasks.Task.Factory.StartNew(
|
||||||
|
(tray) =>
|
||||||
{
|
{
|
||||||
((NotifyIcon?)tray).Text = text;
|
((NotifyIcon?)tray).Text = text;
|
||||||
((NotifyIcon?)tray).Icon = icon;
|
((NotifyIcon?)tray).Icon = icon;
|
||||||
@@ -42,31 +45,51 @@ namespace Espresso.Shell.Core
|
|||||||
|
|
||||||
internal static void SetTray(string text, EspressoSettings settings)
|
internal static void SetTray(string text, EspressoSettings settings)
|
||||||
{
|
{
|
||||||
SetTray(text, settings.Properties.KeepDisplayOn.Value, settings.Properties.Mode,
|
SetTray(
|
||||||
() => {
|
text,
|
||||||
// Set indefinite keep awake.
|
settings.Properties.KeepDisplayOn.Value,
|
||||||
var currentSettings = ModuleSettings.GetSettings<EspressoSettings>(text);
|
settings.Properties.Mode,
|
||||||
currentSettings.Properties.Mode = EspressoMode.INDEFINITE;
|
IndefiniteKeepAwakeCallback(text),
|
||||||
|
TimedKeepAwakeCallback(text),
|
||||||
|
KeepDisplayOnCallback(text));
|
||||||
|
}
|
||||||
|
|
||||||
ModuleSettings.SaveSettings(JsonSerializer.Serialize(currentSettings), text);
|
private static Action KeepDisplayOnCallback(string text)
|
||||||
},
|
{
|
||||||
(hours, minutes) => {
|
return () =>
|
||||||
// Set timed keep awake.
|
{
|
||||||
var currentSettings = ModuleSettings.GetSettings<EspressoSettings>(text);
|
// Just changing the display mode.
|
||||||
currentSettings.Properties.Mode = EspressoMode.TIMED;
|
var currentSettings = ModuleSettings.GetSettings<EspressoSettings>(text);
|
||||||
currentSettings.Properties.Hours.Value = hours;
|
currentSettings.Properties.KeepDisplayOn.Value = !currentSettings.Properties.KeepDisplayOn.Value;
|
||||||
currentSettings.Properties.Minutes.Value = minutes;
|
|
||||||
|
|
||||||
ModuleSettings.SaveSettings(JsonSerializer.Serialize(currentSettings), text);
|
ModuleSettings.SaveSettings(JsonSerializer.Serialize(currentSettings), text);
|
||||||
},
|
};
|
||||||
() =>
|
}
|
||||||
{
|
|
||||||
// Just changing the display mode.
|
|
||||||
var currentSettings = ModuleSettings.GetSettings<EspressoSettings>(text);
|
|
||||||
currentSettings.Properties.KeepDisplayOn.Value = !currentSettings.Properties.KeepDisplayOn.Value;
|
|
||||||
|
|
||||||
ModuleSettings.SaveSettings(JsonSerializer.Serialize(currentSettings), text);
|
private static Action<int, int> TimedKeepAwakeCallback(string text)
|
||||||
});
|
{
|
||||||
|
return (hours, minutes) =>
|
||||||
|
{
|
||||||
|
// Set timed keep awake.
|
||||||
|
var currentSettings = ModuleSettings.GetSettings<EspressoSettings>(text);
|
||||||
|
currentSettings.Properties.Mode = EspressoMode.TIMED;
|
||||||
|
currentSettings.Properties.Hours.Value = hours;
|
||||||
|
currentSettings.Properties.Minutes.Value = minutes;
|
||||||
|
|
||||||
|
ModuleSettings.SaveSettings(JsonSerializer.Serialize(currentSettings), text);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Action IndefiniteKeepAwakeCallback(string text)
|
||||||
|
{
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
// Set indefinite keep awake.
|
||||||
|
var currentSettings = ModuleSettings.GetSettings<EspressoSettings>(text);
|
||||||
|
currentSettings.Properties.Mode = EspressoMode.INDEFINITE;
|
||||||
|
|
||||||
|
ModuleSettings.SaveSettings(JsonSerializer.Serialize(currentSettings), text);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void SetTray(string text, bool keepDisplayOn, EspressoMode mode, Action indefiniteKeepAwakeCallback, Action<int, int> timedKeepAwakeCallback, Action keepDisplayOnCallback)
|
internal static void SetTray(string text, bool keepDisplayOn, EspressoMode mode, Action indefiniteKeepAwakeCallback, Action<int, int> timedKeepAwakeCallback, Action keepDisplayOnCallback)
|
||||||
@@ -76,13 +99,13 @@ namespace Espresso.Shell.Core
|
|||||||
// Main toolstrip.
|
// Main toolstrip.
|
||||||
var operationContextMenu = new ToolStripMenuItem
|
var operationContextMenu = new ToolStripMenuItem
|
||||||
{
|
{
|
||||||
Text = "Mode"
|
Text = "Mode",
|
||||||
};
|
};
|
||||||
|
|
||||||
// Indefinite keep-awake menu item.
|
// Indefinite keep-awake menu item.
|
||||||
var indefiniteMenuItem = new ToolStripMenuItem
|
var indefiniteMenuItem = new ToolStripMenuItem
|
||||||
{
|
{
|
||||||
Text = "Indefinite"
|
Text = "Indefinite",
|
||||||
};
|
};
|
||||||
|
|
||||||
if (mode == EspressoMode.INDEFINITE)
|
if (mode == EspressoMode.INDEFINITE)
|
||||||
@@ -93,6 +116,7 @@ namespace Espresso.Shell.Core
|
|||||||
{
|
{
|
||||||
indefiniteMenuItem.Checked = false;
|
indefiniteMenuItem.Checked = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
indefiniteMenuItem.Click += (e, s) =>
|
indefiniteMenuItem.Click += (e, s) =>
|
||||||
{
|
{
|
||||||
// User opted to set the mode to indefinite, so we need to write new settings.
|
// User opted to set the mode to indefinite, so we need to write new settings.
|
||||||
@@ -101,7 +125,7 @@ namespace Espresso.Shell.Core
|
|||||||
|
|
||||||
var displayOnMenuItem = new ToolStripMenuItem
|
var displayOnMenuItem = new ToolStripMenuItem
|
||||||
{
|
{
|
||||||
Text = "Keep display on"
|
Text = "Keep display on",
|
||||||
};
|
};
|
||||||
if (keepDisplayOn)
|
if (keepDisplayOn)
|
||||||
{
|
{
|
||||||
@@ -111,6 +135,7 @@ namespace Espresso.Shell.Core
|
|||||||
{
|
{
|
||||||
displayOnMenuItem.Checked = false;
|
displayOnMenuItem.Checked = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
displayOnMenuItem.Click += (e, s) =>
|
displayOnMenuItem.Click += (e, s) =>
|
||||||
{
|
{
|
||||||
// User opted to set the display mode directly.
|
// User opted to set the display mode directly.
|
||||||
@@ -120,12 +145,12 @@ namespace Espresso.Shell.Core
|
|||||||
// Timed keep-awake menu item
|
// Timed keep-awake menu item
|
||||||
var timedMenuItem = new ToolStripMenuItem
|
var timedMenuItem = new ToolStripMenuItem
|
||||||
{
|
{
|
||||||
Text = "Timed"
|
Text = "Timed",
|
||||||
};
|
};
|
||||||
|
|
||||||
var halfHourMenuItem = new ToolStripMenuItem
|
var halfHourMenuItem = new ToolStripMenuItem
|
||||||
{
|
{
|
||||||
Text = "30 minutes"
|
Text = "30 minutes",
|
||||||
};
|
};
|
||||||
halfHourMenuItem.Click += (e, s) =>
|
halfHourMenuItem.Click += (e, s) =>
|
||||||
{
|
{
|
||||||
@@ -135,7 +160,7 @@ namespace Espresso.Shell.Core
|
|||||||
|
|
||||||
var oneHourMenuItem = new ToolStripMenuItem
|
var oneHourMenuItem = new ToolStripMenuItem
|
||||||
{
|
{
|
||||||
Text = "1 hour"
|
Text = "1 hour",
|
||||||
};
|
};
|
||||||
oneHourMenuItem.Click += (e, s) =>
|
oneHourMenuItem.Click += (e, s) =>
|
||||||
{
|
{
|
||||||
@@ -145,7 +170,7 @@ namespace Espresso.Shell.Core
|
|||||||
|
|
||||||
var twoHoursMenuItem = new ToolStripMenuItem
|
var twoHoursMenuItem = new ToolStripMenuItem
|
||||||
{
|
{
|
||||||
Text = "2 hours"
|
Text = "2 hours",
|
||||||
};
|
};
|
||||||
twoHoursMenuItem.Click += (e, s) =>
|
twoHoursMenuItem.Click += (e, s) =>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -60,5 +60,19 @@
|
|||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="..\..\..\codeAnalysis\GlobalSuppressions.cs">
|
||||||
|
<Link>GlobalSuppressions.cs</Link>
|
||||||
|
</Compile>
|
||||||
|
<AdditionalFiles Include="..\..\..\codeAnalysis\StyleCop.json">
|
||||||
|
<Link>StyleCop.json</Link>
|
||||||
|
</AdditionalFiles>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="StyleCop.Analyzers">
|
||||||
|
<Version>1.1.118</Version>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -2,10 +2,6 @@
|
|||||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
// See the LICENSE file in the project root for more information.
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
using Espresso.Shell.Core;
|
|
||||||
using ManagedCommon;
|
|
||||||
using Microsoft.PowerToys.Settings.UI.Library;
|
|
||||||
using NLog;
|
|
||||||
using System;
|
using System;
|
||||||
using System.CommandLine;
|
using System.CommandLine;
|
||||||
using System.CommandLine.Invocation;
|
using System.CommandLine.Invocation;
|
||||||
@@ -16,40 +12,44 @@ using System.Reactive.Concurrency;
|
|||||||
using System.Reactive.Linq;
|
using System.Reactive.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using Espresso.Shell.Core;
|
||||||
|
using ManagedCommon;
|
||||||
|
using Microsoft.PowerToys.Settings.UI.Library;
|
||||||
|
using NLog;
|
||||||
|
|
||||||
#pragma warning disable CS8602 // Dereference of a possibly null reference.
|
#pragma warning disable CS8602 // Dereference of a possibly null reference.
|
||||||
#pragma warning disable CS8603 // Possible null reference return.
|
#pragma warning disable CS8603 // Possible null reference return.
|
||||||
|
|
||||||
namespace Espresso.Shell
|
namespace Espresso.Shell
|
||||||
{
|
{
|
||||||
class Program
|
internal class Program
|
||||||
{
|
{
|
||||||
private static Mutex? mutex = null;
|
private static Mutex? _mutex = null;
|
||||||
private const string appName = "Espresso";
|
private const string AppName = "Espresso";
|
||||||
private static FileSystemWatcher? watcher = null;
|
private static FileSystemWatcher? _watcher = null;
|
||||||
private static SettingsUtils? settingsUtils = null;
|
private static SettingsUtils? _settingsUtils = null;
|
||||||
|
|
||||||
public static Mutex Mutex { get => mutex; set => mutex = value; }
|
public static Mutex LockMutex { get => _mutex; set => _mutex = value; }
|
||||||
|
|
||||||
private static Logger? log;
|
private static Logger? _log;
|
||||||
|
|
||||||
static int Main(string[] args)
|
private static int Main(string[] args)
|
||||||
{
|
{
|
||||||
bool instantiated;
|
bool instantiated;
|
||||||
Mutex = new Mutex(true, appName, out instantiated);
|
LockMutex = new Mutex(true, AppName, out instantiated);
|
||||||
|
|
||||||
if (!instantiated)
|
if (!instantiated)
|
||||||
{
|
{
|
||||||
ForceExit(appName + " is already running! Exiting the application.", 1);
|
ForceExit(AppName + " is already running! Exiting the application.", 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
log = LogManager.GetCurrentClassLogger();
|
_log = LogManager.GetCurrentClassLogger();
|
||||||
settingsUtils = new SettingsUtils();
|
_settingsUtils = new SettingsUtils();
|
||||||
|
|
||||||
log.Info("Launching Espresso...");
|
_log.Info("Launching Espresso...");
|
||||||
log.Info(FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion);
|
_log.Info(FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).FileVersion);
|
||||||
log.Debug($"OS: {Environment.OSVersion}");
|
_log.Debug($"OS: {Environment.OSVersion}");
|
||||||
log.Debug($"OS Build: {APIHelper.GetOperatingSystemBuild()}");
|
_log.Debug($"OS Build: {APIHelper.GetOperatingSystemBuild()}");
|
||||||
|
|
||||||
var configOption = new Option<bool>(
|
var configOption = new Option<bool>(
|
||||||
aliases: new[] { "--use-pt-config", "-c" },
|
aliases: new[] { "--use-pt-config", "-c" },
|
||||||
@@ -108,10 +108,10 @@ namespace Espresso.Shell
|
|||||||
configOption,
|
configOption,
|
||||||
displayOption,
|
displayOption,
|
||||||
timeOption,
|
timeOption,
|
||||||
pidOption
|
pidOption,
|
||||||
};
|
};
|
||||||
|
|
||||||
rootCommand.Description = appName;
|
rootCommand.Description = AppName;
|
||||||
|
|
||||||
rootCommand.Handler = CommandHandler.Create<bool, bool, long, int>(HandleCommandLineArguments);
|
rootCommand.Handler = CommandHandler.Create<bool, bool, long, int>(HandleCommandLineArguments);
|
||||||
|
|
||||||
@@ -120,21 +120,21 @@ namespace Espresso.Shell
|
|||||||
|
|
||||||
private static void ForceExit(string message, int exitCode)
|
private static void ForceExit(string message, int exitCode)
|
||||||
{
|
{
|
||||||
log.Debug(message);
|
_log.Debug(message);
|
||||||
log.Info(message);
|
_log.Info(message);
|
||||||
Console.ReadKey();
|
Console.ReadKey();
|
||||||
Environment.Exit(exitCode);
|
Environment.Exit(exitCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void HandleCommandLineArguments(bool usePtConfig, bool displayOn, long timeLimit, int pid)
|
private static void HandleCommandLineArguments(bool usePtConfig, bool displayOn, long timeLimit, int pid)
|
||||||
{
|
{
|
||||||
log.Info($"The value for --use-pt-config is: {usePtConfig}");
|
_log.Info($"The value for --use-pt-config is: {usePtConfig}");
|
||||||
log.Info($"The value for --display-on is: {displayOn}");
|
_log.Info($"The value for --display-on is: {displayOn}");
|
||||||
log.Info($"The value for --time-limit is: {timeLimit}");
|
_log.Info($"The value for --time-limit is: {timeLimit}");
|
||||||
log.Info($"The value for --pid is: {pid}");
|
_log.Info($"The value for --pid is: {pid}");
|
||||||
|
|
||||||
#pragma warning disable CS8604 // Possible null reference argument.
|
#pragma warning disable CS8604 // Possible null reference argument.
|
||||||
TrayHelper.InitializeTray(appName, APIHelper.Extract("shell32.dll", 32, true));
|
TrayHelper.InitializeTray(AppName, APIHelper.Extract("shell32.dll", 32, true));
|
||||||
#pragma warning restore CS8604 // Possible null reference argument.
|
#pragma warning restore CS8604 // Possible null reference argument.
|
||||||
|
|
||||||
if (usePtConfig)
|
if (usePtConfig)
|
||||||
@@ -143,21 +143,20 @@ namespace Espresso.Shell
|
|||||||
// and instead watch for changes in the file.
|
// and instead watch for changes in the file.
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var settingsPath = settingsUtils.GetSettingsFilePath(appName);
|
var settingsPath = _settingsUtils.GetSettingsFilePath(AppName);
|
||||||
log.Info($"Reading configuration file: {settingsPath}");
|
_log.Info($"Reading configuration file: {settingsPath}");
|
||||||
|
|
||||||
watcher = new FileSystemWatcher
|
_watcher = new FileSystemWatcher
|
||||||
{
|
{
|
||||||
Path = Path.GetDirectoryName(settingsPath),
|
Path = Path.GetDirectoryName(settingsPath),
|
||||||
EnableRaisingEvents = true,
|
EnableRaisingEvents = true,
|
||||||
NotifyFilter = NotifyFilters.LastWrite,
|
NotifyFilter = NotifyFilters.LastWrite,
|
||||||
Filter = Path.GetFileName(settingsPath)
|
Filter = Path.GetFileName(settingsPath),
|
||||||
};
|
};
|
||||||
|
|
||||||
Observable.FromEventPattern<FileSystemEventHandler, FileSystemEventArgs>(
|
Observable.FromEventPattern<FileSystemEventHandler, FileSystemEventArgs>(
|
||||||
h => watcher.Changed += h,
|
h => _watcher.Changed += h,
|
||||||
h => watcher.Changed -= h
|
h => _watcher.Changed -= h)
|
||||||
)
|
|
||||||
.SubscribeOn(TaskPoolScheduler.Default)
|
.SubscribeOn(TaskPoolScheduler.Default)
|
||||||
.Select(e => e.EventArgs)
|
.Select(e => e.EventArgs)
|
||||||
.Throttle(TimeSpan.FromMilliseconds(25))
|
.Throttle(TimeSpan.FromMilliseconds(25))
|
||||||
@@ -170,8 +169,8 @@ namespace Espresso.Shell
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
var errorString = $"There was a problem with the configuration file. Make sure it exists.\n{ex.Message}";
|
var errorString = $"There was a problem with the configuration file. Make sure it exists.\n{ex.Message}";
|
||||||
log.Info(errorString);
|
_log.Info(errorString);
|
||||||
log.Debug(errorString);
|
_log.Debug(errorString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -204,20 +203,20 @@ namespace Espresso.Shell
|
|||||||
bool success = APIHelper.SetIndefiniteKeepAwake(displayOn);
|
bool success = APIHelper.SetIndefiniteKeepAwake(displayOn);
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
log.Info($"Currently in indefinite keep awake. Display always on: {displayOn}");
|
_log.Info($"Currently in indefinite keep awake. Display always on: {displayOn}");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var errorMessage = "Could not set up the state to be indefinite keep awake.";
|
var errorMessage = "Could not set up the state to be indefinite keep awake.";
|
||||||
log.Info(errorMessage);
|
_log.Info(errorMessage);
|
||||||
log.Debug(errorMessage);
|
_log.Debug(errorMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void HandleEspressoConfigChange(FileSystemEventArgs fileEvent)
|
private static void HandleEspressoConfigChange(FileSystemEventArgs fileEvent)
|
||||||
{
|
{
|
||||||
log.Info("Detected a settings file change. Updating configuration...");
|
_log.Info("Detected a settings file change. Updating configuration...");
|
||||||
log.Info("Resetting keep-awake to normal state due to settings change.");
|
_log.Info("Resetting keep-awake to normal state due to settings change.");
|
||||||
ResetNormalPowerState();
|
ResetNormalPowerState();
|
||||||
ProcessSettings();
|
ProcessSettings();
|
||||||
}
|
}
|
||||||
@@ -226,7 +225,7 @@ namespace Espresso.Shell
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
EspressoSettings settings = settingsUtils.GetSettings<EspressoSettings>(appName);
|
EspressoSettings settings = _settingsUtils.GetSettings<EspressoSettings>(AppName);
|
||||||
|
|
||||||
if (settings != null)
|
if (settings != null)
|
||||||
{
|
{
|
||||||
@@ -238,6 +237,7 @@ namespace Espresso.Shell
|
|||||||
SetupIndefiniteKeepAwake(settings.Properties.KeepDisplayOn.Value);
|
SetupIndefiniteKeepAwake(settings.Properties.KeepDisplayOn.Value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case EspressoMode.TIMED:
|
case EspressoMode.TIMED:
|
||||||
{
|
{
|
||||||
// Timed keep-awake.
|
// Timed keep-awake.
|
||||||
@@ -246,35 +246,36 @@ namespace Espresso.Shell
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
var errorMessage = "Unknown mode of operation. Check config file.";
|
var errorMessage = "Unknown mode of operation. Check config file.";
|
||||||
log.Info(errorMessage);
|
_log.Info(errorMessage);
|
||||||
log.Debug(errorMessage);
|
_log.Debug(errorMessage);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TrayHelper.SetTray(appName, settings);
|
TrayHelper.SetTray(AppName, settings);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var errorMessage = "Settings are null.";
|
var errorMessage = "Settings are null.";
|
||||||
log.Info(errorMessage);
|
_log.Info(errorMessage);
|
||||||
log.Debug(errorMessage);
|
_log.Debug(errorMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
var errorMessage = $"There was a problem reading the configuration file. Error: {ex.Message}";
|
var errorMessage = $"There was a problem reading the configuration file. Error: {ex.Message}";
|
||||||
log.Info(errorMessage);
|
_log.Info(errorMessage);
|
||||||
log.Debug(errorMessage);
|
_log.Debug(errorMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void SetupTimedKeepAwake(long time, bool displayOn)
|
private static void SetupTimedKeepAwake(long time, bool displayOn)
|
||||||
{
|
{
|
||||||
log.Info($"Timed keep-awake. Expected runtime: {time} seconds with display on setting set to {displayOn}.");
|
_log.Info($"Timed keep-awake. Expected runtime: {time} seconds with display on setting set to {displayOn}.");
|
||||||
|
|
||||||
APIHelper.SetTimedKeepAwake(time, LogTimedKeepAwakeCompletion, LogUnexpectedOrCancelledKeepAwakeCompletion, displayOn);
|
APIHelper.SetTimedKeepAwake(time, LogTimedKeepAwakeCompletion, LogUnexpectedOrCancelledKeepAwakeCompletion, displayOn);
|
||||||
}
|
}
|
||||||
@@ -282,13 +283,13 @@ namespace Espresso.Shell
|
|||||||
private static void LogUnexpectedOrCancelledKeepAwakeCompletion()
|
private static void LogUnexpectedOrCancelledKeepAwakeCompletion()
|
||||||
{
|
{
|
||||||
var errorMessage = "The keep-awake thread was terminated early.";
|
var errorMessage = "The keep-awake thread was terminated early.";
|
||||||
log.Info(errorMessage);
|
_log.Info(errorMessage);
|
||||||
log.Debug(errorMessage);
|
_log.Debug(errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void LogTimedKeepAwakeCompletion(bool result)
|
private static void LogTimedKeepAwakeCompletion(bool result)
|
||||||
{
|
{
|
||||||
log.Info($"Completed timed keep-awake successfully: {result}");
|
_log.Info($"Completed timed keep-awake successfully: {result}");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ResetNormalPowerState()
|
private static void ResetNormalPowerState()
|
||||||
@@ -296,13 +297,13 @@ namespace Espresso.Shell
|
|||||||
bool success = APIHelper.SetNormalKeepAwake();
|
bool success = APIHelper.SetNormalKeepAwake();
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
log.Info("Returned to normal keep-awake state.");
|
_log.Info("Returned to normal keep-awake state.");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var errorMessage = "Could not return to normal keep-awake state.";
|
var errorMessage = "Could not return to normal keep-awake state.";
|
||||||
log.Info(errorMessage);
|
_log.Info(errorMessage);
|
||||||
log.Debug(errorMessage);
|
_log.Debug(errorMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user