Since I consolidate and backup the photos from all of the devices in my family, I end up with a lot of duplicate files as these photos get shared between people and devices. As part of my backup process, I run de-duplication software across the files to reduce my backup storage needs. This de-duplication process usually takes over 12+ hours to run as it attempts fuzzy/visual matching across 50,000+ files (it’s an older PC).
So, why do I need this utility? Just change the sleep setting to “Never” and the PC will stay awake. Well, the Power & Sleep settings are locked by the Administrator and the PC is set to sleep after 15 minutes. Okay — just sit at the PC and move the mouse every few minutes for 12+ hours? No, thank you.
This Windows utility, which is written in C++, simulates a keypress at a defined interval of time. The keypress event resets the internal Windows idle clock which bypasses the Power & Sleep settings. I’ve programmed the utility to simulate a Win+F14 keypress since that combination is typically unused. There are many variations of this type of utility available, but I wanted to write one myself to meet my exact needs.
While the de-duplication software executes, this utility runs in the background and prevents the PC from going to sleep.
Usage
awake.exe [options] Options: --interval Sets the keypress interval in seconds [default: 300 (5 minutes)] --freq Sets the frequency to check idle time in seconds [default: 1 (1 second)] --nodisplay Hides the console window --settings Displays the current settings at runtime --help Displays usage information
Examples
On the Windows taskbar, I’ve pinned a shortcut to the utility with my preferred options present.
awake.exe --nodisplay
This launches the utility and immediately hides the console window so that the utility isn’t visible (nodisplay). All other options are set to their default values. The utility continues running in the background until the machine is powered down or the application is terminated in the Task Manager.
awake.exe --nodisplay --interval 60
This example behaves the same as the prior example except the interval is reduced to 30 seconds. If the machine is set to sleep after 1 minute in the Power & Sleep settings, this option causes the utility to reset the idle clock every 30 seconds in order to keep the machine awake. The interval option should always be set to a value less than the Sleep setting in Power & Sleep settings.
Source Code
I’ve compiled the code (C++) in Visual Studio 2019 and tested on a Windows 10 machine.
#include <windows.h> #include <iostream> using namespace std; void simulate_win_d_keypress() { INPUT simulated_user_input[4]; ZeroMemory(simulated_user_input, sizeof(simulated_user_input)); simulated_user_input[0].type = INPUT_KEYBOARD; simulated_user_input[0].ki.wVk = VK_LWIN; simulated_user_input[1].type = INPUT_KEYBOARD; simulated_user_input[1].ki.wVk = VK_F14; simulated_user_input[2].type = INPUT_KEYBOARD; simulated_user_input[2].ki.wVk = VK_F14; simulated_user_input[2].ki.dwFlags = KEYEVENTF_KEYUP; simulated_user_input[3].type = INPUT_KEYBOARD; simulated_user_input[3].ki.wVk = VK_LWIN; simulated_user_input[3].ki.dwFlags = KEYEVENTF_KEYUP; SendInput(ARRAYSIZE(simulated_user_input), simulated_user_input, sizeof(INPUT)); } int main(int argc, char* argv[]) { LASTINPUTINFO last_user_input; ULONGLONG idle_time = 0; unsigned int idle_threshold_milliseconds = 1000 * 5; unsigned int frequency_check_milliseconds = 1000; int user_arg_idle_threshold_seconds = 0; int user_arg_frequency_check_seconds = 0; bool b_show_settings = false; bool b_hide_console = false; bool b_arg_issue = false; last_user_input.cbSize = sizeof(last_user_input); for (int i_argv_iterator = 1; i_argv_iterator < argc; i_argv_iterator++) { if (string(argv[i_argv_iterator]) == "--interval") { if ((i_argv_iterator + 1) < argc) { user_arg_idle_threshold_seconds = atoi(argv[i_argv_iterator + 1]); if (user_arg_idle_threshold_seconds <= 0) { b_arg_issue = true; } else { idle_threshold_milliseconds = user_arg_idle_threshold_seconds * 1000; } i_argv_iterator++; } else { b_arg_issue = true; } } else if (string(argv[i_argv_iterator]) == "--freq") { if ((i_argv_iterator + 1) < argc) { user_arg_frequency_check_seconds = atoi(argv[i_argv_iterator + 1]); if (user_arg_frequency_check_seconds <= 0) { b_arg_issue = true; } else { frequency_check_milliseconds = user_arg_frequency_check_seconds * 1000; } i_argv_iterator++; } else { b_arg_issue = true; } } else if (string(argv[i_argv_iterator]) == "--settings") { b_show_settings = true; } else if (string(argv[i_argv_iterator]) == "--nodisplay") { b_hide_console = true; } else if (string(argv[i_argv_iterator]) == "--help") { b_arg_issue = true; } else { b_arg_issue = true; } } if (b_arg_issue) { cout << "Usage:\n"; cout << " awake.exe [options]\n\n"; cout << "Options:\n"; cout << " --interval <integer> Sets the keypress interval in seconds [default: 300 (5 minutes)]\n"; cout << " --freq <integer> Sets the frequency to check idle time in seconds [default: 1 (1 second)]\n"; cout << " --nodisplay Hides the console window\n"; cout << " --settings Displays the current settings at runtime\n"; cout << " --help Displays usage information\n"; return 1; } if (b_show_settings) { cout << "Interval set to "; cout << (idle_threshold_milliseconds / 1000); cout << " second"; cout << (((idle_threshold_milliseconds / 1000) > 1) ? "s" : ""); cout << " with idle check every "; cout << (frequency_check_milliseconds / 1000); cout << " second"; cout << (((frequency_check_milliseconds / 1000) > 1) ? "s" : ""); cout << ".\n"; } if (b_hide_console) { FreeConsole(); } SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED | ES_AWAYMODE_REQUIRED); for (;;) { if (!GetLastInputInfo(&last_user_input)) { return 1; } idle_time = GetTickCount64() - last_user_input.dwTime; if (idle_time >= idle_threshold_milliseconds) { simulate_win_d_keypress(); } Sleep(frequency_check_milliseconds); } }