mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 11:48:06 +01:00
Fixes for PowerToys Awake (#12215)
* Change how background threads operate This should reduce CPU usage. * Well there is just no need for the console here * Need to keep the full name sanitized * Update the changes to console handling * Updating how we handle constants * Fix process termination logic * Making some tweaks to the termination logic * Update how the process is tracked * Updating how application closing is done for Awake. * Update with explicit types * Fix high CPU usage for timed keep awake. * Logging typo fix. * Update some of the timer logic. * Fix variable naming for consistency * Cleanup the C++ interface * Cleanup the code a bit This change introduces support for: - Proper event handling across the two apps (Awake and runner). - Removal of unnecessary functions. * Cleaning up the code even further * Remove unnecessary functions
This commit is contained in:
@@ -186,5 +186,9 @@ public
|
|||||||
static String ^ ShowColorPickerSharedEvent() {
|
static String ^ ShowColorPickerSharedEvent() {
|
||||||
return gcnew String(CommonSharedConstants::SHOW_COLOR_PICKER_SHARED_EVENT);
|
return gcnew String(CommonSharedConstants::SHOW_COLOR_PICKER_SHARED_EVENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static String ^ AwakeExitEvent() {
|
||||||
|
return gcnew String(CommonSharedConstants::AWAKE_EXIT_EVENT);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,9 @@ namespace CommonSharedConstants
|
|||||||
|
|
||||||
const wchar_t FANCY_ZONES_EDITOR_TOGGLE_EVENT[] = L"Local\\FancyZones-ToggleEditorEvent-1e174338-06a3-472b-874d-073b21c62f14";
|
const wchar_t FANCY_ZONES_EDITOR_TOGGLE_EVENT[] = L"Local\\FancyZones-ToggleEditorEvent-1e174338-06a3-472b-874d-073b21c62f14";
|
||||||
|
|
||||||
|
// Path to the event used by Awake
|
||||||
|
const wchar_t AWAKE_EXIT_EVENT[] = L"Local\\PowerToysAwakeExitEvent-c0d5e305-35fc-4fb5-83ec-f6070cfaf7fe";
|
||||||
|
|
||||||
// Max DWORD for key code to disable keys.
|
// Max DWORD for key code to disable keys.
|
||||||
const DWORD VK_DISABLED = 0x100;
|
const DWORD VK_DISABLED = 0x100;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,18 @@ namespace Awake.Core
|
|||||||
ES_SYSTEM_REQUIRED = 0x00000001,
|
ES_SYSTEM_REQUIRED = 0x00000001,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// See: https://docs.microsoft.com/windows/console/handlerroutine
|
||||||
|
public enum ControlType
|
||||||
|
{
|
||||||
|
CTRL_C_EVENT = 0,
|
||||||
|
CTRL_BREAK_EVENT = 1,
|
||||||
|
CTRL_CLOSE_EVENT = 2,
|
||||||
|
CTRL_LOGOFF_EVENT = 5,
|
||||||
|
CTRL_SHUTDOWN_EVENT = 6,
|
||||||
|
}
|
||||||
|
|
||||||
|
public delegate bool ConsoleEventHandler(ControlType ctrlType);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Helper class that allows talking to Win32 APIs without having to rely on PInvoke in other parts
|
/// Helper class that allows talking to Win32 APIs without having to rely on PInvoke in other parts
|
||||||
/// of the codebase.
|
/// of the codebase.
|
||||||
@@ -37,6 +49,10 @@ namespace Awake.Core
|
|||||||
private static CancellationToken _threadToken;
|
private static CancellationToken _threadToken;
|
||||||
|
|
||||||
private static Task? _runnerThread;
|
private static Task? _runnerThread;
|
||||||
|
private static System.Timers.Timer _timedLoopTimer;
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
|
private static extern bool SetConsoleCtrlHandler(ConsoleEventHandler handler, bool add);
|
||||||
|
|
||||||
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||||||
private static extern EXECUTION_STATE SetThreadExecutionState(EXECUTION_STATE esFlags);
|
private static extern EXECUTION_STATE SetThreadExecutionState(EXECUTION_STATE esFlags);
|
||||||
@@ -63,10 +79,16 @@ namespace Awake.Core
|
|||||||
|
|
||||||
static APIHelper()
|
static APIHelper()
|
||||||
{
|
{
|
||||||
|
_timedLoopTimer = new System.Timers.Timer();
|
||||||
_log = LogManager.GetCurrentClassLogger();
|
_log = LogManager.GetCurrentClassLogger();
|
||||||
_tokenSource = new CancellationTokenSource();
|
_tokenSource = new CancellationTokenSource();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void SetConsoleControlHandler(ConsoleEventHandler handler, bool addHandler)
|
||||||
|
{
|
||||||
|
SetConsoleCtrlHandler(handler, addHandler);
|
||||||
|
}
|
||||||
|
|
||||||
public static void AllocateConsole()
|
public static void AllocateConsole()
|
||||||
{
|
{
|
||||||
_log.Debug("Bootstrapping the console allocation routine.");
|
_log.Debug("Bootstrapping the console allocation routine.");
|
||||||
@@ -139,7 +161,7 @@ namespace Awake.Core
|
|||||||
}
|
}
|
||||||
catch (OperationCanceledException)
|
catch (OperationCanceledException)
|
||||||
{
|
{
|
||||||
_log.Info("Confirmed background thread cancellation when setting passive keep awake.");
|
_log.Info("Confirmed background thread cancellation when disabling explicit keep awake.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,7 +178,7 @@ namespace Awake.Core
|
|||||||
}
|
}
|
||||||
catch (OperationCanceledException)
|
catch (OperationCanceledException)
|
||||||
{
|
{
|
||||||
_log.Info("Confirmed background thread cancellation when setting indefinite keep awake.");
|
_log.Info("Confirmed background thread cancellation when setting timed keep awake.");
|
||||||
}
|
}
|
||||||
|
|
||||||
_tokenSource = new CancellationTokenSource();
|
_tokenSource = new CancellationTokenSource();
|
||||||
@@ -223,14 +245,25 @@ namespace Awake.Core
|
|||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
_log.Info($"Initiated temporary keep awake in background thread: {GetCurrentThreadId()}. Screen on: {keepDisplayOn}");
|
_log.Info($"Initiated temporary keep awake in background thread: {GetCurrentThreadId()}. Screen on: {keepDisplayOn}");
|
||||||
var startTime = DateTime.UtcNow;
|
|
||||||
while (DateTime.UtcNow - startTime < TimeSpan.FromSeconds(Math.Abs(seconds)))
|
_timedLoopTimer = new System.Timers.Timer(seconds * 1000);
|
||||||
|
_timedLoopTimer.Elapsed += (s, e) =>
|
||||||
{
|
{
|
||||||
if (_threadToken.IsCancellationRequested)
|
_tokenSource.Cancel();
|
||||||
{
|
|
||||||
_threadToken.ThrowIfCancellationRequested();
|
_timedLoopTimer.Stop();
|
||||||
}
|
};
|
||||||
}
|
|
||||||
|
_timedLoopTimer.Disposed += (s, e) =>
|
||||||
|
{
|
||||||
|
_log.Info("Old timer disposed.");
|
||||||
|
};
|
||||||
|
|
||||||
|
_timedLoopTimer.Start();
|
||||||
|
|
||||||
|
WaitHandle.WaitAny(new[] { _threadToken.WaitHandle });
|
||||||
|
_timedLoopTimer.Stop();
|
||||||
|
_timedLoopTimer.Dispose();
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|||||||
12
src/modules/awake/Awake/Core/InternalConstants.cs
Normal file
12
src/modules/awake/Awake/Core/InternalConstants.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
namespace Awake.Core
|
||||||
|
{
|
||||||
|
internal static class InternalConstants
|
||||||
|
{
|
||||||
|
internal const string AppName = "Awake";
|
||||||
|
internal const string FullAppName = "PowerToys " + AppName;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,8 +6,10 @@ using System;
|
|||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using Microsoft.PowerToys.Settings.UI.Library;
|
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.
|
||||||
@@ -16,32 +18,43 @@ namespace Awake.Core
|
|||||||
{
|
{
|
||||||
internal static class TrayHelper
|
internal static class TrayHelper
|
||||||
{
|
{
|
||||||
private static NotifyIcon? trayIcon;
|
private static readonly Logger _log;
|
||||||
|
|
||||||
private static NotifyIcon TrayIcon { get => trayIcon; set => trayIcon = value; }
|
private static NotifyIcon? _trayIcon;
|
||||||
|
|
||||||
private static SettingsUtils? moduleSettings;
|
private static NotifyIcon TrayIcon { get => _trayIcon; set => _trayIcon = value; }
|
||||||
|
|
||||||
private static SettingsUtils ModuleSettings { get => moduleSettings; set => moduleSettings = value; }
|
private static SettingsUtils? _moduleSettings;
|
||||||
|
|
||||||
|
private static SettingsUtils ModuleSettings { get => _moduleSettings; set => _moduleSettings = value; }
|
||||||
|
|
||||||
static TrayHelper()
|
static TrayHelper()
|
||||||
{
|
{
|
||||||
|
_log = LogManager.GetCurrentClassLogger();
|
||||||
TrayIcon = new NotifyIcon();
|
TrayIcon = new NotifyIcon();
|
||||||
ModuleSettings = new SettingsUtils();
|
ModuleSettings = new SettingsUtils();
|
||||||
}
|
}
|
||||||
|
|
||||||
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(
|
Task.Factory.StartNew(
|
||||||
(tray) =>
|
(tray) =>
|
||||||
{
|
{
|
||||||
((NotifyIcon?)tray).Text = text;
|
((NotifyIcon?)tray).Text = text;
|
||||||
((NotifyIcon?)tray).Icon = icon;
|
((NotifyIcon?)tray).Icon = icon;
|
||||||
((NotifyIcon?)tray).ContextMenuStrip = contextMenu;
|
((NotifyIcon?)tray).ContextMenuStrip = contextMenu;
|
||||||
((NotifyIcon?)tray).Visible = true;
|
((NotifyIcon?)tray).Visible = true;
|
||||||
|
|
||||||
Application.Run();
|
_log.Info("Setting up the tray.");
|
||||||
}, TrayIcon);
|
Application.Run();
|
||||||
|
_log.Info("Tray setup complete.");
|
||||||
|
}, TrayIcon);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ClearTray()
|
||||||
|
{
|
||||||
|
TrayIcon.Icon = null;
|
||||||
|
TrayIcon.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void SetTray(string text, AwakeSettings settings)
|
internal static void SetTray(string text, AwakeSettings settings)
|
||||||
@@ -50,10 +63,10 @@ namespace Awake.Core
|
|||||||
text,
|
text,
|
||||||
settings.Properties.KeepDisplayOn,
|
settings.Properties.KeepDisplayOn,
|
||||||
settings.Properties.Mode,
|
settings.Properties.Mode,
|
||||||
PassiveKeepAwakeCallback(text),
|
PassiveKeepAwakeCallback(InternalConstants.AppName),
|
||||||
IndefiniteKeepAwakeCallback(text),
|
IndefiniteKeepAwakeCallback(InternalConstants.AppName),
|
||||||
TimedKeepAwakeCallback(text),
|
TimedKeepAwakeCallback(InternalConstants.AppName),
|
||||||
KeepDisplayOnCallback(text),
|
KeepDisplayOnCallback(InternalConstants.AppName),
|
||||||
ExitCallback());
|
ExitCallback());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,7 +74,7 @@ namespace Awake.Core
|
|||||||
{
|
{
|
||||||
return () =>
|
return () =>
|
||||||
{
|
{
|
||||||
Environment.Exit(0);
|
Environment.Exit(Environment.ExitCode);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,28 +166,21 @@ namespace Awake.Core
|
|||||||
|
|
||||||
public static void SetTray(string text, bool keepDisplayOn, AwakeMode mode, Action passiveKeepAwakeCallback, Action indefiniteKeepAwakeCallback, Action<uint, uint> timedKeepAwakeCallback, Action keepDisplayOnCallback, Action exitCallback)
|
public static void SetTray(string text, bool keepDisplayOn, AwakeMode mode, Action passiveKeepAwakeCallback, Action indefiniteKeepAwakeCallback, Action<uint, uint> timedKeepAwakeCallback, Action keepDisplayOnCallback, Action exitCallback)
|
||||||
{
|
{
|
||||||
var contextMenuStrip = new ContextMenuStrip();
|
ContextMenuStrip? contextMenuStrip = new ContextMenuStrip();
|
||||||
|
|
||||||
// Main toolstrip.
|
// Main toolstrip.
|
||||||
var operationContextMenu = new ToolStripMenuItem
|
ToolStripMenuItem? operationContextMenu = new ToolStripMenuItem
|
||||||
{
|
{
|
||||||
Text = "Mode",
|
Text = "Mode",
|
||||||
};
|
};
|
||||||
|
|
||||||
// No keep-awake menu item.
|
// No keep-awake menu item.
|
||||||
var passiveMenuItem = new ToolStripMenuItem
|
ToolStripMenuItem? passiveMenuItem = new ToolStripMenuItem
|
||||||
{
|
{
|
||||||
Text = "Off (Passive)",
|
Text = "Off (Passive)",
|
||||||
};
|
};
|
||||||
|
|
||||||
if (mode == AwakeMode.PASSIVE)
|
passiveMenuItem.Checked = mode == AwakeMode.PASSIVE;
|
||||||
{
|
|
||||||
passiveMenuItem.Checked = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
passiveMenuItem.Checked = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
passiveMenuItem.Click += (e, s) =>
|
passiveMenuItem.Click += (e, s) =>
|
||||||
{
|
{
|
||||||
@@ -183,19 +189,12 @@ namespace Awake.Core
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Indefinite keep-awake menu item.
|
// Indefinite keep-awake menu item.
|
||||||
var indefiniteMenuItem = new ToolStripMenuItem
|
ToolStripMenuItem? indefiniteMenuItem = new ToolStripMenuItem
|
||||||
{
|
{
|
||||||
Text = "Keep awake indefinitely",
|
Text = "Keep awake indefinitely",
|
||||||
};
|
};
|
||||||
|
|
||||||
if (mode == AwakeMode.INDEFINITE)
|
indefiniteMenuItem.Checked = mode == AwakeMode.INDEFINITE;
|
||||||
{
|
|
||||||
indefiniteMenuItem.Checked = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
indefiniteMenuItem.Checked = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
indefiniteMenuItem.Click += (e, s) =>
|
indefiniteMenuItem.Click += (e, s) =>
|
||||||
{
|
{
|
||||||
@@ -203,18 +202,12 @@ namespace Awake.Core
|
|||||||
indefiniteKeepAwakeCallback();
|
indefiniteKeepAwakeCallback();
|
||||||
};
|
};
|
||||||
|
|
||||||
var displayOnMenuItem = new ToolStripMenuItem
|
ToolStripMenuItem? displayOnMenuItem = new ToolStripMenuItem
|
||||||
{
|
{
|
||||||
Text = "Keep screen on",
|
Text = "Keep screen on",
|
||||||
};
|
};
|
||||||
if (keepDisplayOn)
|
|
||||||
{
|
displayOnMenuItem.Checked = keepDisplayOn;
|
||||||
displayOnMenuItem.Checked = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
displayOnMenuItem.Checked = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
displayOnMenuItem.Click += (e, s) =>
|
displayOnMenuItem.Click += (e, s) =>
|
||||||
{
|
{
|
||||||
@@ -223,43 +216,40 @@ namespace Awake.Core
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Timed keep-awake menu item
|
// Timed keep-awake menu item
|
||||||
var timedMenuItem = new ToolStripMenuItem
|
ToolStripMenuItem? timedMenuItem = new ToolStripMenuItem
|
||||||
{
|
{
|
||||||
Text = "Keep awake temporarily",
|
Text = "Keep awake temporarily",
|
||||||
};
|
};
|
||||||
if (mode == AwakeMode.TIMED)
|
|
||||||
{
|
|
||||||
timedMenuItem.Checked = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
timedMenuItem.Checked = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var halfHourMenuItem = new ToolStripMenuItem
|
timedMenuItem.Checked = mode == AwakeMode.TIMED;
|
||||||
|
|
||||||
|
ToolStripMenuItem? halfHourMenuItem = new ToolStripMenuItem
|
||||||
{
|
{
|
||||||
Text = "30 minutes",
|
Text = "30 minutes",
|
||||||
};
|
};
|
||||||
|
|
||||||
halfHourMenuItem.Click += (e, s) =>
|
halfHourMenuItem.Click += (e, s) =>
|
||||||
{
|
{
|
||||||
// User is setting the keep-awake to 30 minutes.
|
// User is setting the keep-awake to 30 minutes.
|
||||||
timedKeepAwakeCallback(0, 30);
|
timedKeepAwakeCallback(0, 30);
|
||||||
};
|
};
|
||||||
|
|
||||||
var oneHourMenuItem = new ToolStripMenuItem
|
ToolStripMenuItem? oneHourMenuItem = new ToolStripMenuItem
|
||||||
{
|
{
|
||||||
Text = "1 hour",
|
Text = "1 hour",
|
||||||
};
|
};
|
||||||
|
|
||||||
oneHourMenuItem.Click += (e, s) =>
|
oneHourMenuItem.Click += (e, s) =>
|
||||||
{
|
{
|
||||||
// User is setting the keep-awake to 1 hour.
|
// User is setting the keep-awake to 1 hour.
|
||||||
timedKeepAwakeCallback(1, 0);
|
timedKeepAwakeCallback(1, 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
var twoHoursMenuItem = new ToolStripMenuItem
|
ToolStripMenuItem? twoHoursMenuItem = new ToolStripMenuItem
|
||||||
{
|
{
|
||||||
Text = "2 hours",
|
Text = "2 hours",
|
||||||
};
|
};
|
||||||
|
|
||||||
twoHoursMenuItem.Click += (e, s) =>
|
twoHoursMenuItem.Click += (e, s) =>
|
||||||
{
|
{
|
||||||
// User is setting the keep-awake to 2 hours.
|
// User is setting the keep-awake to 2 hours.
|
||||||
@@ -267,10 +257,11 @@ namespace Awake.Core
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Exit menu item.
|
// Exit menu item.
|
||||||
var exitContextMenu = new ToolStripMenuItem
|
ToolStripMenuItem? exitContextMenu = new ToolStripMenuItem
|
||||||
{
|
{
|
||||||
Text = "Exit",
|
Text = "Exit",
|
||||||
};
|
};
|
||||||
|
|
||||||
exitContextMenu.Click += (e, s) =>
|
exitContextMenu.Click += (e, s) =>
|
||||||
{
|
{
|
||||||
// User is setting the keep-awake to 2 hours.
|
// User is setting the keep-awake to 2 hours.
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ using System.Reflection;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using Awake.Core;
|
using Awake.Core;
|
||||||
|
using interop;
|
||||||
using ManagedCommon;
|
using ManagedCommon;
|
||||||
using Microsoft.PowerToys.Settings.UI.Library;
|
using Microsoft.PowerToys.Settings.UI.Library;
|
||||||
using NLog;
|
using NLog;
|
||||||
@@ -27,8 +28,6 @@ namespace Awake
|
|||||||
internal class Program
|
internal class Program
|
||||||
{
|
{
|
||||||
private static Mutex? _mutex = null;
|
private static Mutex? _mutex = null;
|
||||||
private const string AppName = "Awake";
|
|
||||||
private const string FullAppName = "PowerToys " + AppName;
|
|
||||||
private static FileSystemWatcher? _watcher = null;
|
private static FileSystemWatcher? _watcher = null;
|
||||||
private static SettingsUtils? _settingsUtils = null;
|
private static SettingsUtils? _settingsUtils = null;
|
||||||
|
|
||||||
@@ -36,17 +35,25 @@ namespace Awake
|
|||||||
|
|
||||||
private static Logger? _log;
|
private static Logger? _log;
|
||||||
|
|
||||||
|
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
||||||
|
private static ConsoleEventHandler _handler;
|
||||||
|
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
||||||
|
|
||||||
|
private static ManualResetEvent _exitSignal = new ManualResetEvent(false);
|
||||||
|
|
||||||
private static int Main(string[] args)
|
private static int Main(string[] args)
|
||||||
{
|
{
|
||||||
bool instantiated;
|
// Log initialization needs to always happen before we test whether
|
||||||
LockMutex = new Mutex(true, AppName, out instantiated);
|
// only one instance of Awake is running.
|
||||||
|
_log = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
|
LockMutex = new Mutex(true, InternalConstants.AppName, out bool instantiated);
|
||||||
|
|
||||||
if (!instantiated)
|
if (!instantiated)
|
||||||
{
|
{
|
||||||
ForceExit(AppName + " is already running! Exiting the application.", 1);
|
Exit(InternalConstants.AppName + " is already running! Exiting the application.", 1, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
_log = LogManager.GetCurrentClassLogger();
|
|
||||||
_settingsUtils = new SettingsUtils();
|
_settingsUtils = new SettingsUtils();
|
||||||
|
|
||||||
_log.Info("Launching PowerToys Awake...");
|
_log.Info("Launching PowerToys Awake...");
|
||||||
@@ -56,7 +63,7 @@ namespace Awake
|
|||||||
|
|
||||||
_log.Info("Parsing parameters...");
|
_log.Info("Parsing parameters...");
|
||||||
|
|
||||||
var configOption = new Option<bool>(
|
Option<bool>? configOption = new Option<bool>(
|
||||||
aliases: new[] { "--use-pt-config", "-c" },
|
aliases: new[] { "--use-pt-config", "-c" },
|
||||||
getDefaultValue: () => false,
|
getDefaultValue: () => false,
|
||||||
description: "Specifies whether PowerToys Awake will be using the PowerToys configuration file for managing the state.")
|
description: "Specifies whether PowerToys Awake will be using the PowerToys configuration file for managing the state.")
|
||||||
@@ -69,7 +76,7 @@ namespace Awake
|
|||||||
|
|
||||||
configOption.Required = false;
|
configOption.Required = false;
|
||||||
|
|
||||||
var displayOption = new Option<bool>(
|
Option<bool>? displayOption = new Option<bool>(
|
||||||
aliases: new[] { "--display-on", "-d" },
|
aliases: new[] { "--display-on", "-d" },
|
||||||
getDefaultValue: () => true,
|
getDefaultValue: () => true,
|
||||||
description: "Determines whether the display should be kept awake.")
|
description: "Determines whether the display should be kept awake.")
|
||||||
@@ -82,7 +89,7 @@ namespace Awake
|
|||||||
|
|
||||||
displayOption.Required = false;
|
displayOption.Required = false;
|
||||||
|
|
||||||
var timeOption = new Option<uint>(
|
Option<uint>? timeOption = new Option<uint>(
|
||||||
aliases: new[] { "--time-limit", "-t" },
|
aliases: new[] { "--time-limit", "-t" },
|
||||||
getDefaultValue: () => 0,
|
getDefaultValue: () => 0,
|
||||||
description: "Determines the interval, in seconds, during which the computer is kept awake.")
|
description: "Determines the interval, in seconds, during which the computer is kept awake.")
|
||||||
@@ -95,7 +102,7 @@ namespace Awake
|
|||||||
|
|
||||||
timeOption.Required = false;
|
timeOption.Required = false;
|
||||||
|
|
||||||
var pidOption = new Option<int>(
|
Option<int>? pidOption = new Option<int>(
|
||||||
aliases: new[] { "--pid", "-p" },
|
aliases: new[] { "--pid", "-p" },
|
||||||
getDefaultValue: () => 0,
|
getDefaultValue: () => 0,
|
||||||
description: "Bind the execution of PowerToys Awake to another process.")
|
description: "Bind the execution of PowerToys Awake to another process.")
|
||||||
@@ -108,7 +115,7 @@ namespace Awake
|
|||||||
|
|
||||||
pidOption.Required = false;
|
pidOption.Required = false;
|
||||||
|
|
||||||
var rootCommand = new RootCommand
|
RootCommand? rootCommand = new RootCommand
|
||||||
{
|
{
|
||||||
configOption,
|
configOption,
|
||||||
displayOption,
|
displayOption,
|
||||||
@@ -116,7 +123,7 @@ namespace Awake
|
|||||||
pidOption,
|
pidOption,
|
||||||
};
|
};
|
||||||
|
|
||||||
rootCommand.Description = AppName;
|
rootCommand.Description = InternalConstants.AppName;
|
||||||
|
|
||||||
rootCommand.Handler = CommandHandler.Create<bool, bool, uint, int>(HandleCommandLineArguments);
|
rootCommand.Handler = CommandHandler.Create<bool, bool, uint, int>(HandleCommandLineArguments);
|
||||||
|
|
||||||
@@ -125,14 +132,38 @@ namespace Awake
|
|||||||
return rootCommand.InvokeAsync(args).Result;
|
return rootCommand.InvokeAsync(args).Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ForceExit(string message, int exitCode)
|
private static bool ExitHandler(ControlType ctrlType)
|
||||||
|
{
|
||||||
|
_log.Info($"Exited through handler with control type: {ctrlType}");
|
||||||
|
|
||||||
|
Exit("Exiting from the internal termination handler.", Environment.ExitCode);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Exit(string message, int exitCode, bool force = false)
|
||||||
{
|
{
|
||||||
_log.Info(message);
|
_log.Info(message);
|
||||||
Environment.Exit(exitCode);
|
|
||||||
|
APIHelper.SetNoKeepAwake();
|
||||||
|
TrayHelper.ClearTray();
|
||||||
|
|
||||||
|
// Because we are running a message loop for the tray, we can't just use Environment.Exit,
|
||||||
|
// but have to make sure that we properly send the termination message.
|
||||||
|
bool cwResult = System.Diagnostics.Process.GetCurrentProcess().CloseMainWindow();
|
||||||
|
_log.Info($"Request to close main window status: {cwResult}");
|
||||||
|
|
||||||
|
if (force)
|
||||||
|
{
|
||||||
|
Environment.Exit(exitCode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void HandleCommandLineArguments(bool usePtConfig, bool displayOn, uint timeLimit, int pid)
|
private static void HandleCommandLineArguments(bool usePtConfig, bool displayOn, uint timeLimit, int pid)
|
||||||
{
|
{
|
||||||
|
_handler += new ConsoleEventHandler(ExitHandler);
|
||||||
|
APIHelper.SetConsoleControlHandler(_handler, true);
|
||||||
|
|
||||||
if (pid == 0)
|
if (pid == 0)
|
||||||
{
|
{
|
||||||
_log.Info("No PID specified. Allocating console...");
|
_log.Info("No PID specified. Allocating console...");
|
||||||
@@ -150,11 +181,18 @@ namespace Awake
|
|||||||
// and instead watch for changes in the file.
|
// and instead watch for changes in the file.
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
#pragma warning disable CS8604 // Possible null reference argument.
|
new Thread(() =>
|
||||||
TrayHelper.InitializeTray(FullAppName, new Icon(Application.GetResourceStream(new Uri("/Images/Awake.ico", UriKind.Relative)).Stream));
|
{
|
||||||
#pragma warning restore CS8604 // Possible null reference argument.
|
EventWaitHandle? eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.AwakeExitEvent());
|
||||||
|
if (eventHandle.WaitOne())
|
||||||
|
{
|
||||||
|
Exit("Received a signal to end the process. Making sure we quit...", 0, true);
|
||||||
|
}
|
||||||
|
}).Start();
|
||||||
|
|
||||||
var settingsPath = _settingsUtils.GetSettingsFilePath(AppName);
|
TrayHelper.InitializeTray(InternalConstants.FullAppName, new Icon(Application.GetResourceStream(new Uri("/Images/Awake.ico", UriKind.Relative)).Stream));
|
||||||
|
|
||||||
|
string? settingsPath = _settingsUtils.GetSettingsFilePath(InternalConstants.AppName);
|
||||||
_log.Info($"Reading configuration file: {settingsPath}");
|
_log.Info($"Reading configuration file: {settingsPath}");
|
||||||
|
|
||||||
_watcher = new FileSystemWatcher
|
_watcher = new FileSystemWatcher
|
||||||
@@ -165,22 +203,22 @@ namespace Awake
|
|||||||
Filter = Path.GetFileName(settingsPath),
|
Filter = Path.GetFileName(settingsPath),
|
||||||
};
|
};
|
||||||
|
|
||||||
var changedObservable = Observable.FromEventPattern<FileSystemEventHandler, FileSystemEventArgs>(
|
IObservable<System.Reactive.EventPattern<FileSystemEventArgs>>? changedObservable = Observable.FromEventPattern<FileSystemEventHandler, FileSystemEventArgs>(
|
||||||
h => _watcher.Changed += h,
|
h => _watcher.Changed += h,
|
||||||
h => _watcher.Changed -= h);
|
h => _watcher.Changed -= h);
|
||||||
|
|
||||||
var createdObservable = Observable.FromEventPattern<FileSystemEventHandler, FileSystemEventArgs>(
|
IObservable<System.Reactive.EventPattern<FileSystemEventArgs>>? createdObservable = Observable.FromEventPattern<FileSystemEventHandler, FileSystemEventArgs>(
|
||||||
cre => _watcher.Created += cre,
|
cre => _watcher.Created += cre,
|
||||||
cre => _watcher.Created -= cre);
|
cre => _watcher.Created -= cre);
|
||||||
|
|
||||||
var mergedObservable = Observable.Merge(changedObservable, createdObservable);
|
IObservable<System.Reactive.EventPattern<FileSystemEventArgs>>? mergedObservable = Observable.Merge(changedObservable, createdObservable);
|
||||||
|
|
||||||
mergedObservable.Throttle(TimeSpan.FromMilliseconds(25))
|
mergedObservable.Throttle(TimeSpan.FromMilliseconds(25))
|
||||||
.SubscribeOn(TaskPoolScheduler.Default)
|
.SubscribeOn(TaskPoolScheduler.Default)
|
||||||
.Select(e => e.EventArgs)
|
.Select(e => e.EventArgs)
|
||||||
.Subscribe(HandleAwakeConfigChange);
|
.Subscribe(HandleAwakeConfigChange);
|
||||||
|
|
||||||
TrayHelper.SetTray(FullAppName, new AwakeSettings());
|
TrayHelper.SetTray(InternalConstants.FullAppName, new AwakeSettings());
|
||||||
|
|
||||||
// Initially the file might not be updated, so we need to start processing
|
// Initially the file might not be updated, so we need to start processing
|
||||||
// settings right away.
|
// settings right away.
|
||||||
@@ -188,14 +226,14 @@ namespace Awake
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
var errorString = $"There was a problem with the configuration file. Make sure it exists.\n{ex.Message}";
|
string? 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
|
||||||
{
|
{
|
||||||
var mode = timeLimit <= 0 ? AwakeMode.INDEFINITE : AwakeMode.TIMED;
|
AwakeMode mode = timeLimit <= 0 ? AwakeMode.INDEFINITE : AwakeMode.TIMED;
|
||||||
|
|
||||||
if (mode == AwakeMode.INDEFINITE)
|
if (mode == AwakeMode.INDEFINITE)
|
||||||
{
|
{
|
||||||
@@ -207,22 +245,19 @@ namespace Awake
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var exitSignal = new ManualResetEvent(false);
|
|
||||||
if (pid != 0)
|
if (pid != 0)
|
||||||
{
|
{
|
||||||
RunnerHelper.WaitForPowerToysRunner(pid, () =>
|
RunnerHelper.WaitForPowerToysRunner(pid, () =>
|
||||||
{
|
{
|
||||||
exitSignal.Set();
|
Exit("Terminating from PowerToys binding hook.", 0, true);
|
||||||
Environment.Exit(0);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
exitSignal.WaitOne();
|
_exitSignal.WaitOne();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void SetupIndefiniteKeepAwake(bool displayOn)
|
private static void SetupIndefiniteKeepAwake(bool displayOn)
|
||||||
{
|
{
|
||||||
// Indefinite keep awake.
|
|
||||||
APIHelper.SetIndefiniteKeepAwake(LogCompletedKeepAwakeThread, LogUnexpectedOrCancelledKeepAwakeThreadCompletion, displayOn);
|
APIHelper.SetIndefiniteKeepAwake(LogCompletedKeepAwakeThread, LogUnexpectedOrCancelledKeepAwakeThreadCompletion, displayOn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -237,7 +272,7 @@ namespace Awake
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
AwakeSettings settings = _settingsUtils.GetSettings<AwakeSettings>(AppName);
|
AwakeSettings settings = _settingsUtils.GetSettings<AwakeSettings>(InternalConstants.AppName);
|
||||||
|
|
||||||
if (settings != null)
|
if (settings != null)
|
||||||
{
|
{
|
||||||
@@ -251,14 +286,12 @@ namespace Awake
|
|||||||
|
|
||||||
case AwakeMode.INDEFINITE:
|
case AwakeMode.INDEFINITE:
|
||||||
{
|
{
|
||||||
// Indefinite keep awake.
|
|
||||||
SetupIndefiniteKeepAwake(settings.Properties.KeepDisplayOn);
|
SetupIndefiniteKeepAwake(settings.Properties.KeepDisplayOn);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case AwakeMode.TIMED:
|
case AwakeMode.TIMED:
|
||||||
{
|
{
|
||||||
// Timed keep-awake.
|
|
||||||
uint computedTime = (settings.Properties.Hours * 60 * 60) + (settings.Properties.Minutes * 60);
|
uint computedTime = (settings.Properties.Hours * 60 * 60) + (settings.Properties.Minutes * 60);
|
||||||
SetupTimedKeepAwake(computedTime, settings.Properties.KeepDisplayOn);
|
SetupTimedKeepAwake(computedTime, settings.Properties.KeepDisplayOn);
|
||||||
|
|
||||||
@@ -267,25 +300,25 @@ namespace Awake
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
var errorMessage = "Unknown mode of operation. Check config file.";
|
string? errorMessage = "Unknown mode of operation. Check config file.";
|
||||||
_log.Info(errorMessage);
|
_log.Info(errorMessage);
|
||||||
_log.Debug(errorMessage);
|
_log.Debug(errorMessage);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TrayHelper.SetTray(FullAppName, settings);
|
TrayHelper.SetTray(InternalConstants.FullAppName, settings);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var errorMessage = "Settings are null.";
|
string? 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.GetType()} {ex.Message}";
|
string? errorMessage = $"There was a problem reading the configuration file. Error: {ex.GetType()} {ex.Message}";
|
||||||
_log.Info(errorMessage);
|
_log.Info(errorMessage);
|
||||||
_log.Debug(errorMessage);
|
_log.Debug(errorMessage);
|
||||||
}
|
}
|
||||||
@@ -307,7 +340,7 @@ namespace Awake
|
|||||||
|
|
||||||
private static void LogUnexpectedOrCancelledKeepAwakeThreadCompletion()
|
private static void LogUnexpectedOrCancelledKeepAwakeThreadCompletion()
|
||||||
{
|
{
|
||||||
var errorMessage = "The keep-awake thread was terminated early.";
|
string? errorMessage = "The keep-awake thread was terminated early.";
|
||||||
_log.Info(errorMessage);
|
_log.Info(errorMessage);
|
||||||
_log.Debug(errorMessage);
|
_log.Debug(errorMessage);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#include <common/utils/winapi_error.h>
|
#include <common/utils/winapi_error.h>
|
||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
|
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
|
||||||
{
|
{
|
||||||
@@ -33,34 +34,23 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The PowerToy name that will be shown in the settings.
|
|
||||||
const static wchar_t* MODULE_NAME = L"Awake";
|
const static wchar_t* MODULE_NAME = L"Awake";
|
||||||
|
|
||||||
// Add a description that will we shown in the module settings page.
|
|
||||||
const static wchar_t* MODULE_DESC = L"A module that keeps your computer awake on-demand.";
|
const static wchar_t* MODULE_DESC = L"A module that keeps your computer awake on-demand.";
|
||||||
|
|
||||||
// Implement the PowerToy Module Interface and all the required methods.
|
|
||||||
class Awake : public PowertoyModuleIface
|
class Awake : public PowertoyModuleIface
|
||||||
{
|
{
|
||||||
std::wstring app_name;
|
std::wstring app_name;
|
||||||
|
|
||||||
// Contains the non localized key of the powertoy
|
|
||||||
std::wstring app_key;
|
std::wstring app_key;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// The PowerToy state.
|
|
||||||
bool m_enabled = false;
|
bool m_enabled = false;
|
||||||
|
|
||||||
HANDLE m_hProcess;
|
|
||||||
|
|
||||||
HANDLE send_telemetry_event;
|
HANDLE send_telemetry_event;
|
||||||
|
|
||||||
// Handle to event used to invoke PowerToys Awake
|
|
||||||
HANDLE m_hInvokeEvent;
|
HANDLE m_hInvokeEvent;
|
||||||
|
PROCESS_INFORMATION p_info;
|
||||||
|
|
||||||
bool is_process_running()
|
bool is_process_running()
|
||||||
{
|
{
|
||||||
return WaitForSingleObject(m_hProcess, 0) == WAIT_TIMEOUT;
|
return WaitForSingleObject(p_info.hProcess, 0) == WAIT_TIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void launch_process()
|
void launch_process()
|
||||||
@@ -69,26 +59,22 @@ private:
|
|||||||
unsigned long powertoys_pid = GetCurrentProcessId();
|
unsigned long powertoys_pid = GetCurrentProcessId();
|
||||||
|
|
||||||
std::wstring executable_args = L"--use-pt-config --pid " + std::to_wstring(powertoys_pid);
|
std::wstring executable_args = L"--use-pt-config --pid " + std::to_wstring(powertoys_pid);
|
||||||
|
std::wstring application_path = L"modules\\Awake\\PowerToys.Awake.exe";
|
||||||
|
std::wstring full_command_path = application_path + L" " + executable_args.data();
|
||||||
Logger::trace(L"PowerToys Awake launching with parameters: " + executable_args);
|
Logger::trace(L"PowerToys Awake launching with parameters: " + executable_args);
|
||||||
|
|
||||||
SHELLEXECUTEINFOW sei{ sizeof(sei) };
|
STARTUPINFO info = { sizeof(info) };
|
||||||
sei.fMask = { SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI };
|
|
||||||
sei.lpFile = L"modules\\Awake\\PowerToys.Awake.exe";
|
if (!CreateProcess(application_path.c_str(), full_command_path.data(), NULL, NULL, true, NULL, NULL, NULL, &info, &p_info))
|
||||||
sei.nShow = SW_SHOWNORMAL;
|
|
||||||
sei.lpParameters = executable_args.data();
|
|
||||||
if (!ShellExecuteExW(&sei))
|
|
||||||
{
|
{
|
||||||
DWORD error = GetLastError();
|
DWORD error = GetLastError();
|
||||||
std::wstring message = L"PowerToys Awake failed to start with error = ";
|
std::wstring message = L"PowerToys Awake failed to start with error: ";
|
||||||
message += std::to_wstring(error);
|
message += std::to_wstring(error);
|
||||||
Logger::error(message);
|
Logger::error(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_hProcess = sei.hProcess;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Constructor
|
|
||||||
Awake()
|
Awake()
|
||||||
{
|
{
|
||||||
app_name = GET_RESOURCE_STRING(IDS_AWAKE_NAME);
|
app_name = GET_RESOURCE_STRING(IDS_AWAKE_NAME);
|
||||||
@@ -99,37 +85,31 @@ public:
|
|||||||
Logger::info("Launcher object is constructing");
|
Logger::info("Launcher object is constructing");
|
||||||
};
|
};
|
||||||
|
|
||||||
// Destroy the powertoy and free memory
|
|
||||||
virtual void destroy() override
|
virtual void destroy() override
|
||||||
{
|
{
|
||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the display name of the powertoy, this will be cached by the runner
|
|
||||||
virtual const wchar_t* get_name() override
|
virtual const wchar_t* get_name() override
|
||||||
{
|
{
|
||||||
return MODULE_NAME;
|
return MODULE_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return JSON with the configuration options.
|
|
||||||
virtual bool get_config(wchar_t* buffer, int* buffer_size) override
|
virtual bool get_config(wchar_t* buffer, int* buffer_size) override
|
||||||
{
|
{
|
||||||
HINSTANCE hinstance = reinterpret_cast<HINSTANCE>(&__ImageBase);
|
HINSTANCE hinstance = reinterpret_cast<HINSTANCE>(&__ImageBase);
|
||||||
|
|
||||||
// Create a Settings object.
|
|
||||||
PowerToysSettings::Settings settings(hinstance, get_name());
|
PowerToysSettings::Settings settings(hinstance, get_name());
|
||||||
settings.set_description(MODULE_DESC);
|
settings.set_description(MODULE_DESC);
|
||||||
|
|
||||||
return settings.serialize_to_buffer(buffer, buffer_size);
|
return settings.serialize_to_buffer(buffer, buffer_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the non localized key of the powertoy, this will be cached by the runner
|
|
||||||
virtual const wchar_t* get_key() override
|
virtual const wchar_t* get_key() override
|
||||||
{
|
{
|
||||||
return app_key.c_str();
|
return app_key.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called by the runner to pass the updated settings values as a serialized JSON.
|
|
||||||
virtual void set_config(const wchar_t* config) override
|
virtual void set_config(const wchar_t* config) override
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -139,7 +119,7 @@ public:
|
|||||||
PowerToysSettings::PowerToyValues::from_json_string(config, get_key());
|
PowerToysSettings::PowerToyValues::from_json_string(config, get_key());
|
||||||
|
|
||||||
// If you don't need to do any custom processing of the settings, proceed
|
// If you don't need to do any custom processing of the settings, proceed
|
||||||
// to persists the values calling:
|
// to persists the values.
|
||||||
values.save_to_settings_file();
|
values.save_to_settings_file();
|
||||||
}
|
}
|
||||||
catch (std::exception&)
|
catch (std::exception&)
|
||||||
@@ -160,15 +140,36 @@ public:
|
|||||||
{
|
{
|
||||||
if (m_enabled)
|
if (m_enabled)
|
||||||
{
|
{
|
||||||
|
Logger::trace(L"Disabling Awake...");
|
||||||
ResetEvent(send_telemetry_event);
|
ResetEvent(send_telemetry_event);
|
||||||
ResetEvent(m_hInvokeEvent);
|
ResetEvent(m_hInvokeEvent);
|
||||||
TerminateProcess(m_hProcess, 1);
|
|
||||||
|
auto exitEvent = CreateEvent(nullptr, false, false, CommonSharedConstants::AWAKE_EXIT_EVENT);
|
||||||
|
if (!exitEvent)
|
||||||
|
{
|
||||||
|
Logger::warn(L"Failed to create exit event for PowerToys Awake. {}", get_last_error_or_default(GetLastError()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logger::trace(L"Signaled exit event for PowerToys Awake.");
|
||||||
|
if (!SetEvent(exitEvent))
|
||||||
|
{
|
||||||
|
Logger::warn(L"Failed to signal exit event for PowerToys Awake. {}", get_last_error_or_default(GetLastError()));
|
||||||
|
|
||||||
|
// For some reason, we couldn't process the signal correctly, so we still
|
||||||
|
// need to terminate the Awake process.
|
||||||
|
TerminateProcess(p_info.hProcess, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
ResetEvent(exitEvent);
|
||||||
|
CloseHandle(exitEvent);
|
||||||
|
CloseHandle(p_info.hProcess);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_enabled = false;
|
m_enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns if the powertoys is enabled
|
|
||||||
virtual bool is_enabled() override
|
virtual bool is_enabled() override
|
||||||
{
|
{
|
||||||
return m_enabled;
|
return m_enabled;
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels
|
|||||||
OnPropertyChanged(nameof(IsEnabled));
|
OnPropertyChanged(nameof(IsEnabled));
|
||||||
OnPropertyChanged(nameof(IsTimeConfigurationEnabled));
|
OnPropertyChanged(nameof(IsTimeConfigurationEnabled));
|
||||||
|
|
||||||
var outgoing = new OutGoingGeneralSettings(GeneralSettingsConfig);
|
OutGoingGeneralSettings outgoing = new OutGoingGeneralSettings(GeneralSettingsConfig);
|
||||||
SendConfigMSG(outgoing.ToString());
|
SendConfigMSG(outgoing.ToString());
|
||||||
NotifyPropertyChanged();
|
NotifyPropertyChanged();
|
||||||
}
|
}
|
||||||
@@ -143,7 +143,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library.ViewModels
|
|||||||
SndAwakeSettings outsettings = new SndAwakeSettings(Settings);
|
SndAwakeSettings outsettings = new SndAwakeSettings(Settings);
|
||||||
SndModuleSettings<SndAwakeSettings> ipcMessage = new SndModuleSettings<SndAwakeSettings>(outsettings);
|
SndModuleSettings<SndAwakeSettings> ipcMessage = new SndModuleSettings<SndAwakeSettings>(outsettings);
|
||||||
|
|
||||||
var targetMessage = ipcMessage.ToJsonString();
|
string targetMessage = ipcMessage.ToJsonString();
|
||||||
SendConfigMSG(targetMessage);
|
SendConfigMSG(targetMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user