Visual Basic - Technik, FAQ, Tricks, Beispiele

Home / System / Windows / Shutdown

Windows richtig runterfahren

Impressum
Kontakt
DSVGO
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