Tipp 4.6 - Aktuellen Benutzer abmelden

Wie kann ich den aktuellen Benutzer abmelden, um das System herunterzufahren?

Mit dieser Funktion können Sie ich einen Systemklang durchführen. Kopieren Sie einfach nachfolgenden Quellcode in die Zwischenablage und fügen Sie anschließend den Inhalt der Zwischenablage in ein neues Modul ein. Die Aufrufparameter finden Sie im Quellcode beschrieben.

Api-AufrufeVerwendete Win32-Api-Aufrufe und Typen: GetCurrentProcess, OpenProcessToken, LookupPrivilegeValue, AdjustTokenPrivileges, ExitWindowsEx, GetVersionEx, SetLastError - LUID, token_PRIVILEGES, OSVERSIONINFO

Beispiel:

Option Explicit
'// -----------------------------------------------------
'// Verschiedene Methoden, den aktuellen Benutzer
'// abzumelden und/oder das System herunterzufahren:
'// -----------------------------------------------------
'// Methode       | Beschreibung
'// -----------------------------------------------------
'// Logoff        | Aktuellen Benutzer abmelden
'// -----------------------------------------------------
'// ForceLogoff   | Aktuellen Benutzer abmelden (erzw.)
'// -----------------------------------------------------
'// Shutdown      | System herunterfahren
'// -----------------------------------------------------
'// ForceShutdown | System herunterfahren (erzwingen)
'// -----------------------------------------------------
'// Logoff        | Aktuellen Benutzer abmelden
'// -----------------------------------------------------
'// Autor:        | Stefan Kulpa
'//               | EDV Innovation & Consulting
'//               | Dormagen
'// -----------------------------------------------------
 
Public Enum EXIT_FLAGS
  EWX_LOGOFF = 0  ' WinNT
  EWX_SHUTDOWN = 1  ' WinNT
  EWX_REBOOT = 2  ' WinNT
  EWX_FORCE = 4  ' WinNT
  EWX_POWEROFF = 8  ' WinNT
  EWX_SHUTDOWNPWROFF = EWX_SHUTDOWN + EWX_POWEROFF  ' WinNT
  SHRS_EXIT_NO_DEFPROMPT = 1  ' Win9x
  SHRS_REBOOT_SYSTEM = 2  ' Win9x
End Enum
Public Type LUID
  UsedPart                   As Long
  IgnoredForNowHigh32BitPart As Long
End Type
Public Type token_PRIVILEGES
  PrivilegeCount             As Long
  TheLuid                    As LUID
  Attributes                 As Long
End Type
Public Type OSVERSIONINFO
  dwOSVersionInfoSize        As Long
  dwMajorVersion             As Long
  dwMinorVersion             As Long
  dwBuildNumber              As Long
  dwPlatformID               As Long
  szCSDVersion               As String * 128
End Type
 
Public Declare Function GetCurrentProcess _
    Lib "kernel32" () As Long
 
Public Declare Function OpenProcessToken _
    Lib "advapi32.dll" _
    (ByVal ProcessHandle As Long, _
    ByVal DesiredAccess As Long, _
    TokenHandle As Long) As Long
 
Public Declare Function LookupPrivilegeValue _
    Lib "advapi32.dll" Alias _
    "LookupPrivilegeValueA" _
    (ByVal lpSystemName As String, _
    ByVal lpName As String, _
    lpLuid As LUID) As Long
 
Public Declare Function AdjustTokenPrivileges _
    Lib "advapi32.dll" _
    (ByVal TokenHandle As Long, _
    ByVal DisableAllPrivileges As Long, _
    NewState As token_PRIVILEGES, _
    ByVal BufferLength As Long, _
    PreviousState As token_PRIVILEGES, _
    ReturnLength As Long) As Long
 
Public Declare Function ExitWindowsEx _
    Lib "user32" _
    (ByVal dwOptions As Long, _
    ByVal dwReserved As Long) As Long
 
Public Declare Function GetVersionEx _
    Lib "kernel32" Alias _
    "GetVersionExA" _
    (lpVersionInformation As OSVERSIONINFO) As Long
 
Public Declare Sub SetLastError _
    Lib "kernel32" _
    (ByVal dwErrCode As Long)
 
Public Sub Logoff()
 
  ExitWindowsEx (EWX_LOGOFF), &HFFFF
 
End Sub
 
Public Sub ForceLogoff()
 
  ExitWindowsEx (EWX_LOGOFF Or EWX_FORCE), &HFFFF
 
End Sub
 
Public Sub Shutdown()
 
  If IsWinNT Then AdjustToken
  ExitWindowsEx (EWX_LOGOFF Or EWX_POWEROFF), &HFFFF
 
End Sub
 
Public Sub ForceShutdown()
 
  If IsWinNT Then AdjustToken
  ExitWindowsEx (EWX_SHUTDOWN Or EWX_FORCE), &HFFFF
 
End Sub
 
Private Sub AdjustToken()
  '// -----------------------------------------------------
  '// Methode:   | Vor dem Shutdown das NT-Sicherheitssys.
  '//            | berücksichtigen
  '// -----------------------------------------------------
  '// Parameter: | entfällt
  '// -----------------------------------------------------
  '// Rückgabe:  | entfällt
  '// -----------------------------------------------------
  Const token_ADJUST_PRIVILEGES   As Long = &H20
  Const token_QUERY               As Long = &H8
  Const SE_PRIVILEGE_ENABLED      As Long = &H2
 
  Dim hdlProcessHandle            As Long
  Dim hdlTokenHandle              As Long
  Dim tmpLuid                     As LUID
  Dim tkp                         As token_PRIVILEGES
  Dim tkpNewButIgnored            As token_PRIVILEGES
  Dim lBufferNeeded               As Long
 
  SetLastError 0
  hdlProcessHandle = GetCurrentProcess()
 
  OpenProcessToken _
      hdlProcessHandle, _
      (token_ADJUST_PRIVILEGES Or token_QUERY), _
      hdlTokenHandle
 
  LookupPrivilegeValue "", "SeShutdownPrivilege", tmpLuid
  tkp.PrivilegeCount = 1
  tkp.TheLuid = tmpLuid
  tkp.Attributes = SE_PRIVILEGE_ENABLED
 
  AdjustTokenPrivileges _
      hdlTokenHandle, _
      False, _
      tkp, _
      Len(tkpNewButIgnored), _
      tkpNewButIgnored, _
      lBufferNeeded
 
End Sub
 
Public Property Get IsWinNT() As Boolean
 
  Const VER_PLATFORM_WIN32_NT As Long = 2
  Dim uOSVer                  As OSVERSIONINFO
 
  uOSVer.dwOSVersionInfoSize = Len(uOSVer)
  GetVersionEx uOSVer
  IsWinNT = (uOSVer.dwPlatformID = VER_PLATFORM_WIN32_NT)
 
End Property