安排机器唤醒

时间:2009-07-17 06:53:00

标签: c# windows-services acpi

以编程方式使Windows XP(或更高版本)计算机在特定时间唤醒的最佳方法是什么。 (理想情况下,Media Center可以自动启动以录制特定的电视节目)

我有一个Windows服务(用C#编写),我希望这项服务能够使托管的机器在预定的时间启动。

是否需要配置任何BIOS设置或先决条件(例如ACPI)才能正常工作?

这台机器将使用拨号或3G无线调制解调器,所以不幸的是它不能依赖局域网唤醒。

4 个答案:

答案 0 :(得分:12)

您可以使用waitable timers从暂停或休眠状态唤醒。根据我的发现,无法以编程方式从正常关闭模式唤醒(软关闭/ S5),在这种情况下,您需要在BIOS中指定WakeOnRTC警报。要使用C#中的等待计时器,您需要pInvoke。进口申报是:

public delegate void TimerCompleteDelegate();

[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr CreateWaitableTimer(IntPtr lpTimerAttributes, bool bManualReset, string lpTimerName);

[DllImport("kernel32.dll", SetLastError = true)]
static extern bool SetWaitableTimer(IntPtr hTimer, [In] ref long pDueTime, int lPeriod, TimerCompleteDelegate pfnCompletionRoutine, IntPtr pArgToCompletionRoutine, bool fResume);

[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool CancelWaitableTimer(IntPtr hTimer);

您可以通过以下方式使用这些功能:

public static IntPtr SetWakeAt(DateTime dt)
{
    TimerCompleteDelegate timerComplete = null;

    // read the manual for SetWaitableTimer to understand how this number is interpreted.
    long interval = dt.ToFileTimeUtc(); 
    IntPtr handle = CreateWaitableTimer(IntPtr.Zero, true, "WaitableTimer");
    SetWaitableTimer(handle, ref interval, 0, timerComplete, IntPtr.Zero, true);
    return handle;
}

然后,您可以使用返回的句柄作为参数取消CancelWaitableTimer的等待计时器。

您的程序可以使用pInvoke休眠和休眠:

[DllImport("powrprof.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetSuspendState(bool hibernate, bool forceCritical, bool disableWakeEvent);

public static bool Hibernate()
{
    return SetSuspendState(true, false, false);
}

public static bool Sleep()
{
    return SetSuspendState(false, false, false);
}

您的系统可能不允许程序让计算机进入休眠状态。您可以调用以下方法来允许休眠:

public static bool EnableHibernate()
{
    Process p = new Process();
    p.StartInfo.FileName = "powercfg.exe";
    p.StartInfo.CreateNoWindow = true;
    p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
    p.StartInfo.Arguments = "/hibernate on"; // this might be different in other locales
    return p.Start();
}

答案 1 :(得分:4)

Win7中的任务调度程序,taskschd.msc(以及我也相信XP)可以设置为在不同的触发器上唤醒系统。这些触发器可以是时间表,时间,事件等。

至少在Win7中,您需要将“允许唤醒定时器”设置为“启用”才能使其正常工作。此设置位于...

- >控制面板\硬件和声音\电源选项
单击 - “编辑计划设置”
单击 - “更改高级电源设置”
扩展 - “睡眠”
展开 - “允许唤醒定时器”

答案 2 :(得分:1)

您最好的选择是使用Wake on LAN功能。这将需要另一台机器发送一个特殊类型的数据包来唤醒你的机器。

如果您的机器未连接到网络或由于某种原因您不能将此逻辑移动到另一台计算机上,这将没有用。但是对于有多台机器且想要以编程方式唤醒它们的某些配置它很有用。

答案 3 :(得分:0)

某些机器有一个BIOS闹钟,可以设置为在某个小时唤醒计算机。应该可以对这个时钟进行编程,但我不知道具体的细节。

修改:我发现这个program可以让您设置时间。它在C语言下,在Linux下,但也许它可以给你一些提示。

警告但是:在尝试直接更改BIOS设置的任何内容之前,请务必从BIOS屏幕中记下每个设置,因为如果出现错误,BIOS可能会恢复为出厂默认设置,您可能需要重新设置它。