c# - 安排机器唤醒

标签 c# windows-services acpi

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

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

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

这台机器将使用拨号或 3G 无线调制解调器,因此很遗憾它不能依赖 LAN 唤醒。

最佳答案

您可以使用 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 休眠和 sleep :

[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();
}

关于c# - 安排机器唤醒,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1141735/

相关文章:

c# - 无法在 Visual Studio 2015 Community Edition 中打开 Windows Phone 8.1 项目

c# - 单元测试和休眠?

.NET Windows服务需要使用STAThread

c# - 双击启动 Windows 服务

perl - 解析相同语法的不同文件并计算文件之间的相似度

operating-system - 现代操作系统是否使用 MCFG ACPI 表来查找 xHCI 的寄存器?

c# - 通过 DataGridView 使用热键选择上一行和下一行的正确方法

javascript - 使用 Chart.js 创建图表 使用 C# 字符串会导致问题

wcf - 将 IoC 支持添加到 Windows 服务中托管的 WCF 服务 (Autofac)

Linux ACPI 配置