using System; using System.Runtime.InteropServices; using Microsoft.Win32.SafeHandles; using System.Threading; using System.ComponentModel;namespace ConsoleApplication1 { 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 Main(string[] args) { SetWaitForWakeUpTime(); } static void SetWaitForWakeUpTime() { // 定时器时间 DateTime utc = DateTime.Now.AddMinutes(1); 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()); } } // You could make it a recursive call here, setting it to 1 hours time or similar Console.WriteLine("Wake up call"); Console.ReadLine(); } } }用CreateWaitableTimer创建内核对象的定时器,上面这个例子是休眠状态下的唤醒功能,改改应该就能用了
用通知(Notify)功能来模拟Timer:利用CeSetUserNotificationEx
private static extern void SystemIdleTimerReset(); private static int nDisableSleepCalls = 0;
private static System.Threading.Timer preventSleepTimer = null; private static void PokeDeviceToKeepAwake(object extra)
{
try
{
SystemIdleTimerReset();
}
catch (Exception e)
{
// TODO
}
}
/**//// <summary>
/// 禁止设备自动关闭电源
/// </summary>
public static void DisableDeviceSleep()
{
nDisableSleepCalls++;
if (nDisableSleepCalls == 1)
{
//Debug.Assert(preventSleepTimer == null);
// 没隔30秒刷新一次计时器
preventSleepTimer = new System.Threading.Timer(new System.Threading.TimerCallback (PokeDeviceToKeepAwake),
null, 0, 30 * 1000);
}
}
/**//// <summary>
/// 允许设备自动关闭电源
/// </summary>
public static void EnableDeviceSleep()
{
nDisableSleepCalls--;
if (nDisableSleepCalls == 0)
{
//Debug.Assert(preventSleepTimer != null);
if (preventSleepTimer != null)
{
preventSleepTimer.Dispose();
preventSleepTimer = null;
}
}
} 在定时开始时调用DisableDeviceSleep方法就OK了。
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
using System.Threading;
using System.ComponentModel;namespace ConsoleApplication1 {
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 Main(string[] args) {
SetWaitForWakeUpTime();
} static void SetWaitForWakeUpTime() {
// 定时器时间
DateTime utc = DateTime.Now.AddMinutes(1);
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());
}
} // You could make it a recursive call here, setting it to 1 hours time or similar
Console.WriteLine("Wake up call");
Console.ReadLine();
}
}
}用CreateWaitableTimer创建内核对象的定时器,上面这个例子是休眠状态下的唤醒功能,改改应该就能用了
这个方法我测试过,是可以的,楼主到哪一步出的错误呢如果待机,电源进入非正常供电状态,目前没有一个软件是可以继续运行的,因为没有电方法就是我说的那种,把关闭电源禁止掉,DisableDeviceSleep