Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check if disabling sleep with SetThreadExecutionState fails?

When disabling system sleep using the following line:

SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS | EXECUTION_STATE.ES_AWAYMODE_REQUIRED);

How can I tell that it worked? On one of my computers for instance, it doesn't work. The computer stil goes to sleep but there is no exception. If there is no exception, is there any other way to know that the call to SetThreadExecutionSTate failed?

like image 961
Luis Ferrao Avatar asked Mar 05 '13 14:03

Luis Ferrao


2 Answers

The return value of SetThreadExecutionState is used to indicate success or failure. This is described in the documentation.

Return value

If the function succeeds, the return value is the previous thread execution state.

If the function fails, the return value is NULL.

The value of NULL is simply 0 so you can check for success by comparing the return value against 0. So there will not be an exception when it fails. The return value will simply be 0. Don't expect Windows API functions to raise exceptions to signal failure. They simply do not do that.

The p/invoke signature that you need, obtained from pinvoke.net is:

[FlagsAttribute]
public enum EXECUTION_STATE : uint
{
     ES_AWAYMODE_REQUIRED = 0x00000040,
     ES_CONTINUOUS = 0x80000000,
     ES_DISPLAY_REQUIRED = 0x00000002,
     ES_SYSTEM_REQUIRED = 0x00000001
     // Legacy flag, should not be used.
     // ES_USER_PRESENT = 0x00000004
}

[DllImport("kernel32.dll", SetLastError = true)]
static extern EXECUTION_STATE SetThreadExecutionState(EXECUTION_STATE esFlags);

Then you can call it like this

bool succeeded = (SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS | 
    EXECUTION_STATE.ES_AWAYMODE_REQUIRED) != 0);

And if the call fails then raise an exception like this:

if (!succeeded)
    throw new Win32Exception();

Most likely your problem is that you are using ES_AWAYMODE_REQUIRED. I think you should be using ES_SYSTEM_REQUIRED.

like image 187
David Heffernan Avatar answered Sep 20 '22 05:09

David Heffernan


The function returns a value to indicate whether the operation succeeded or not. If the return value is NULL, the operation failed. (Source)

The return value is NULL which is equivalent to 0.

You should therefore capture the return value in a variable and check if it is zero:

uint result = SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS |
                                      EXECUTION_STATE.ES_AWAYMODE_REQUIRED);
if (result != 0)
{
    // Function failed...
}
like image 35
John Willemse Avatar answered Sep 18 '22 05:09

John Willemse