Exit Windows with a WSH-Script

Oh yes, you can force Windows 98 to shutdown, restart or logoff from a WSH script. Programmers know the Windows API-Function ExitWindowsEx, which may be used to force a shutdown, restart etc. The problem: We can't call this function from a simple script or use a RunDll32.exe call. This is caused by the inability to pass parameters from a command line to the called API-function.

Note: I have shown in my WSH books a technique using an ActiveX control to access the API-function ExitWindowsEx from WSH scripts. The WSHExtend ActiveX-control is written in VB and is contained on the sample CD-ROM of my Inside Windows Scripting Host title (and may be downloaded from the Windows Scripting Host Bazaar). I have implemented the frist version of this control only for Win 9x, but there is a 2nd edition also handling NT (the source is published in my German WSH Book. For Windows 2000 I recommend using WMI to shutdown the system.

But during examining the internals of Windows 98 I found also a "backdoor" a Microsoft developer has implemented to access the ExitWindowsEx-API-function from within the Windows shell. Suppose this developer suffers also from many mouse clicks to restart Windows during testing and optimizing the operating system.

The undocumented "backdoor" comes with the function SHExitWindowsEx in Shell32.dll. This functions acts as a wrapper to call ExitWindowsEx. You may call the function from the Windows shell with the following command:

RunDll32.exe Shell32.dll,SHExitWindowsEx 0x0

The program RunDll32.exe calls the function SHExitWindowsEx in Shell32.dll. The function requests one parameter, which must be a string defining a hexadecimal number for the exit mode. The string must be written as 0x0... The string 0x0 defines the value 0, 0x01 defines 1 and so on. SHExitWindowsEx reads this parameter, converts it to a hexadecimal value and calls the API-function ExitWindowsEx. The following table specifies the values you may use:

Command Remark
Shell32.dll,ExitWindowsEx,0x0 Logoff
Shell32.dll,ExitWindowsEx,0x1 Shutdown
Shell32.dll,ExitWindowsEx,0x2 Restart

The following listing shows how to use this know how within a WSH script.

'************************************************
' File: Shell.vbs (WSH-sample in VBScript) 
' Author: Günter Born
'
' Demonstrates the access of the API-function
' SHExitWindowsEx of the Windows-Shell. That allows
' the use of the API-Function ExitWindowsEx from the
' command level. The function expects one parameter,
' specifying the termination mode.
'
' Shell32.dll,ExitWindowsEx,0x0 Logoff
' Shell32.dll,ExitWindowsEx,0x1 Shutdown
' Shell32.dll,ExitWindowsEx,0x2 Restart
'
' In no way shall the author be liable for any
' losses or damages resulting from the use of this
' program. Use AS-IS at your own risk.
'
' The code is the property of the author. You may
' use the code and modify it, as far as this header
' remains intact. Further updates and other samples
' may be found on my site:
' http://www.borncity.de
'************************************************
Option Explicit

Dim Shell, Title, obj

Title = "WSH by Günter Born"

' Fetch the object reference for the Shell
Set Shell = WScript.CreateObject ("Shell.Application")
Set obj = WScript.CreateObject("WScript.Shell")

' invoke the End-method? 
If (MsgBox("Logoff?", _
vbYesNo + vbQuestion, Title) = vbYes) Then _
obj.Run "RunDll32.exe Shell32.dll,SHExitWindowsEx 0x0" 

' invoke the Exit-method? 
If (MsgBox("Shutdown Windows?", _
vbYesNo + vbQuestion, Title) = vbYes) Then _
obj.Run "RunDll32.exe Shell32.dll,SHExitWindowsEx 0x01" 
End if

' invoke the Reset-method? 
If (MsgBox("Restart?", _
vbYesNo + vbQuestion, Title) = vbYes) Then
obj.Run "RunDll32.exe Shell32.dll,SHExitWindowsEx 0x02" 
End if

'*** End

Additional information about this sample and the way the way how to call API-functions from WSH scripts may be found in my WSH book Inside Windows Scripting Host, published by Microsoft Press Germany.

Back