4

Ok, so I found some code to check if a screensaver is running and kill it if I want to. This doesn't seem to work on Windows 7 PCs. Does anyone know how this code can be modified, or provide new code to accomplish this?

My application is designed to run in the background until a particular event occurs, and then create and display a full screen notification. This needs to be displayed even if a screen saver is currently up.

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
IronicMuffin
  • 4,182
  • 12
  • 47
  • 90
  • 2
    What happens if you want to show the message, but the system requires a password to exit the screensaver? Hopefully you'll be in enough control of the machines in question that this isn't an issue, but it is something that is capable of ruining your plans, I guess... – ZombieSheep Mar 29 '11 at 15:15
  • No worries on that. Policy is no password on these boxes. If for whatever reason there was one, I wouldn't be upset if the enter password box popped up. – IronicMuffin Mar 29 '11 at 15:42

4 Answers4

4

The easiest way is to fake a mouse move event with x=y=0 by calling SendInput().

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
2

The following question may provide some insight:

How to turn screensaver on (windows 7) by a code (in cmd)?

However, what if the machine is locked? I don't think you'll be able to display any application on top of the lock screen unless it is actually a screensaver (and even then it may not be possible)

Community
  • 1
  • 1
Daniel Frear
  • 1,459
  • 14
  • 22
  • This is for store employees at a busy PC. It *should* never be locked. If it is, then we will have to deal with it. For now I just need to kill a non-password protected screen saver. I'll check out the question, though. Thanks! – IronicMuffin Mar 29 '11 at 15:25
  • This is good if I need to exert more control over the screensaver, or turn it back on...but I'm going to mark David Heffernan's response as the answer. Was looking for simple, quick, and effective. Thanks! – IronicMuffin Mar 29 '11 at 16:22
  • No problem, it was more for information than a complete answer :) – Daniel Frear Mar 30 '11 at 09:24
1

Assuming you don't have a password-protected screensaver: (from http://support.microsoft.com/kb/140723)

PostMessage (GetActiveWindow(), WM_CLOSE, 0, 0L);
Gabe
  • 84,912
  • 12
  • 139
  • 238
  • 1
    Did you even read the article? That example code is for Windows 95. – Mark Ransom Mar 29 '11 at 16:07
  • 1
    @Mark: Yes, I read the article, which is why I know that the method that works for Win95 also works for any version of Windows (NT, 2k, etc.) when the screensaver is not password protected. Since the OP said they wouldn't have passwords, this method applies. – Gabe Mar 29 '11 at 17:43
0

Use SetThreadExecutionState this winAPI to tell the operating system that the thread is in use, even if the user is not interacting with the computer. These will prevent to appear screen saver and stop the machine from being suspended automatically.

Enables an application to inform the system that it is in use, thereby preventing the system from entering sleep or turning off the display while the application is running.

There are series of flags to specify a new state for the current thread:

  • ES_AWAYMODE_REQUIRED (0x00000040) : Enables away mode.
  • 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.
  • 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.

As this is an winAPI, so you have to PInvoke this :

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

User-Defined Types:

[FlagsAttribute]
public enum EXECUTION_STATE :uint
{
   ES_AWAYMODE_REQUIRED = 0x00000040,
   ES_CONTINUOUS = 0x80000000,
   ES_DISPLAY_REQUIRED = 0x00000002,
   ES_SYSTEM_REQUIRED = 0x00000001
}

Here below is the calling procedure:

//To stop screen saver and monitor power off event
//You can combine several flags and specify multiple behaviors with a single call
SetThreadExecutionState(EXECUTION_STATE.ES_DISPLAY_REQUIRED | EXECUTION_STATE.ES_SYSTEM_REQUIRED | EXECUTION_STATE.ES_CONTINUOUS);

//To reset or allow those event again you have to call this API with only ES_CONTINUOUS
SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS);//This will reset as normal

According to MSDN this API is safe to use.

The system maintains a count of applications that have called SetThreadExecutionState. The system tracks each thread that calls SetThreadExecutionState and adjusts the counter accordingly. If this counter reaches zero and there has not been any user input, the system enters sleep.

If the Application crashed before resetting flag, the System will adjust and will reset automatically.

yeasir007
  • 2,110
  • 2
  • 28
  • 43