HOWTO: Programmatically Force a Logoff on Windows 95

Last reviewed: May 20, 1997
Article ID: Q168690
The information in this article applies to:
  • Microsoft Win32 Application Programming Interface (API) included with: - Microsoft Windows 95

SUMMARY

You can use the Win32 API ExitWindowsEx() on Windows NT to force a logoff. You accomplish this by combining the EWX_LOGOFF and EWX_FORCE flags. Unfortunately, this combination is not supported on Windows 95.

You can duplicate this capability on Windows 95 by taking some additional steps before calling ExitWindowsEx().

MORE INFORMATION

ExitWindowsEx() with the EWX_LOGOFF flag alone does not force non- responsive applications to close. To achieve this, follow these steps:

  1. Enumerate top-level windows with the EnumWindows() API.

  2. In the EnumWindowsProc, ask each application to shut down by sending it the WM_QUERYENDSESSION message.

  3. If the application responds positively, then send the WM_ENDSESSION message to direct the application to terminate.

  4. If the application responds negatively, terminate the application with the TerminateProcess() API.

  5. Once all applications with top-level windows have been shut down in this manner, you can call ExitWindowsEx(EWX_LOGOFF) with a reasonable assurance that the logoff operation will complete.

IMPORTANT: Using the TerminateProcess() API is not a "nice" way to shut down an application and could result in the loss of data. This technique should only be used if a machine must be guaranteed to perform the logoff operation while unattended.

NOTE: This method is not 100% successful. There are a few applications that cause ExitWindowsEx() to fail. This article will be updated when more information is available.

NOTE: ExitWindowsEx does not work correctly if it is called from a Win32 Console application. This must be a Windows application to work properly.

Sample Code

The following sample code demonstrates the technique:

   #include <windows.h>

   BOOL CALLBACK EnumWindowsProc(
       HWND hwnd,
       DWORD lParam
       );

   //
   // EnumWindowsProc must be called from a windows
   // application on Windows 95
   //
   int WINAPI WinMain(
       HINSTANCE hInstance,
       HINSTANCE hPrevInstance,
       LPSTR lpCmdLine,
       int nCmdShow
       )
   {
       //
       // close all open applications
       //
       EnumWindows(EnumWindowsProc, 0);

       // Now do a regular logoff
       ExitWindowsEx(EWX_LOGOFF , 0);

   }

   BOOL CALLBACK EnumWindowsProc(
       HWND hwnd,
       DWORD lParam
       )
   {
       DWORD      pid = 0;
       LRESULT    lResult;
       HANDLE     hProcess;
       DWORD      dwResult;

       lResult = SendMessageTimeout(
           hwnd,
           WM_QUERYENDSESSION,
           0,
           ENDSESSION_LOGOFF,
           SMTO_ABORTIFHUNG,
           2000,
           &dwResult);

       if( lResult )
       {
          //
          // application will terminate nicely so let it
          //
          lResult = SendMessageTimeout(
              hwnd,
              WM_ENDSESSION,
              TRUE,
              ENDSESSION_LOGOFF,
              SMTO_ABORTIFHUNG,
              2000,
              &dwResult);

       }
       else  // we have to take more forceful measures
       {
           //
           // get the processid for this window
           //
           GetWindowThreadProcessId( hwnd, &pid );
           //
           // open the process with all access
           //
           hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
           //
           // bye-bye
           //
           TerminateProcess(hProcess, 0);

       }
       //
       // continue the enumeration
       //
       return TRUE;
   }


Additional query words: 95 win95 ExitWindowsEx FORCE LOGOFF
Keywords : BseMisc BseProcThrd
Platform : NT WINDOWS
Issue type : kbhowto


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: May 20, 1997
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.