Say you have a long running process that you let go overnight, only to come back the next morning and realize “Oh no, only an hour into it, my computer went to sleep!”. Thanks to some Windows internals, it’s possible to make it realize there is a background task running and should not go to sleep.
I personally use this exact method in my FastFlix program to make sure the computer doesn’t interrupt the coding process. It should work with any version of Python3, and it boils down too:
#!/usr/bin/env python # -*- coding: UTF-8 -*- import ctypes import time CONTINUOUS = 0x80000000 SYSTEM_REQUIRED = 0x00000001 DISPLAY_REQUIRED = 0x00000002 ctypes.windll.kernel32.SetThreadExecutionState(CONTINUOUS | SYSTEM_REQUIRED) try: # This is where you would do stuff while True: time.sleep(600) finally: ctypes.windll.kernel32.SetThreadExecutionState(CONTINUOUS)
As this example shows, you let this run in the background to always keep your computer from sleeping. Just be careful you don’t abuse your IT policies by allowing your computer to stay on for a lot longer than they want.
It’s pretty straightforward code, the main function being SetThreadExecutionState.
|ES_CONTINUOUS||0x80000000||Informs the system that the state being set should remain in effect until the next call that uses ES_CONTINUOUS and one of the other state flags is cleared.|
|ES_DISPLAY_REQUIRED||0x00000002||Forces the display to be on by resetting the display idle timer.|
|ES_SYSTEM_REQUIRED||0x00000001||Forces the system to be in the working state by resetting the system idle timer.|
Notice that it doesn’t take multiple arguments, like what you expect in Python. Instead it accepts a single hex value that represents the culmination of all the options you want to set. Hence why you see us passing them in via a “bitwise or” expression. For example, if you also wanted to force the screen to stay on, just need to add:
ctypes.windll.kernel32.SetThreadExecutionState(CONTINUOUS | SYSTEM_REQUIRED | DISPLAY_REQUIRED)
After this is set, it is extremely important to remember to always reset it back to
ES_CONTINUOUS after your work is done.
Use atexit for safety
In our example above, we simply add this in a finally clause. For a more robust program you may want to ensure it’s always called via
#!/usr/bin/env python # -*- coding: UTF-8 -*- import ctypes import atexit CONTINUOUS = 0x80000000 SYSTEM_REQUIRED = 0x00000001 DISPLAY_REQUIRED = 0x00000002 ctypes.windll.kernel32.SetThreadExecutionState(CONTINUOUS | SYSTEM_REQUIRED) @atexit.register def cleanup(): ctypes.windll.kernel32.SetThreadExecutionState(CONTINUOUS) # Do Stuff