在做一个如标题的程序,参考了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的文档应该是支持唤醒的,如图:
#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(¤tTime);
FILETIME fileTime;
SystemTimeToFileTime(¤tTime, &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和固件设置中是否允许唤醒,是否有相关的定时唤醒设置等等。
如果我的回答解决了您的问题,请采纳!