simulate "Wake up computer to run this task" feature of taskscheduler in C#

R

Rahul

Hello,

Is it possible (by code) to set a timer and "force" the computer to
wake up from hibernation/standby/sleep mode (either at specific
time... or after specific interval) through C# code?

Please let me know about any possible solutions/ideas you may have.

Thanks,

Rahul
 
P

Peter Duniho

Is it possible (by code) to set a timer and "force" the computer to
wake up from hibernation/standby/sleep mode (either at specific
time... or after specific interval) through C# code?

Please let me know about any possible solutions/ideas you may have.

Some BIOS's do in fact support timer-based wake-ups, but as far as I know
there's no Windows API support for setting that (of course it would have
to be set while the computer is awake, since when it's suspended --
hibernating or just on standby -- no code is executed).

If it does exist, I would expect to find it in something related to ACPI,
probably in the WMI classes. Unfortunately, I don't use WMI and so don't
really know what the best way for finding specific WMI support in the docs
is (all I can find is the general purpose "System.Management" namespace,
with various abstract classes and APIs for accessing objects that I don't
find documented).

Pete
 
W

Willy Denoyette [MVP]

Rahul said:
Hello,

Is it possible (by code) to set a timer and "force" the computer to
wake up from hibernation/standby/sleep mode (either at specific
time... or after specific interval) through C# code?

Please let me know about any possible solutions/ideas you may have.

Thanks,

Rahul



Nothing in the framework, so you'll have to "PInvoke" a bit.
The API's you need to call are CreateWaitableTimer and SetWaitableTimer.
Following is a complete (Q&D) sample that illustrates how you can set a
system to be awoken from sleep/hibernate using above Win32 API's.
Note that here I'm setting a relative wakeup time of 300000000 nSecs.
That means that the computer will wake-up (supposing he's asleep or
hibernating) within 30 seconds after setting the timer.
Consult the MSDN docs for details on SetWaitableTimer and it's arguments.


using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Threading;
namespace Willys
{
class Program
{
[DllImport("kernel32.dll")]
public static extern IntPtr CreateWaitableTimer(IntPtr
lpTimerAttributes,
bool bManualReset, string lpTimerName);

[DllImport("kernel32.dll")]
public static extern bool SetWaitableTimer(IntPtr hTimer, [In] ref long
pDueTime, int lPeriod, IntPtr pfnCompletionRoutine, IntPtr
lpArgToCompletionRoutine, bool fResume);

[DllImport("kernel32", SetLastError = true, ExactSpelling = true)]
public static extern Int32 WaitForSingleObject(IntPtr handle, uint
milliseconds);

static void Main()
{
SetWaitForWakeUpTime();
}

static IntPtr handle;
static void SetWaitForWakeUpTime()
{
long duetime = -300000000; // negative value, so a RELATIVE
due time
handle = CreateWaitableTimer(IntPtr.Zero, true,
"MyWaitabletimer");
SetWaitableTimer(handle, ref duetime, 0, IntPtr.Zero,
IntPtr.Zero, true);
long duetime = -300000000;
Console.WriteLine("{0:x}",duetime);
handle = CreateWaitableTimer(IntPtr.Zero, true,
"MyWaitabletimer");
SetWaitableTimer(handle, ref duetime, 0, IntPtr.Zero,
IntPtr.Zero, true);
uint INFINITE = 0xFFFFFFFF;
int ret = WaitForSingleObject(handle, INFINITE);
MessageBox.Show("Wake up call");
}

}


Willy.
 
W

Willy Denoyette [MVP]

Willy Denoyette said:
Rahul said:
Hello,

Is it possible (by code) to set a timer and "force" the computer to
wake up from hibernation/standby/sleep mode (either at specific
time... or after specific interval) through C# code?

Please let me know about any possible solutions/ideas you may have.

Thanks,

Rahul



Nothing in the framework, so you'll have to "PInvoke" a bit.
The API's you need to call are CreateWaitableTimer and SetWaitableTimer.
Following is a complete (Q&D) sample that illustrates how you can set a
system to be awoken from sleep/hibernate using above Win32 API's.
Note that here I'm setting a relative wakeup time of 300000000 nSecs.
That means that the computer will wake-up (supposing he's asleep or
hibernating) within 30 seconds after setting the timer.
Consult the MSDN docs for details on SetWaitableTimer and it's arguments.


using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Threading;
namespace Willys
{
class Program
{
[DllImport("kernel32.dll")]
public static extern IntPtr CreateWaitableTimer(IntPtr
lpTimerAttributes,
bool bManualReset, string lpTimerName);

[DllImport("kernel32.dll")]
public static extern bool SetWaitableTimer(IntPtr hTimer, [In] ref long
pDueTime, int lPeriod, IntPtr pfnCompletionRoutine, IntPtr
lpArgToCompletionRoutine, bool fResume);

[DllImport("kernel32", SetLastError = true, ExactSpelling = true)]
public static extern Int32 WaitForSingleObject(IntPtr handle, uint
milliseconds);

static void Main()
{
SetWaitForWakeUpTime();
}

static IntPtr handle;
static void SetWaitForWakeUpTime()
{
long duetime = -300000000; // negative value, so a RELATIVE
due time
handle = CreateWaitableTimer(IntPtr.Zero, true,
"MyWaitabletimer");
SetWaitableTimer(handle, ref duetime, 0, IntPtr.Zero,
IntPtr.Zero, true);
long duetime = -300000000;
Console.WriteLine("{0:x}",duetime);
handle = CreateWaitableTimer(IntPtr.Zero, true,
"MyWaitabletimer");
SetWaitableTimer(handle, ref duetime, 0, IntPtr.Zero,
IntPtr.Zero, true);
uint INFINITE = 0xFFFFFFFF;
int ret = WaitForSingleObject(handle, INFINITE);
MessageBox.Show("Wake up call");
}

}


Willy.



Or using EventWaitHandle and V2's SafeWaitHandle ...

class Program
{
[DllImport("kernel32.dll")]
public static extern SafeWaitHandle CreateWaitableTimer(IntPtr
lpTimerAttributes,
bool bManualReset, string lpTimerName);

[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetWaitableTimer(SafeWaitHandle hTimer, [In]
ref long
pDueTime, int lPeriod, IntPtr pfnCompletionRoutine, IntPtr
lpArgToCompletionRoutine, bool fResume);

....

static void SetWaitForWakeUpTime()
{
DateTime utc = new DateTime(2008, 3, 16, 22, 53, 00,
DateTimeKind.Utc);
long duetime = utc.ToFileTime();
using(SafeWaitHandle handle = CreateWaitableTimer(IntPtr.Zero,
true, "MyWaitabletimer"))
{
if(SetWaitableTimer(handle, ref duetime, 0, IntPtr.Zero,
IntPtr.Zero, true))
{
using(EventWaitHandle wh = new EventWaitHandle(false,
EventResetMode.AutoReset))
{
wh.SafeWaitHandle = handle;
wh.WaitOne();
}
}
else
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
MessageBox.Show("Wake up call");
}


Willy.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top