How to prevent Windows from entering in hibernate/sleep mode
-
I have a Qt application that periodically performs some checks using a video camera (it takes and processes an image every second). I need Windows to be active without going into hibernation nor sleep mode as long as the application is running and to achieve it I have added the following code fragment in the main.cpp file of my application
// ... previous code omitted // From documentation, it should inform the o.s. that the app is in use preventing it to hibernate or sleep SetThreadExecutionState(ES_CONTINUOUS | ES_DISPLAY_REQUIRED | ES_SYSTEM_REQUIRED | ES_AWAYMODE_REQUIRED); // Execute the main application LoginDialog loginDialog(!appMode); int result = loginDialog.proceed() ? application.exec() : 0; // Restore to the previous state when the app closes SetThreadExecutionState(ES_CONTINUOUS); return result;
Unfortunately this approach is not giving the desired effects and after some time it hibernates and I don't understand why. Unfortunately I can't run the program with administrator privileges and this could be the cause but I'm not sure. I would like some help in solving my problem.
-
So what should I use? I need to capture a frame every second and perform some operations
If you need the system to stay awake it should be enough to call this once:
SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED)
Alternatively you can start a timer and call this periodically:
SetThreadExecutionState(ES_SYSTEM_REQUIRED)
If you also need the display to stay on addES_DISPLAY_REQUIRED
to any of those.What should I do in case of failure?
I don't know. It's your app. You could inform the user, close the app, do nothing or anything else you feel like. Up to you.
-
@franco-amato said in How to prevent Windows from entering in hibernate/sleep mode:
SetThreadExecutionState(...)
You are not checking the return value to see if this is succeeding.
The vaguely worded Microsoft docs might provide a clue:
Calling SetThreadExecutionState without ES_CONTINUOUS simply resets the idle timer; to keep the display or system in the working state, the thread must call SetThreadExecutionState periodically.
It is not clear what would change the thread execution state after you set it.
You may need to ensure this is called "periodically" (whatever that means). You could try it in a Qt timer slot or even a do-nothing native event filter (QCoreApplication::installNativeEventFilter) and see how it flies.
-
@ChrisW67 said in How to prevent Windows from entering in hibernate/sleep mode:
You are not checking the return value to see if this is succeeding.
What should I do in case of failure?
You may need to ensure this is called "periodically" (whatever that means). You could try it in a Qt timer slot
Just calling SetThreadExecutionState in a timer slot? With what arguments?
or even a do-nothing native event filter (QCoreApplication::installNativeEventFilter) and see how it flies.
Can you help with some code?
-
@franco-amato said in How to prevent Windows from entering in hibernate/sleep mode:
What should I do in case of failure?
Nothing, but you know that, for whatever reason, your application cannot rely on not being put to sleep. You choose whether to keep running... or try to work out why it failed and correct the code/environment (I cannot see why it should fail).
Just calling SetThreadExecutionState in a timer slot? With what arguments?
The same ones (assuming this call is not presently failing)
Can you help with some code?
I'd try the timer first. Probably seconds in between.
Something like this (untested) will call it constantly (probably overkill)
#include <QAbstractNativeEventFilter> // Filter used to call SetThreadExecutionState every time the application receives an event // Passes all events untouched class KeepAwakeFilter : public QAbstractNativeEventFilter { public: bool nativeEventFilter(const QByteArray &eventType, void *message, qintptr *result) override { Q_UNUSED(eventType); Q_UNUSED(message); Q_UNUSED(result); SetThreadExecutionState(ES_CONTINUOUS | ES_DISPLAY_REQUIRED | ES_SYSTEM_REQUIRED | ES_AWAYMODE_REQUIRED); return false; } }; // then in main.cpp or somewhere equivalent KeepAwakeFilter keepAwakeFilter; app.installNativeEventFilter(&keepAwakeFilter); // and just before you leave main and destroy keepAwakeFilter and app app.removeNativeFilter(&keepAwakeFilter);
-
@ChrisW67 said in How to prevent Windows from entering in hibernate/sleep mode:
Nothing, but you know that, for whatever reason, your application cannot rely on not being put to sleep. You choose whether to keep running... or try to work out why it failed and correct the code/environment (I cannot see why it should fail).
Unfortunately if the call to SetThreadExecutionState fails and Windows enter in Hibernation/Sleep mode, my app stops capturing from camera and I don't know how to do to keep it running in this case. Do you have any suggestion?
-
I hope you are not allowed to do this! Certainly without some kind of special privileges/run as administrator or similar. Otherwise user-level programs can be written by whoever which will prevent my PC sleeping/hibernating, which I would hope would be forbidden.
-
@JonB. On one level I agree with you. On another, things like presentation apps routinely block both screen blanking and hibernation. There is nothing in the docs I see that specified admin rights are required e.g., System Sleep Criteria. The docs do say that none of these measures block a user from taking affirmative action to sleep/hibernate/shutdown e.g., with the power button or closing a laptop cover.
@franco-amato You have not disclosed if the call is, in fact, failing.
If it is failing, then does it work if you run your application as admin? Yes, then you must need these permissions.
-
You don't usually need a timer for this.
ES_CONTINUOUS
means "I need the state of the specified flags preserved until I clear them". If you specify it you don't need a timer. If you don't then you should call the function periodically. I would use a sparse timer for this (every couple of seconds I'd say). There's no need to spam the system with it on every native event callback.That being said take care which flags you actually specify. If you need the display running use
ES_DISPLAY_REQUIRED
, but combining it withES_AWAYMODE_REQUIRED
doesn't make much sense. The away mode makes the computer to go to a sleep-like state that still allows it to perform some background tasks. That's not what you'd do if you need display to be on.Keep in mind though, that this function doesn't prevent computer from going to sleep. It only resets/stops the automatic sleep timer. The user can still make the computer go to sleep manually. To prevent that you'd have to actually change the power saving settings of the system, and for that you do need admin rights.
And yes, do check return values of your system calls!
@JonB It's quite normal for an app to prevent sleep/hibernation in specific scenarios, and no special privileges are required for that. You wouldn't want your computer to go to sleep when you're watching a movie, in the middle of printing a long document or at 99% of a large download that doesn't handle resuming for example. It's just that these states should only be enabled for the duration of these actions and (usually) not for the entire app lifetime.
-
@Chris-Kawa
I respect what you guys are saying. OTOH I wouldn't want my computer not to go to sleep because for no particular reason the author of some program fancied putting in a system call to say "busy/don't sleep" when they want to endlessly poll, put up some advertising, don't know what they are doing or a thousand other possibilities. Since Windows allows this I can only hope Linux does not. I believe, from what I have seen on this forum, that Android would not allow that willy-nilly and would be strict about necessary privileges. Ho-hum. -
@JonB said:
because for no particular reason the author of some program fancied putting in a system call to say "busy/don't sleep"
It's not like a virus. It's not a hidden feature. If an app does something stupid with it there's nothing stopping you from uninstalling it or not installing it in the first place. Like I said - the app can't stop your PC from going to sleep. It stops it from automatically going to sleep.
I wouldn't want my computer not to go to sleep
So you'd rather move your mouse constantly for 2h when watching a movie? Or run your video player with sudo?
-
@Chris-Kawa said in How to prevent Windows from entering in hibernate/sleep mode:
You don't usually need a timer for this.
ES_CONTINUOUS
means "I need the state of the specified flags preserved until I clear them".In my case (without a timer) it's not working
That being said take care which flags you actually specify. If you need the display running use
ES_DISPLAY_REQUIRED
, but combining it withES_AWAYMODE_REQUIRED
doesn't make much sense.So what should I use? I need to capture a frame every second and perform some operations
And yes, do check return values of your system calls!
What should I do in case of failure?
-
So what should I use? I need to capture a frame every second and perform some operations
If you need the system to stay awake it should be enough to call this once:
SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED)
Alternatively you can start a timer and call this periodically:
SetThreadExecutionState(ES_SYSTEM_REQUIRED)
If you also need the display to stay on addES_DISPLAY_REQUIRED
to any of those.What should I do in case of failure?
I don't know. It's your app. You could inform the user, close the app, do nothing or anything else you feel like. Up to you.
-
F franco.amato has marked this topic as solved on