2

I have a Windows service that may change the timeout on the logon screensaver in Windows (as described here.) To do that I change the following registry key to the timeout in seconds:

HKEY_USERS\.DEFAULT\Control Panel\Desktop\ScreenSaveTimeOut

The issue is that how do I make OS "read" or refresh the actual screensaver timeout after a change in the registry key above?

My practice shows that it is refreshed (for sure) only when I reboot the system, but in my case I need it to be applied without the reboot.

EDIT_1: After suggestion below I tried, as it seems to me, all possible combinations of the flags for the following:

DWORD bsmInfo1 = BSM_ALLDESKTOPS;
DWORD dwFlgs = BSF_FORCEIFHUNG | BSF_IGNORECURRENTTASK | BSF_NOTIMEOUTIFNOTHUNG | BSF_SENDNOTIFYMESSAGE;
int nbsm1 = ::BroadcastSystemMessage(dwFlgs, &bsmInfo1, WM_SETTINGCHANGE, 0, (LPARAM)L"Windows");
DWORD bsmInfo2 = BSM_ALLDESKTOPS;
int nbsm2 = ::BroadcastSystemMessage(dwFlgs, &bsmInfo2, WM_SETTINGCHANGE, 0, (LPARAM)L"WindowsThemeElement");

to no avail :( I receive 1 as a result from both calls but it has no effect.

c00000fd
  • 20,994
  • 29
  • 177
  • 400

2 Answers2

1

I was able to resolve this.-.-.

c00000fd
  • 20,994
  • 29
  • 177
  • 400
0

If your service is running in the same session as the logon screensaver then you can call SystemParametersInfo with the SPI_SETSCREENSAVETIMEOUT flag.

SystemParametersInfo broadcasts the WM_SETTINGCHANGE message to all top level windows to indicate that a parameter has changed. If your code isn't running in the correct session then you could use BroadcastSystemMessage with the BSM_ALLDESKTOPS flag to deliver the WM_SETTINGCHANGE message. However, this does require the SE_TCB_NAME privilege, so your code would have to be running as SYSTEM.

I haven't actually tried this cross-session, so I can't guarantee that it works.

arx
  • 16,686
  • 2
  • 44
  • 61
  • I tried your suggestion... please check my adjusted question. Do you have an idea which flags to call it with? – c00000fd Jan 14 '14 at 06:50
  • Is your code running as SYSTEM? If not, the function succeeds but the `bsmInfo1` variable, which the function updates to indicate who got the message, doesn't contain the `BSM_ALLDESKTOPS` flag. What value do you get in `bsmInfo1`? – arx Jan 14 '14 at 15:51
  • And the wParam and lParam should be `SPI_SETSCREENSAVETIMEOUT` and "" respectively, i.e. `int nbsm = ::BroadcastSystemMessage(dwFlgs, &bsmInfo, WM_SETTINGCHANGE, SPI_SETSCREENSAVETIMEOUT, (LPARAM)L"");`. – arx Jan 14 '14 at 16:02
  • Oh, my bad. Yes, the code is running from a LocalSystem service. And after BroadcastSystemMessage returns 1, which I believe is success, `bsmInfo1` is set `0x1F`. Still even with your modifications the logon screensaver timeout doesn't change. – c00000fd Jan 14 '14 at 21:36
  • It seems like you'll need some code running in the correct session. Sorry I couldn't be more help. – arx Jan 15 '14 at 19:53
  • Thanks for your help anyway. Btw, I did resolve it! It's not an easy solution but it works. Check the answer below. – c00000fd Jan 16 '14 at 09:40