How to end Win2K screen saver, or make Win2K reboot when screen saver is on

I have a 24x7x365 server application on a dedicated Win2K box.  I want my application to restart Windows at a pre-determined time every day (or by a remote command at any time).

I have the code to successfully reboot Windows 2000 using ExitWindowsEx() but this fails to completely shut down Win2K if the password-enabled screen saver is on.

Another acceptable solution would be to programmatically log back in, if that's possible.

If this stuff is easy to find, take it easy on me:  I'm on-site 200 miles from home and have to try to get home for dinner!

Rob---
LVL 2
RHenningsgardAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

jkrCommented:
You'd find the process that has a .scr extension and terminate it. See http://support.microsoft.com/kb/q175030/ ("How To Enumerate Applications Using Win32 APIs") on how to find it and http://support.microsoft.com/default.aspx?scid=KB;en-us;178893& ("How To Terminate an Application "Cleanly" in Win32") on how to terminate it.
0
jkrCommented:
BTW, have you tried 'InitiateSystemShutdown()'? This should work with a running screensaver (even a protected one) also. At least it did when I tried it last...
0
RHenningsgardAuthor Commented:
Thanks!  I kind of thought that might be the approach to take.  I'm punting for today, just restarting my application instead of the reboot, so I can get home.  Will award points on this after I get a chance to implement it.
0
Cloud Class® Course: SQL Server Core 2016

This course will introduce you to SQL Server Core 2016, as well as teach you about SSMS, data tools, installation, server configuration, using Management Studio, and writing and executing queries.

RHenningsgardAuthor Commented:
Well, I got part-way there.  I can enumerate processes and find the screen saver and its process ID, but I can't get a window handle to the screen saver, to send it a WM_CLOSE message.  I tried using FindWindow to no avail.  Works on apps like NOTEPAD.EXE, but it returns a zero handle for the screen saver.

[[later:  Maybe the problem is that I was running the screen saver from the properties dialog, using the "Test" button.  I'll try this tomorrow with the screen saver actually having timed out]]

I also took a stab at using EnumWindows() to give me all of the existing window handles, and then GetWindowThreadProcessID to hopefully match up one of the window handles to the screen saver's process ID.  In this I was unsuccessful at getting anything but zeroes back from GetWindowThreadProcessID, so I must be doing something wrong there.

Do you suppose the approach I'm taking will work, once I actually get my GetWindowThreadProcessID call working properly?

Any other suggestions?

Rob---
0
jkrCommented:
>>but I can't get a window handle to the screen saver, to send it a WM_CLOSE message

Um, user 'TerminateProcess()' on the process handle and leave the window handle out :o)

      // Wait on the handle. If it signals, great. If it times out,
      // then you kill it.
      if(WaitForSingleObject(hProc, dwTimeout)!=WAIT_OBJECT_0)
         dwRet=(TerminateProcess(hProc,0)?TA_SUCCESS_KILL:TA_FAILED);
      else
         dwRet = TA_SUCCESS_CLEAN
0
RHenningsgardAuthor Commented:
Several attempts with TerminateProcess did not succeed.  Is the ProcessID enumerated by Process32First/Next the process handle, or is there a level of indirection there I need to traverse to get the process handle?

Also tried setting SystemParametersInfo(SPI_SETSCREENSAVEACTIVE,0) to no avail, despite it returning true.

I even tried launching the screen saver using ShellExecute(), saving the HInstance handle, and passing that later to TerminateProcess.  No joy: The screen saver keeps merrily running along.

Seems either I'm more inept than I thought, or programmatically shutting off the screen saver is tougher than I expected!

I'm still open to suggestions.
0
jkrCommented:
>>Is the ProcessID enumerated by Process32First/Next the process handle

The process ID is a process ID - to obtain a handle, you need to 'OpenProcess()', e.g.

   #define TA_FAILED 0
   #define TA_SUCCESS_CLEAN 1
   #define TA_SUCCESS_KILL 2

   DWORD WINAPI TerminateApp( DWORD dwPI )
   {
      HANDLE   hProc ;
      DWORD   dwRet ;

      // If we can't open the process with PROCESS_TERMINATE rights,
      // then we give up immediately.
      hProc = OpenProcess(SYNCHRONIZE|PROCESS_TERMINATE, FALSE,
         dwPID);

      if(hProc == NULL)
      {
         return TA_FAILED ;
      }


         dwRet=(TerminateProcess(hProc,0)?TA_SUCCESS_KILL:TA_FAILED);
      else
         dwRet = TA_SUCCESS_CLEAN ;

      CloseHandle(hProc) ;

      return dwRet ;
   }

BTW, have you tried 'InitiateSystemShutdown()'?
0
RHenningsgardAuthor Commented:
Hey jkr, (apparently nobody would bother to take you on for a question like this... you must be the EE authority on stuff like this!)

Got to dash off to the customer site, so will not get to this until the morrow.  As you can tell, I am a newbie to most of the inter-process communications and controls in Windows, having programmed about 99.9% just individual applications.  I appreciate the education you're spooning out to me.

<<The process ID is a process ID - to obtain a handle>>

Yep, I figured that had to be the case.  Thanks for the OpenProcess() example.

<<BTW, have you tried 'InitiateSystemShutdown()'?>>

Sorry I didn't mention it:  That was the first suggestion I tried.  It doesn't shut down the screen saver.  Works fine if the system is logged in and running normally, so I assume I called it correctly.

More to come...
0
RHenningsgardAuthor Commented:
Hello again jkr,

Well your suggestion works perfectly, unless the screen saver has the "[X]Password protected" option selected.  When that's the case, the password dialog pops up, and that's where the machine sits.

I'm going to try stuffing the keyboard buffer with the machine's Admin password and <Enter>, and we'll see if that gets the last piece of this puzzle solved.  That solution would work for me fine, as every one of the dedicated computers running my application wil be set up with AutoAdminLogon=1 in the registry, thus always logged on in the Admin account with a clear-text password in the Registry.

Will let you know in a bit how I make out.  I may also try terminating the WinLogon process, just to see what happens.  I will of course read any more suggestions you may have.
0
RHenningsgardAuthor Commented:
Well, no go sending keystrokes to the screen-saver password dialog using keybd_event.  (Works everywhere else I can try it).  This is turning out to be more tricky than I imagined!

If I don't succeed fairly soon, I'm going to have to abandon the effort and write my own screen-saver instead.

0
jkrCommented:
Is your app running under an admin account? If so, try to

   HANDLE           hToken;
   TOKEN_PRIVILEGES tp;

   if   (   !OpenProcessToken   (   GetCurrentProcess   (),
                                    TOKEN_ADJUST_PRIVILEGES,
                                    &hToken
                                )
        )   return  (   FALSE);


   tp.PrivilegeCount    =   1;
   
   LookupPrivilegeValue (   NULL,
                            SE_DEBUG_NAME,
                            &tp.Privileges  [   0].Luid
                        );

   tp.Privileges    [   0].Attributes   =       bEnable
                                            ?   SE_PRIVILEGE_ENABLED
                                            :   0;

   AdjustTokenPrivileges    (   hToken,
                                FALSE,
                                &tp,
                                sizeof  (   tp),
                                NULL,
                                NULL
                            );

*before* calling 'TerminateProcess()'
0
RHenningsgardAuthor Commented:
Well, "swing and a miss" on killing WINLOGON.EXE.  Heck, even Task Manager can't do it!

I'm out of ideas.  JKR, you're going to get at least a major point split on this question for the great advice you've given me.  Do you have any other thoughts?
0
jkrCommented:
You cannot killl 'winlogon.exe', but with enabling SE_DEBUG_NAME like above, you should be able to kill the screeensaver.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
RHenningsgardAuthor Commented:
JKR, I am concluding that, apart from a serious hack, there's no way to have an executable program running on Windows log the desktop back in to a password-protected screen saver.  Your tips were good, and they added to my repertoire of tricks, so I'm awarding you the points.

Rob---
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Development

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.