Rubrik: System/Windows · Sonstiges | VB-Versionen: VB4, VB5, VB6 | 02.08.01 |
Sicherer Windows-Neustart (auch unter NT/2000) Hier wird gezeigt, wie sich Windows per Programmcode sowohl unter Win9x/ME als auch unter WinNT/2000 neu starten lässt. | ||
Autor: Dieter Otter | Bewertung: | Views: 20.162 |
www.tools4vb.de | System: Win9x, WinNT, Win2k, WinXP, Win7, Win8, Win10, Win11 | Beispielprojekt auf CD |
Um Windows per Programmcode neu zu starten, kennen Sie sicherlich (fast) alle die API-Funktion ExitWindowsEx. Über einen Parameter gibt man hierbei an, ob
- Windows beendet und neu gestartet werden soll
- Windows heruntergefahren werden soll
- oder ob man sich unter einen neuen Benutzernamen neu-anmelden möchte
Unter den Betriebssystem Windows 95/98 und ME funktioniert ExitWindowsEx einwandfrei.
Wie verhält sich die Funktion aber unter Windows NT/2000?
Wird die Anwendung unter Windows NT oder Windows 2000 ausgeführt, so müssen vor dem Funktions-Aufruf zunächst Sicherheitsüberprüfungen und Veränderungen durchgeführt werden, um sicherzustellen, daß das Token vorhanden ist, das einen Neustart des Systems zulässt.
Dieser Tipp stellt Ihnen die Prozedur RebootSystem vor, welche unabhängig vom eingesetzten Betriebssystem ordnungsgemäß arbeitet. Innerhalb der Prozedur wird zunächst das Betriebssystem ermittelt. Handelt es sich um Windows NT/2000, so werden die gerade genannten Vorkehrungen automatisch getroffen, so daß die API-Funktion ExitWindowsEx auch unter WinNT/2000 korrekt funktioniert.
' System herunterfahren/neu starten ' oder aktuellen Benutzer abmelden Public Function RebootSystem(ByVal Action As EWX_ACTION) _ As Boolean Dim ret As Long Dim hToken As Long Dim tkp As TOKEN_PRIVILEGES Dim tkpOld As TOKEN_PRIVILEGES Dim fOkReboot As Boolean Const sSHUTDOWN As String = "SeShutdownPrivilege" If IsWindowsNT() Then ' Windows NT wird ausgeführt. ' Sicherheitsüberprüfungen und ' Veränderungen sind jetzt notwendig, ' um sicherzustellen, daß das Token ' vorhanden ist, das einen Neustart zuläßt. If OpenProcessToken(GetCurrentProcess(), _ TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY, hToken) Then ret = LookupPrivilegeValue(vbNullString, _ sSHUTDOWN, tkp.Privileges(0).pLuid) tkp.PrivilegeCount = 1 tkp.Privileges(0).Attributes = SE_PRIVILEGE_ENABLED fOkReboot = AdjustTokenPrivileges(hToken, 0, tkp, _ LenB(tkpOld), tkpOld, ret) End If Else ' Win95/98 wird ausgeführt. Keine Aktion ist notwendig. fOkReboot = True End If If fOkReboot Then _ RebootSystem = (ExitWindowsEx(Action, 0) <> 0) End Function
Und hier alle benötigten Deklarationen und "Hilfsfunktionen", welche die Hintergrundarbeiten erledigen.
Option Explicit ' Windows-Version ' für den Aufruf der GetVersionEx-Funktion Private Type OSVERSIONINFO dwOSVersionInfoSize As Long dwMajorVersion As Long dwMinorVersion As Long dwBuildNumber As Long dwPlatformId As Long szCSDVersion As String * 128 End Type Private Declare Function GetVersionEx Lib "Kernel32" _ Alias "GetVersionExA" ( _ lpVersionInformation As OSVERSIONINFO) As Long ' System beenden + neu starten Private Declare Function ExitWindowsEx Lib "user32" ( _ ByVal uFlags As Long, _ ByVal dwReserved As Long) As Long Public Enum EWX_ACTION EWX_LOGOFF = 0 EWX_SHUTDOWN = 1 EWX_REBOOT = 2 End Enum ' Für Windows NT/2000 Private Const ANYSIZE_ARRAY = 1 Private Type LARGE_INTEGER lowpart As Long highpart As Long End Type Private Type LUID_AND_ATTRIBUTES pLuid As LARGE_INTEGER Attributes As Long End Type Private Type TOKEN_PRIVILEGES PrivilegeCount As Long Privileges(ANYSIZE_ARRAY) As LUID_AND_ATTRIBUTES End Type Private Const TOKEN_ADJUST_PRIVILEGES = 32 Private Const TOKEN_QUERY = 8 Private Const SE_PRIVILEGE_ENABLED As Long = 2 Private Declare Function LookupPrivilegeValue Lib "advapi32.dll" _ Alias "LookupPrivilegeValueA" ( _ ByVal lpSystemName As String, _ ByVal lpName As String, _ lpLuid As LARGE_INTEGER) As Long Private Declare Function GetCurrentProcess Lib "Kernel32" () As Long Private 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 Private Declare Function OpenProcessToken Lib "advapi32.dll" ( _ ByVal ProcessHandle As Long, _ ByVal DesiredAccess As Long, _ TokenHandle As Long) As Long ' Aktuelle Windows-Plattform ermitteln Private Function GetWinPlatform() As Long Dim osvi As OSVERSIONINFO Dim strCSDVersion As String osvi.dwOSVersionInfoSize = Len(osvi) If GetVersionEx(osvi) = 0 Then Exit Function End If GetWinPlatform = osvi.dwPlatformId End Function ' Prüfen, ob Windows NT/2000 Public Function IsWindowsNT() As Boolean Const dwMaskNT = &H2& IsWindowsNT = (GetWinPlatform() And dwMaskNT) End Function
Beispiel für den Aufruf von RebootSystem
' System herunterfahren und neu starten RebootSystem EWX_REBOOT ' System herunterfahren (ohne Neustart) RebootSystem EWX_SHUTDOWN ' Aktuellen Benutzer abmelden RebootSystem EWX_LOGOFF