Visual Basic - Technik, FAQ, Tricks, Beispiele

Home / System / Windows / Shutdown

Windows richtig runterfahren

Historie
16.08.2001Berücksichtigung von PowerOff (Hinweis von Mathias Schiffer)
14.01.2001Erste Version (nach einer Idee von Francesco Balena)

Einleitung

Das Runterfahren des Betriebssystem ist dank der API-Funktion ExitWindows eigentlich gar nicht so schwer. Nur die "sicheren" Betriebssysteme WindowsNT/2000 verlangen eine besondere Behandlung, damit der laufende Prozess das "Shutdown"-Recht bekommt.

Beispiel

Der folgende Code führt bei Button-Click zum System-Neustart (Reboot = True), wobei versucht wird alle laufenden Applikationen ordnungsgemäß (Force = False, Voreinstellung) zu beenden:

Private Sub Command1_Click()
  ShutDown True, False
End Sub

Code / Quelltext

Im Deklarationsteil müssen folgende API-Funktionen eingebunden werden:

Private Type LUID
  LowPart As Long
  HighPart As Long
End Type

Private Type TOKEN_PRIVILEGES
  PrivilegeCount As Long
  LuidUDT As LUID
  Attributes As Long
End Type

Private Declare Function AdjustTokenPrivileges Lib "advapi32" ( _
    ByVal TokenHandle As Long, _
    ByVal DisableAllPrivileges As Long, _
    ByRef NewState As TOKEN_PRIVILEGES, _
    ByVal BufferLength As Long, _
    ByRef PreviousState As Any, _
    ByRef ReturnLength As Any _
  ) As Long
Private Declare Function ExitWindowsEx Lib "user32" ( _
    ByVal dwOptions As Long, _
    ByVal dwReserved As Long _
  ) As Long
Private Declare Function GetCurrentProcess Lib "kernel32" ( _
  ) As Long
Private Declare Function GetVersion Lib "kernel32" () As Long
Private Declare Function LookupPrivilegeValueA Lib "advapi32" ( _
    ByVal lpSystemName As String, _
    ByVal lpName As String, _
    ByRef lpLuid As LUID _
  ) As Long
Private Declare Function OpenProcessToken Lib "advapi32" ( _
    ByVal ProcessHandle As Long, _
    ByVal DesiredAccess As Long, _
    ByRef TokenHandle As Long _
  ) As Long

Die eigentliche Routine sieht dann so aus:

Public Sub ShutDown( _
    Optional ByVal Reboot As Boolean = False, _
    Optional ByVal Force As Boolean = False _
  )
  Const EWX_SHUTDOWN = 1
  Const EWX_REBOOT = 2
  Const EWX_FORCE = 4
  Const EWX_POWEROFF = 8
  Const SE_PRIVILEGE_ENABLED = &H2
  Const TOKEN_ADJUST_PRIVILEGES = &H20
  Const TOKEN_QUERY = &H8
  
  Dim Flags As Long
  Dim Token As Long
  Dim TP As TOKEN_PRIVILEGES
  
  'WinNT/2000 benötigt spezielle Rechte:
  If GetVersion() >= 0 Then
    OpenProcessToken _
        GetCurrentProcess(), _
        TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY, Token
    LookupPrivilegeValueA _
        "", "SeShutdownPrivilege", TP.LuidUDT
    TP.PrivilegeCount = 1
    TP.Attributes = SE_PRIVILEGE_ENABLED
    AdjustTokenPrivileges _
        Token, False, TP, 0, ByVal 0&, ByVal 0&
  End If
  
  'Shutdown durchführen:
  Flags = EWX_SHUTDOWN
  If Reboot Then
    Flags = Flags Or EWX_REBOOT
  Else
    Flags = Flags Or EWX_POWEROFF
  End If
  If Force Then Flags = Flags Or EWX_FORCE
  ExitWindowsEx Flags, &HFFFF
End Sub

© Jost Schwider, 14.01.2001-16.08.2001 - http://vb-tec.de/shutdown.htm