mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-10 21:41:51 +02:00
Proper threading support for all parts of the keep-awake process
This commit is contained in:
@@ -78,21 +78,14 @@ namespace Espresso.Shell.Core
|
|||||||
return SetAwakeState(EXECUTION_STATE.ES_CONTINUOUS);
|
return SetAwakeState(EXECUTION_STATE.ES_CONTINUOUS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public static void SetIndefiniteKeepAwake(Action<bool> callback, Action failureCallback, bool keepDisplayOn = true)
|
||||||
/// Sets up the machine to be awake indefinitely.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="keepDisplayOn">Determines whether the display should be kept on while the machine is awake.</param>
|
|
||||||
/// <returns>Status of the attempt. True if successful, false if not.</returns>
|
|
||||||
public static bool SetIndefiniteKeepAwake(bool keepDisplayOn = true)
|
|
||||||
{
|
{
|
||||||
if (keepDisplayOn)
|
_tokenSource = new CancellationTokenSource();
|
||||||
{
|
_threadToken = _tokenSource.Token;
|
||||||
return SetAwakeState(EXECUTION_STATE.ES_SYSTEM_REQUIRED | EXECUTION_STATE.ES_DISPLAY_REQUIRED | EXECUTION_STATE.ES_CONTINUOUS);
|
|
||||||
}
|
Task.Run(() => RunIndefiniteLoop(keepDisplayOn), _threadToken)
|
||||||
else
|
.ContinueWith((result) => callback(result.Result), TaskContinuationOptions.OnlyOnRanToCompletion)
|
||||||
{
|
.ContinueWith((result) => failureCallback, TaskContinuationOptions.NotOnRanToCompletion);
|
||||||
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)
|
||||||
@@ -105,6 +98,45 @@ namespace Espresso.Shell.Core
|
|||||||
.ContinueWith((result) => failureCallback, TaskContinuationOptions.NotOnRanToCompletion);
|
.ContinueWith((result) => failureCallback, TaskContinuationOptions.NotOnRanToCompletion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool RunIndefiniteLoop(bool keepDisplayOn = true)
|
||||||
|
{
|
||||||
|
bool success;
|
||||||
|
if (keepDisplayOn)
|
||||||
|
{
|
||||||
|
success = SetAwakeState(EXECUTION_STATE.ES_SYSTEM_REQUIRED | EXECUTION_STATE.ES_DISPLAY_REQUIRED | EXECUTION_STATE.ES_CONTINUOUS);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
success = SetAwakeState(EXECUTION_STATE.ES_SYSTEM_REQUIRED | EXECUTION_STATE.ES_CONTINUOUS);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
_log.Info("Initiated indefinite keep awake in background thread.");
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (_threadToken.IsCancellationRequested)
|
||||||
|
{
|
||||||
|
_threadToken.ThrowIfCancellationRequested();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_log.Info("Could not successfully set up indefinite keep awake.");
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException ex)
|
||||||
|
{
|
||||||
|
// Task was clearly cancelled.
|
||||||
|
_log.Info($"Background thread termination. Message: {ex.Message}");
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static bool RunTimedLoop(long seconds, bool keepDisplayOn = true)
|
private static bool RunTimedLoop(long seconds, bool keepDisplayOn = true)
|
||||||
{
|
{
|
||||||
bool success = false;
|
bool success = false;
|
||||||
|
|||||||
@@ -186,38 +186,29 @@ namespace Espresso.Shell
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var exitSignal = new ManualResetEvent(false);
|
||||||
if (pid != 0)
|
if (pid != 0)
|
||||||
{
|
{
|
||||||
RunnerHelper.WaitForPowerToysRunner(pid, () =>
|
RunnerHelper.WaitForPowerToysRunner(pid, () =>
|
||||||
{
|
{
|
||||||
|
exitSignal.Set();
|
||||||
Environment.Exit(0);
|
Environment.Exit(0);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
new ManualResetEvent(false).WaitOne();
|
exitSignal.WaitOne();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void SetupIndefiniteKeepAwake(bool displayOn)
|
private static void SetupIndefiniteKeepAwake(bool displayOn)
|
||||||
{
|
{
|
||||||
// Indefinite keep awake.
|
// Indefinite keep awake.
|
||||||
bool success = APIHelper.SetIndefiniteKeepAwake(displayOn);
|
APIHelper.SetIndefiniteKeepAwake(LogCompletedKeepAwakeThread, LogUnexpectedOrCancelledKeepAwakeThreadCompletion, displayOn);
|
||||||
if (success)
|
|
||||||
{
|
|
||||||
_log.Info($"Currently in indefinite keep awake. Display always on: {displayOn}");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var errorMessage = "Could not set up the state to be indefinite keep awake.";
|
|
||||||
_log.Info(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();
|
|
||||||
ProcessSettings();
|
ProcessSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,34 +268,19 @@ namespace Espresso.Shell
|
|||||||
{
|
{
|
||||||
_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, LogCompletedKeepAwakeThread, LogUnexpectedOrCancelledKeepAwakeThreadCompletion, displayOn);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void LogUnexpectedOrCancelledKeepAwakeCompletion()
|
private static void LogUnexpectedOrCancelledKeepAwakeThreadCompletion()
|
||||||
{
|
{
|
||||||
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 LogCompletedKeepAwakeThread(bool result)
|
||||||
{
|
{
|
||||||
_log.Info($"Completed timed keep-awake successfully: {result}");
|
_log.Info($"Exited keep-awake thread successfully: {result}");
|
||||||
}
|
|
||||||
|
|
||||||
private static void ResetNormalPowerState()
|
|
||||||
{
|
|
||||||
bool success = APIHelper.SetNormalKeepAwake();
|
|
||||||
if (success)
|
|
||||||
{
|
|
||||||
_log.Info("Returned to normal keep-awake state.");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var errorMessage = "Could not return to normal keep-awake state.";
|
|
||||||
_log.Info(errorMessage);
|
|
||||||
_log.Debug(errorMessage);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user