I have two Windows 10 PCs, both running the Fall Creators Update, with all recent patches installed. One wakes up from sleep after a timer is set via CreateWaitableTimer/SetWaitableTimer, the other doesn't...which is a problem, because the non-waking one is my DVR and needs to be able to wake up on demand :).
Neither has hibernation enabled.
I can't see any unusual events on the system which refuses to wake up. It just doesn't wake up, unless I do a manual wakeup or send it a wake-on-lan packet.
Here's the C# test code I'm running on both systems:
public class Program
{
[ DllImport( "kernel32.dll" ) ]
private static extern SafeWaitHandle CreateWaitableTimer( IntPtr lpTimerAttributes, bool bManualReset,
string lpTimerName );
[ DllImport( "kernel32.dll", SetLastError = true ) ]
[ return : MarshalAs( UnmanagedType.Bool ) ]
private static extern bool SetWaitableTimer( SafeWaitHandle hTimer, [ In ] ref long pDueTime, int lPeriod,
IntPtr pfnCompletionRoutine, IntPtr lpArgToCompletionRoutine, bool fResume );
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool CancelWaitableTimer(IntPtr hTimer);
[DllImport("powrprof.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetSuspendState(bool hibernate, bool forceCritical, bool disableWakeEvent);
private static ILogger _logger;
private static bool Hibernate()
{
bool retVal = SetSuspendState(true, false, false);
_logger.Information(retVal
? $"Returning from hibernation at {DateTime.Now.ToLongTimeString()}"
: $"Failed to enter hibernation, error message was {Marshal.GetLastWin32Error()}");
return retVal;
}
private static bool Sleep()
{
bool retVal = SetSuspendState(false, false, false);
_logger.Information( retVal
? $"Returning from sleep at {DateTime.Now.ToLongTimeString()}"
: $"Failed to enter sleep, error message was {Marshal.GetLastWin32Error()}" );
return retVal;
}
private static void SetWakeTimer( int minutes, bool hibernate )
{
DateTime utc = DateTime.Now.AddMinutes( minutes );
long duetime = utc.ToFileTime();
using( SafeWaitHandle handle = CreateWaitableTimer( IntPtr.Zero, true, "SleepWakeTimerTest" ) )
{
if( SetWaitableTimer( handle, ref duetime, 0, IntPtr.Zero, IntPtr.Zero, true ) )
{
_logger.Information($"Timer set, will trigger at {utc.ToLongTimeString()}");
if ( hibernate ) Hibernate();
else Sleep();
}
else
Console.WriteLine($"CreateWaitableTimer failed, error message was {Marshal.GetLastWin32Error()}");
}
}
static void Main( string[] args )
{
_logger = new LoggerConfiguration()
.WriteTo.File( $"log-{DateTime.Now:yyyy-M-d-hhmmss}.txt" )
.CreateLogger();
_logger.Information("parsing command line arguments...");
var cmdLine = new FluentCommandLineParser();
int delay = 2;
bool hibernate = false;
cmdLine.Setup<int>( 'd', "delay" )
.Callback( x => delay = x )
.SetDefault( 2 )
.WithDescription( "wakeup delay, in minutes" );
cmdLine.Setup<bool>( 'h', "hibernate" )
.Callback( x => hibernate = x )
.SetDefault( false )
.WithDescription( "hibernate if flag set, otherwise sleep" );
SetWakeTimer( delay, hibernate );
}
}
Suggestions on what to check or what additional diagnostic steps to take would be much appreciated.
Additional Info
It was suggested that I try waking the computer via a manually-defined scheduled task (i.e., by using the Task Scheduler app). Interestingly, the task did not wake up the computer.