使用C++编写程序让系统进入睡眠后然后10秒后自动唤醒

在做一个如标题的程序,参考了Windows的API感觉有可行性,通过SetSuspendState 函数让系统睡眠,https://learn.microsoft.com/zh-cn/windows/win32/api/powrprof/nf-powrprof-setsuspendstate
然后参考Windows的API的系统唤醒事件https://learn.microsoft.com/zh-cn/windows/win32/power/system-wake-up-events
编写了如下程序,然而在系统睡眠后程序也不跑手动唤醒后才继续执行,有什么解决方法?
看Windows的文档应该是支持唤醒的,如图:

img

img

img


#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <stdio.h>
#include <powrprof.h>
#include <time.h>
#include <iostream>
#pragma comment(lib, "PowrProf.lib")

void Time()
{
    time_t timep;
    time(&timep);
    char tmp[64];
    strftime(tmp, sizeof(tmp), "%Y-%m-%d %H:%M:%S", localtime(&timep));
    std::cout << "currentTime is " << tmp << "." << std::endl;
}

int main()
{
    // 创建一个可等待的计时器对象
    HANDLE hTimer = CreateWaitableTimer(NULL, FALSE, NULL);
    if (hTimer == NULL)
    {
        printf("CreateWaitableTimer failed (%d)\n", GetLastError());
        return 1;
    }
    else {
        std::cout << "CreateWaitableTimer ";
        Time();
    }
    // 设置计时器为10秒后触发,并指定系统应唤醒
    LARGE_INTEGER liDueTime;
    liDueTime.QuadPart = -100000000LL; // 10秒
    if (!SetWaitableTimer(hTimer, &liDueTime, 0, NULL, NULL, TRUE))
    {
        printf("SetWaitableTimer failed (%d)\n", GetLastError());
        return 2;
    }
    else
    {
        std::cout << "SetWaitableTimer ";
        Time();
    }
        
    // 让系统进入睡眠状态
    std::cout << "SetSuspendState ";
    Time();
    SetSuspendState(FALSE, FALSE, FALSE);

    // 等待计时器信号
    if (WaitForSingleObject(hTimer, INFINITE) != WAIT_OBJECT_0)
    {
        printf("WaitForSingleObject failed (%d)\n", GetLastError());
        return 3;
    }
    else
    {
        std::cout << "WaitForSingleObjectl ";
        Time();

    }
        
    // 关闭计时器对象
    CloseHandle(hTimer);
    std::cout << "woken up ";
    Time();
    printf("The system has been woken up.\n");
    system("pause");
    return 0;
}

AI生成的请先验证能够正常使用,我这边尝试过GPT,newBing几个不同的AI均不能够实现目的。拒绝直接复制AI的答案。


#include <iostream>
#include <Windows.h>
#include <PowrProf.h>

#pragma comment(lib, "PowrProf.lib")

int main()
{
    // 让系统进入睡眠
    SetSuspendState(FALSE, TRUE, FALSE);

    // 注册系统唤醒事件
    HANDLE hWakeUpEvent = CreateEvent(NULL, FALSE, FALSE, L"MyWakeUpEvent");
    if (hWakeUpEvent == NULL)
    {
        std::cout << "CreateEvent failed: " << GetLastError() << std::endl;
        return 1;
    }

    // 设定唤醒时间
    SYSTEMTIME currentTime;
    GetSystemTime(&currentTime);
    FILETIME fileTime;
    SystemTimeToFileTime(&currentTime, &fileTime);
    ULARGE_INTEGER currentTimeLarge;
    currentTimeLarge.LowPart = fileTime.dwLowDateTime;
    currentTimeLarge.HighPart = fileTime.dwHighDateTime;
    ULARGE_INTEGER wakeUpTimeLarge;
    wakeUpTimeLarge.QuadPart = currentTimeLarge.QuadPart + 10000000; // 延迟10秒钟唤醒
    fileTime.dwLowDateTime = wakeUpTimeLarge.LowPart;
    fileTime.dwHighDateTime = wakeUpTimeLarge.HighPart;

    // 设置唤醒时间
    int result = SetWaitableTimer(hWakeUpEvent, (LARGE_INTEGER*)&fileTime, 0, NULL, NULL, FALSE);
    if (result == 0)
    {
        std::cout << "SetWaitableTimer failed: " << GetLastError() << std::endl;
        CloseHandle(hWakeUpEvent);
        return 1;
    }

    // 进入等待状态,等待系统唤醒事件的发生
    DWORD waitResult = WaitForSingleObject(hWakeUpEvent, INFINITE);
    if (waitResult != WAIT_OBJECT_0)
    {
        std::cout << "WaitForSingleObject failed: " << GetLastError() << std::endl;
        CloseHandle(hWakeUpEvent);
        return 1;
    }

    // 处理唤醒事件
    std::cout << "System is awake." << std::endl;

    CloseHandle(hWakeUpEvent);

    return 0;
}

以下是一个使用 C++ 编写程序让系统进入睡眠后然后 10 秒后自动唤醒的示例代码:

#include <Windows.h>
#include <powrprof.h>
#include <thread>

#pragma comment(lib, "Powrprof.lib")

int main() {
    // 调用 SetSuspendState 函数使系统进入睡眠状态
    SetSuspendState(FALSE, FALSE, FALSE);  // FALSE 表示不立即进入睡眠模式,而是等待系统自动进入

    // 使用 std::thread 延时 10 秒
    std::thread delay([&]() {
        std::this_thread::sleep_for(std::chrono::seconds(10));
        });

    // 等待 delay 线程执行完毕,然后唤醒系统
    delay.join();  // 等待延时线程执行完毕
    SetSuspendState(FALSE, TRUE, FALSE);  // TRUE 表示立即进入睡眠模式

    return 0;
}

首先在程序中使用 SetSuspendState() 函数使系统进入睡眠状态。其中第一个参数 FALSE 表示不立即进入睡眠模式,而是等待系统自动进入;第二个参数 FALSE 表示系统进入睡眠模式后不休眠,而是保持唤醒。然后使用 std::thread 类型的延时函数 sleep_for() 延时 10 秒,再次调用 SetSuspendState() 函数,将第二个参数设为 TRUE,表示立即进入睡眠模式。最后在程序结束前,join() 主线程和延时线程,确保延时线程执行完毕再结束程序。

需要注意的是,SetSuspendState() 函数需要使用 Powrprof.h 头文件,并且需要与 Powrprof.lib 库文件链接。

你的程序没啥问题, 问题是唤醒需要一分钟以上, 设定时间再短, 也要一分钟, 这是我测试的结果.

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
其中一个可能问题是在运行程序时,需要管理员权限才能让程序正常进入睡眠状态。可以尝试以管理员身份运行程序,或者在代码中添加获取管理员权限的相关代码。

另外,参考Windows API文档中的说明,可能需要在操作系统的硬件、BIOS、固件等方面进行设置,才能够保证成功唤醒系统。可以尝试在操作系统设置中检查相关的配置选项,确认其是否符合要求。

以下是修改后的代码,其中添加了获取管理员权限的相关代码:

#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <stdio.h>
#include <powrprof.h>
#include <time.h>
#include <iostream>
#pragma comment(lib, "PowrProf.lib")

void Time()
{
    time_t timep;
    time(&timep);
    char tmp[64];
    strftime(tmp, sizeof(tmp), "%Y-%m-%d %H:%M:%S", localtime(&timep));
    std::cout << "currentTime is " << tmp << "." << std::endl;
}

bool IsElevated()
{
    BOOL fIsElevated = FALSE;
    HANDLE hToken = NULL;
    if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
    {
        TOKEN_ELEVATION elevation = { 0 };
        DWORD cbSize = sizeof(TOKEN_ELEVATION);
        if (GetTokenInformation(hToken, TokenElevation, &elevation, sizeof(elevation), &cbSize))
        {
            fIsElevated = elevation.TokenIsElevated;
        }
    }
    if (hToken)
    {
        CloseHandle(hToken);
    }
    return fIsElevated;
}

int main()
{
    if (!IsElevated())
    {
        printf("The program must be run as an administrator.\n");
        system("pause");
        return 1;
    }

    // 创建一个可等待的计时器对象
    HANDLE hTimer = CreateWaitableTimer(NULL, FALSE, NULL);
    if (hTimer == NULL)
    {
        printf("CreateWaitableTimer failed (%d)\n", GetLastError());
        return 2;
    }
    else 
    {
        std::cout << "CreateWaitableTimer ";
        Time();
    }

    // 设置计时器为10秒后触发,并指定系统应唤醒
    LARGE_INTEGER liDueTime;
    liDueTime.QuadPart = -100000000LL; // 10秒
    if (!SetWaitableTimer(hTimer, &liDueTime, 0, NULL, NULL, TRUE))
    {
        printf("SetWaitableTimer failed (%d)\n", GetLastError());
        return 3;
    }
    else
    {
        std::cout << "SetWaitableTimer ";
        Time();
    }

    // 让系统进入睡眠状态
    std::cout << "SetSuspendState ";
    Time();
    SetSuspendState(FALSE, FALSE, FALSE);

    // 等待计时器信号
    if (WaitForSingleObject(hTimer, INFINITE) != WAIT_OBJECT_0)
    {
        printf("WaitForSingleObject failed (%d)\n", GetLastError());
        return 4;
    }
    else
    {
        std::cout << "WaitForSingleObjectl ";
        Time();
    }

    // 关闭计时器对象
    CloseHandle(hTimer);
    std::cout << "woken up ";
    Time();
    printf("The system has been woken up.\n");
    system("pause");
    return 0;
}

建议在运行之前从设置中检查相关的配置选项是否符合要求,比如在BIOS和固件设置中是否允许唤醒,是否有相关的定时唤醒设置等等。
如果我的回答解决了您的问题,请采纳!