mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 11:48:06 +01:00
Awake Updates - TILLSON_11272024 (#36049)
* Update with bug fixes for tray icon and support for parent process * Process information enum * Update the docs * Fix spelling * Make sure that PID is used in PT config flow * Logic for checks based on #34148 * Update with link to PR * Fixes #34717 * Small cleanup * Proper task segmentation in a function * Cleanup the code * Fix synchronization context issue * Update planning doc * Test disabling caching to see if that manages to pass CI * Cleanup to make sure that we're logging things properly. * Update ci.yml * Disable cache to pass CI * Retry logic * Cleanup * Code cleanup * Fixes #35848 * Update notes and codename * After third attempt, log error instead of throwing exception * More cleanup to avoid double execution * Add expected word * Safeguards for bad values for timed keep-awake * More updates to make sure I am using uint * Update error message * Update packages * Fix notice and revert CsWinRT upgrade * Codename update * Update expect.txt * Update the struct * Ensuring we're properly awaiting tray initialization * Update to make sure tray reflects the bound process * Cleanup, proper JSON serialization for logs. * Not needed. * Add command validation logic * Moving the initialization logic earlier * Make sure we show the display state in the tooltip * Update tray string * Update src/modules/awake/Awake/Core/Manager.cs Co-authored-by: Jaime Bernardo <jaime@janeasystems.com> * Update src/modules/awake/Awake/Core/Manager.cs Co-authored-by: Jaime Bernardo <jaime@janeasystems.com> * Update src/modules/awake/Awake/Core/Manager.cs Co-authored-by: Jaime Bernardo <jaime@janeasystems.com> * Update src/modules/awake/Awake/Core/Manager.cs Co-authored-by: Jaime Bernardo <jaime@janeasystems.com> * Update logic for icon resets * Update doc * Simplify function for setting mode shell icon * Issues should be properly linked * Minor cleanup * Update timed behavior --------- Co-authored-by: Jaime Bernardo <jaime@janeasystems.com> Co-authored-by: Clint Rutkas <clint@rutkas.com>
This commit is contained in:
@@ -4,8 +4,8 @@
|
||||
|
||||
using System;
|
||||
using System.CommandLine;
|
||||
using System.CommandLine.Parsing;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
@@ -15,7 +15,6 @@ using System.Reflection;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Awake.Core;
|
||||
using Awake.Core.Models;
|
||||
using Awake.Core.Native;
|
||||
@@ -28,33 +27,34 @@ namespace Awake
|
||||
{
|
||||
internal sealed class Program
|
||||
{
|
||||
private static Mutex? _mutex;
|
||||
private static readonly string[] _aliasesConfigOption = ["--use-pt-config", "-c"];
|
||||
private static readonly string[] _aliasesDisplayOption = ["--display-on", "-d"];
|
||||
private static readonly string[] _aliasesTimeOption = ["--time-limit", "-t"];
|
||||
private static readonly string[] _aliasesPidOption = ["--pid", "-p"];
|
||||
private static readonly string[] _aliasesExpireAtOption = ["--expire-at", "-e"];
|
||||
private static readonly string[] _aliasesParentPidOption = ["--use-parent-pid", "-u"];
|
||||
|
||||
private static readonly JsonSerializerOptions _serializerOptions = new() { IncludeFields = true };
|
||||
private static readonly ETWTrace _etwTrace = new();
|
||||
|
||||
private static FileSystemWatcher? _watcher;
|
||||
private static SettingsUtils? _settingsUtils;
|
||||
private static ETWTrace _etwTrace = new ETWTrace();
|
||||
|
||||
private static bool _startedFromPowerToys;
|
||||
|
||||
public static Mutex? LockMutex { get => _mutex; set => _mutex = value; }
|
||||
public static Mutex? LockMutex { get; set; }
|
||||
|
||||
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
||||
private static ConsoleEventHandler _handler;
|
||||
private static SystemPowerCapabilities _powerCapabilities;
|
||||
#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
||||
|
||||
internal static readonly string[] AliasesConfigOption = ["--use-pt-config", "-c"];
|
||||
internal static readonly string[] AliasesDisplayOption = ["--display-on", "-d"];
|
||||
internal static readonly string[] AliasesTimeOption = ["--time-limit", "-t"];
|
||||
internal static readonly string[] AliasesPidOption = ["--pid", "-p"];
|
||||
internal static readonly string[] AliasesExpireAtOption = ["--expire-at", "-e"];
|
||||
internal static readonly string[] AliasesParentPidOption = ["--use-parent-pid", "-u"];
|
||||
|
||||
private static readonly Icon _defaultAwakeIcon = new(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Assets/Awake/awake.ico"));
|
||||
|
||||
private static int Main(string[] args)
|
||||
private static async Task<int> Main(string[] args)
|
||||
{
|
||||
_settingsUtils = new SettingsUtils();
|
||||
|
||||
LockMutex = new Mutex(true, Core.Constants.AppName, out bool instantiated);
|
||||
|
||||
Logger.InitializeLogger(Path.Combine("\\", Core.Constants.AppName, "Logs"));
|
||||
|
||||
try
|
||||
@@ -62,7 +62,7 @@ namespace Awake
|
||||
string appLanguage = LanguageHelper.LoadLanguage();
|
||||
if (!string.IsNullOrEmpty(appLanguage))
|
||||
{
|
||||
System.Threading.Thread.CurrentThread.CurrentUICulture = new CultureInfo(appLanguage);
|
||||
Thread.CurrentThread.CurrentUICulture = new CultureInfo(appLanguage);
|
||||
}
|
||||
}
|
||||
catch (CultureNotFoundException ex)
|
||||
@@ -70,6 +70,8 @@ namespace Awake
|
||||
Logger.LogError("CultureNotFoundException: " + ex.Message);
|
||||
}
|
||||
|
||||
await TrayHelper.InitializeTray(TrayHelper.DefaultAwakeIcon, Core.Constants.FullAppName);
|
||||
AppDomain.CurrentDomain.ProcessExit += (_, _) => TrayHelper.RunOnMainThread(() => LockMutex?.ReleaseMutex());
|
||||
AppDomain.CurrentDomain.UnhandledException += AwakeUnhandledExceptionCatcher;
|
||||
|
||||
if (!instantiated)
|
||||
@@ -103,46 +105,76 @@ namespace Awake
|
||||
// To make it easier to diagnose future issues, let's get the
|
||||
// system power capabilities and aggregate them in the log.
|
||||
Bridge.GetPwrCapabilities(out _powerCapabilities);
|
||||
Logger.LogInfo(JsonSerializer.Serialize(_powerCapabilities));
|
||||
Logger.LogInfo(JsonSerializer.Serialize(_powerCapabilities, _serializerOptions));
|
||||
|
||||
Logger.LogInfo("Parsing parameters...");
|
||||
|
||||
var configOption = new Option<bool>(AliasesConfigOption, () => false, Resources.AWAKE_CMD_HELP_CONFIG_OPTION)
|
||||
Option<bool> configOption = new(_aliasesConfigOption, () => false, Resources.AWAKE_CMD_HELP_CONFIG_OPTION)
|
||||
{
|
||||
Arity = ArgumentArity.ZeroOrOne,
|
||||
IsRequired = false,
|
||||
};
|
||||
|
||||
var displayOption = new Option<bool>(AliasesDisplayOption, () => true, Resources.AWAKE_CMD_HELP_DISPLAY_OPTION)
|
||||
Option<bool> displayOption = new(_aliasesDisplayOption, () => true, Resources.AWAKE_CMD_HELP_DISPLAY_OPTION)
|
||||
{
|
||||
Arity = ArgumentArity.ZeroOrOne,
|
||||
IsRequired = false,
|
||||
};
|
||||
|
||||
var timeOption = new Option<uint>(AliasesTimeOption, () => 0, Resources.AWAKE_CMD_HELP_TIME_OPTION)
|
||||
Option<uint> timeOption = new(_aliasesTimeOption, () => 0, Resources.AWAKE_CMD_HELP_TIME_OPTION)
|
||||
{
|
||||
Arity = ArgumentArity.ExactlyOne,
|
||||
IsRequired = false,
|
||||
};
|
||||
|
||||
var pidOption = new Option<int>(AliasesPidOption, () => 0, Resources.AWAKE_CMD_HELP_PID_OPTION)
|
||||
Option<int> pidOption = new(_aliasesPidOption, () => 0, Resources.AWAKE_CMD_HELP_PID_OPTION)
|
||||
{
|
||||
Arity = ArgumentArity.ZeroOrOne,
|
||||
IsRequired = false,
|
||||
};
|
||||
|
||||
var expireAtOption = new Option<string>(AliasesExpireAtOption, () => string.Empty, Resources.AWAKE_CMD_HELP_EXPIRE_AT_OPTION)
|
||||
Option<string> expireAtOption = new(_aliasesExpireAtOption, () => string.Empty, Resources.AWAKE_CMD_HELP_EXPIRE_AT_OPTION)
|
||||
{
|
||||
Arity = ArgumentArity.ZeroOrOne,
|
||||
IsRequired = false,
|
||||
};
|
||||
|
||||
var parentPidOption = new Option<bool>(AliasesParentPidOption, () => false, Resources.AWAKE_CMD_PARENT_PID_OPTION)
|
||||
Option<bool> parentPidOption = new(_aliasesParentPidOption, () => false, Resources.AWAKE_CMD_PARENT_PID_OPTION)
|
||||
{
|
||||
Arity = ArgumentArity.ZeroOrOne,
|
||||
IsRequired = false,
|
||||
};
|
||||
|
||||
timeOption.AddValidator(result =>
|
||||
{
|
||||
if (result.Tokens.Count != 0 && !uint.TryParse(result.Tokens[0].Value, out _))
|
||||
{
|
||||
string errorMessage = $"Interval in --time-limit could not be parsed correctly. Check that the value is valid and doesn't exceed 4,294,967,295. Value used: {result.Tokens[0].Value}.";
|
||||
Logger.LogError(errorMessage);
|
||||
result.ErrorMessage = errorMessage;
|
||||
}
|
||||
});
|
||||
|
||||
pidOption.AddValidator(result =>
|
||||
{
|
||||
if (result.Tokens.Count != 0 && !int.TryParse(result.Tokens[0].Value, out _))
|
||||
{
|
||||
string errorMessage = $"PID value in --pid could not be parsed correctly. Check that the value is valid and falls within the boundaries of Windows PID process limits. Value used: {result.Tokens[0].Value}.";
|
||||
Logger.LogError(errorMessage);
|
||||
result.ErrorMessage = errorMessage;
|
||||
}
|
||||
});
|
||||
|
||||
expireAtOption.AddValidator(result =>
|
||||
{
|
||||
if (result.Tokens.Count != 0 && !DateTimeOffset.TryParse(result.Tokens[0].Value, out _))
|
||||
{
|
||||
string errorMessage = $"Date and time value in --expire-at could not be parsed correctly. Check that the value is valid date and time. Refer to https://aka.ms/powertoys/awake for format examples. Value used: {result.Tokens[0].Value}.";
|
||||
Logger.LogError(errorMessage);
|
||||
result.ErrorMessage = errorMessage;
|
||||
}
|
||||
});
|
||||
|
||||
RootCommand? rootCommand =
|
||||
[
|
||||
configOption,
|
||||
@@ -207,9 +239,7 @@ namespace Awake
|
||||
// Start the monitor thread that will be used to track the current state.
|
||||
Manager.StartMonitor();
|
||||
|
||||
TrayHelper.InitializeTray(_defaultAwakeIcon, Core.Constants.FullAppName);
|
||||
|
||||
var eventHandle = new EventWaitHandle(false, EventResetMode.ManualReset, PowerToys.Interop.Constants.AwakeExitEvent());
|
||||
EventWaitHandle eventHandle = new(false, EventResetMode.ManualReset, PowerToys.Interop.Constants.AwakeExitEvent());
|
||||
new Thread(() =>
|
||||
{
|
||||
WaitHandle.WaitAny([eventHandle]);
|
||||
@@ -219,7 +249,8 @@ namespace Awake
|
||||
if (usePtConfig)
|
||||
{
|
||||
// Configuration file is used, therefore we disregard any other command-line parameter
|
||||
// and instead watch for changes in the file.
|
||||
// and instead watch for changes in the file. This is used as a priority against all other arguments,
|
||||
// so if --use-pt-config is applied the rest of the arguments are irrelevant.
|
||||
Manager.IsUsingPowerToysConfig = true;
|
||||
|
||||
try
|
||||
@@ -259,13 +290,14 @@ namespace Awake
|
||||
// Second, we snap to process-based execution. Because this is something that
|
||||
// is snapped to a running entity, we only want to enable the ability to set
|
||||
// indefinite keep-awake with the display settings that the user wants to set.
|
||||
// In this context, manual (explicit) PID takes precedence over parent PID.
|
||||
int targetPid = pid != 0 ? pid : useParentPid ? Manager.GetParentProcess()?.Id ?? 0 : 0;
|
||||
|
||||
if (targetPid != 0)
|
||||
{
|
||||
Logger.LogInfo($"Bound to target process: {targetPid}");
|
||||
|
||||
Manager.SetIndefiniteKeepAwake(displayOn);
|
||||
Manager.SetIndefiniteKeepAwake(displayOn, targetPid);
|
||||
|
||||
RunnerHelper.WaitForPowerToysRunner(targetPid, () =>
|
||||
{
|
||||
@@ -338,8 +370,8 @@ namespace Awake
|
||||
|
||||
private static void SetupFileSystemWatcher(string settingsPath)
|
||||
{
|
||||
var directory = Path.GetDirectoryName(settingsPath)!;
|
||||
var fileName = Path.GetFileName(settingsPath);
|
||||
string directory = Path.GetDirectoryName(settingsPath)!;
|
||||
string fileName = Path.GetFileName(settingsPath);
|
||||
|
||||
_watcher = new FileSystemWatcher
|
||||
{
|
||||
@@ -364,7 +396,7 @@ namespace Awake
|
||||
|
||||
private static void InitializeSettings()
|
||||
{
|
||||
var settings = Manager.ModuleSettings?.GetSettings<AwakeSettings>(Core.Constants.AppName) ?? new AwakeSettings();
|
||||
AwakeSettings settings = Manager.ModuleSettings?.GetSettings<AwakeSettings>(Core.Constants.AppName) ?? new AwakeSettings();
|
||||
TrayHelper.SetTray(settings, _startedFromPowerToys);
|
||||
}
|
||||
|
||||
@@ -385,7 +417,7 @@ namespace Awake
|
||||
{
|
||||
try
|
||||
{
|
||||
var settings = _settingsUtils!.GetSettings<AwakeSettings>(Core.Constants.AppName)
|
||||
AwakeSettings settings = _settingsUtils!.GetSettings<AwakeSettings>(Core.Constants.AppName)
|
||||
?? throw new InvalidOperationException("Settings are null.");
|
||||
|
||||
Logger.LogInfo($"Identified custom time shortcuts for the tray: {settings.Properties.CustomTrayTimes.Count}");
|
||||
|
||||
Reference in New Issue
Block a user