VB 5/6-Tipp 0418: Windows in allen Versionen herunterfahren
von Florian Rittmeier
Beschreibung
Dieser Tipp bietet entgegen Tipp 20 eine umfassende Lösung für alle Windows-Systeme um den Rechner herunterzufahren, zu rebooten und in den Login-Modus zu versetzen. Bei NT-Systemen müssen nämlich zu Beginn eines solchen Vorgangs zuerst, wie hier gezeigt, die nötigen Rechte zum Beenden des Explorers gesetzt werden.
Schwierigkeitsgrad: | Verwendete API-Aufrufe: AdjustTokenPrivileges, ExitWindowsEx, GetCurrentProcess, LookupPrivilegeValueA (LookupPrivilegeValue), OpenProcessToken | Download: |
'Dieser Quellcode stammt von http://www.activevb.de 'und kann frei verwendet werden. Für eventuelle Schäden 'wird nicht gehaftet. 'Um Fehler oder Fragen zu klären, nutzen Sie bitte unser Forum. 'Ansonsten viel Spaß und Erfolg mit diesem Source! '----------- Anfang Projektdatei prjshutdown.vbp ----------- '-------- Anfang Formular "Form1" alias frmMain.frm -------- ' Steuerelement: Kontrollkästchen-Steuerelement "Check2" ' Steuerelement: Kontrollkästchen-Steuerelement "Check1" ' Steuerelement: Kombinationsliste "Combo1" ' Steuerelement: Schaltfläche "cmdNTbased" Option Explicit Private Const EWX_LOGOFF As Long = 0 Private Const EWX_SHUTDOWN As Long = 1 Private Const EWX_REBOOT As Long = 2 Private Const EWX_POWEROFF As Long = 8 Private Const EWX_FORCE As Long = 4 Private Const EWX_FORCEIFHUNG As Long = 16 Private Sub cmdNTbased_Click() If Combo1.ListIndex = -1 Then Exit Sub Dim ShutdownManager As New clsShutdown Dim param As Long Dim boxres As VbMsgBoxResult ' Die eventuellen Zusatzparameter berücksichtigen If Check1.Value = 1 Then param = param Or EWX_FORCE End If If Check2.Value = 1 Then ' Funktioniert erst ab Windows 2000 param = param Or EWX_FORCEIFHUNG End If param = param Or Combo1.ItemData(Combo1.ListIndex) If (param And EWX_SHUTDOWN) > 0 Or _ (param And EWX_POWEROFF) > 0 Or _ (param And EWX_REBOOT) > 0 Then ' Hier muss berücksichtigt werden, ob es sich ' um ein NT-basierendes OS handelt boxres = MsgBox("Verwenden Sie ein NT-basierendes Betriebsystem?", _ vbYesNoCancel, App.Title) If boxres = vbYes Then ShutdownManager.ShutDownNTbasedWindows param Exit Sub End If End If ShutdownManager.ShutDownDOSbasedWindows param End Sub Private Sub Form_Initialize() Combo1.AddItem "Benutzer abmelden" Combo1.ItemData(Combo1.NewIndex) = EWX_LOGOFF Combo1.AddItem "System herunterfahren" Combo1.ItemData(Combo1.NewIndex) = EWX_SHUTDOWN Combo1.AddItem "System neustarten" Combo1.ItemData(Combo1.NewIndex) = EWX_REBOOT Combo1.AddItem "System herunterfahren und ausschalten" Combo1.ItemData(Combo1.NewIndex) = EWX_POWEROFF Combo1.ListIndex = 0 Check1.Caption = "Alle Anwendungen ohne Rückfrage sofort beenden. (Holzhammermethode)" Check2.Caption = "Sollte eine Anwendung nicht reagieren, dann diese ohne Rückfrage " & _ "beenden. (sanfter Holzhammer)(erst ab Windows 2000 verfügbar)" End Sub '--------- Ende Formular "Form1" alias frmMain.frm --------- '---- Anfang Klasse "clsShutdown" alias clsShutdown.cls ---- Option Explicit Private Const TOKEN_ADJUST_PRIVILEGES As Long = &H20 Private Const SE_SHUTDOWN_NAME As String = "SeShutdownPrivilege" Private Const SE_PRIVILEGE_ENABLED As Long = &H2 Private Const EWX_LOGOFF As Long = 0& Private Const EWX_SHUTDOWN As Long = 1& Private Const EWX_REBOOT As Long = 2& Private Const EWX_FORCE As Long = 4& Private Const EWX_POWEROFF As Long = 8& Private Const EWX_FORCEIFHUNG As Long = 16& Private Type LUID lowpart As Long highpart As Long End Type Private Type LUID_AND_ATTRIBUTES pLuid As LUID Attributes As Long End Type Private Type TOKEN_PRIVILEGES PrivilegeCount As Long Privileges As LUID_AND_ATTRIBUTES End Type Private Declare Function AdjustTokenPrivileges Lib "advapi32.dll" ( _ ByVal TokenHandle As Long, ByVal DisableAllPrivileges As Long, _ NewState As TOKEN_PRIVILEGES, BufferLength As Any, _ PreviousState As Any, ReturnLength As Any) As Long Private Declare Function ExitWindowsEx Lib "user32.dll" ( _ ByVal uFlags As Long, ByVal dwReserved As Long) As Long Private Declare Function OpenProcessToken Lib "advapi32.dll" ( _ ByVal ProcessHandle As Long, ByVal DesiredAccess As Long, _ TokenHandle As Long) As Long Private Declare Function GetCurrentProcess Lib "kernel32.dll" () As Long Private Declare Function LookupPrivilegeValue Lib "advapi32.dll" Alias "LookupPrivilegeValueA" ( _ ByVal lpSystemName As String, ByVal lpName As String, _ lpLuid As LUID) As Long Public Function ShutDownDOSbasedWindows(ByVal ShutDownMode As Long) As Boolean Dim retval As Long retval = ExitWindowsEx(ShutDownMode, 0&) If retval = 0 Then Call MsgBox("Das System kann aufgrund eines Fehlers nicht heruntergefahren werden.", _ vbExclamation + vbOKOnly, App.Title) Exit Function End If ShutDownDOSbasedWindows = True End Function Public Function ShutDownNTbasedWindows(ByVal ShutDownMode As Long) As Boolean Dim retval As Long If (ShutDownMode And EWX_SHUTDOWN) > 0 Or _ (ShutDownMode And EWX_POWEROFF) > 0 Or _ (ShutDownMode And EWX_REBOOT) > 0 Then If Not AdjustPrivilege2ShutdownOrRestart(True) Then Call MsgBox("Das Privileg zum Herunterfahren/Neustarten des Systems " & _ "konnte nicht aktiviert werden.", _ vbExclamation + vbOKOnly, App.Title) Exit Function End If End If ShutDownNTbasedWindows = ShutDownDOSbasedWindows(ShutDownMode) If (ShutDownMode And EWX_SHUTDOWN) > 0 Or _ (ShutDownMode And EWX_POWEROFF) > 0 Or _ (ShutDownMode And EWX_REBOOT) > 0 Then If Not AdjustPrivilege2ShutdownOrRestart(False) Then ' Meckere nicht, denn für den Anwender spielt es im Prinzip keine Rolle End If End If End Function Private Function AdjustPrivilege2ShutdownOrRestart(ByVal EnablePrivilege As Boolean) As Boolean Dim retval As Long, hToken As Long 'Zunächst ein Handle für den Accesstoken des aktuellen Prozesses ermitteln retval = OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES, hToken) If retval = 0 Then Call MsgBox("Das Handle für den Accesstoken des aktuellen Prozesses konnte " & _ "nicht erlangt werden.", vbExclamation + vbOKOnly, App.Title) Exit Function End If ' Nun den aktuellen LUID für das SE_SHUTDOWN-Privileg ermitteln Dim SE_SHUTDOWN_LI As LUID retval = LookupPrivilegeValue(vbNullString, SE_SHUTDOWN_NAME, SE_SHUTDOWN_LI) If retval = 0 Then Call MsgBox("Der aktuelle LUID für das SE_SHUTDOWN-Privileg " & _ "konnte nicht ermittelt werden konnte.", _ vbExclamation + vbOKOnly, App.Title) Exit Function End If 'Das SE_SHUTDOWN-Privileg aktivieren Dim tokenpriv As TOKEN_PRIVILEGES 'durch den angepassten UDT immer 1 tokenpriv.PrivilegeCount = 1 If EnablePrivilege Then 'Privileg aktivieren tokenpriv.Privileges.Attributes = SE_PRIVILEGE_ENABLED Else 'Privileg deaktivieren tokenpriv.Privileges.Attributes = 0 End If 'LUID zuweisen tokenpriv.Privileges.pLuid.highpart = SE_SHUTDOWN_LI.highpart tokenpriv.Privileges.pLuid.lowpart = SE_SHUTDOWN_LI.lowpart 'Anpassung durchführen retval = AdjustTokenPrivileges(hToken, 0, tokenpriv, _ ByVal CLng(0), ByVal CLng(0), ByVal CLng(0)) If retval = 0 Then Call MsgBox("Das Privileg zum Herunterfahren des Systems " & _ "konnte aus unbekanntem Grund nicht modifiziert werden.", _ vbExclamation + vbOKOnly, App.Title) Exit Function End If AdjustPrivilege2ShutdownOrRestart = True End Function '----- Ende Klasse "clsShutdown" alias clsShutdown.cls ----- '------------ Ende Projektdatei prjshutdown.vbp ------------
Tipp-Kompatibilität:
Windows/VB-Version | Win32s | Win95 | Win98 | WinME | WinNT4 | Win2000 | WinXP |
VB4 | |||||||
VB5 | |||||||
VB6 |
Ihre Meinung
Falls Sie Fragen zu diesem Artikel haben oder Ihre Erfahrung mit anderen Nutzern austauschen möchten, dann teilen Sie uns diese bitte in einem der unten vorhandenen Themen oder über einen neuen Beitrag mit. Hierzu können sie einfach einen Beitrag in einem zum Thema passenden Forum anlegen, welcher automatisch mit dieser Seite verknüpft wird.
Archivierte Nutzerkommentare
Klicken Sie diesen Text an, wenn Sie die 36 archivierten Kommentare ansehen möchten.
Diese stammen noch von der Zeit, als es noch keine direkte Forenunterstützung für Fragen und Kommentare zu einzelnen Artikeln gab.
Aus Gründen der Vollständigkeit können Sie sich die ausgeblendeten Kommentare zu diesem Artikel aber gerne weiterhin ansehen.
Kommentar von Fred am 09.11.2009 um 07:56
Hallo Hairichi
Klar, der Shell funktioniert auch unter XP / VB6 SP6 einwandfrei. Get so ja auch unter Windows START, Run... shutdown.exe -h (z.B. für Help)
Nur: Standby und Hibernate ist damit nicht möglich. Das geht nich ohne API
- IsPwrHibernateAllowed
- SetSystemPowerState
Gruss
Fred
Kommentar von Hairichi am 07.11.2009 um 15:01
Hi
das ist zu viel Code
einfacher gehts so:
[code]Shell("shutdown.exe -s") 'herunterfahren
Shell("shutdown.exe -l") 'ausloggen
Shell("shutdown.exe -r") 'neustarten[code]
//Edit : Getestet in Visual Basic 2008
// Bitte testet es in VB6 und sagt mir obs geht
Gruß
Hairichi
Kommentar von Rainer Kornisch am 08.06.2009 um 09:12
einfach genial !
Für VB-Fans gibt es nichts besseres als ActiveVb
Kommentar von Fred am 15.05.2009 um 22:47
<< Von Seb am 15.05.2009 um 14:44
wofür wird ein 10kB ordner eigentlich gezipt?? >>
Weil ein zip File ein Container ist, ein in sich geschlossenes Objekt und als physischer File beliebig transportierbar und austauschbar.
Ein Ordner (engl: Folder, technisch: Directory) wird nur innerhalb Windows konsistent als Objekt erkannt. In Wirklichkeit ist er eben 'nur' eine logische Verzeichnisstruktur, welche die enthaltenen Objekte auflistet. Also: Nie Ordner herumschicken, sondern Zip-Container. Das Zip-Format ist längst ein weltweiter Defacto-Standard für den Datenaustausch. Etwa so, wie Schuhschachteln oder Zigarettenpackungen... ;)
Kommentar von Seb am 15.05.2009 um 14:44
wofür wird ein 10kB ordner eigentlich gezipt??
Kommentar von FisHFooD am 20.09.2008 um 14:05
Mit dem Standby Modus macht sichs jeder viel zu schwer....
einfach in VB:
shell "rundll32.exe PowrProf.dll, SetSuspendState"
fertig...
Kommentar von FisHFooD am 20.09.2008 um 14:05
Mit dem Standby Modus macht sichs jeder viel zu schwer....
einfach in VB:
shell "rundll32.exe PowrProf.dll, SetSuspendState"
fertig...
Kommentar von Timon am 31.01.2008 um 23:16
Für Stand-by und Hibernate(Ruhezustannd) http://www.microsoft.com/germany/msdn/library/visualtools/vb6/WindowsindenRuhezustandversetzen.mspx?mfr=true
Kommentar von rtzuj am 18.10.2007 um 20:02
wie funzt das?
Kommentar von DominikFe am 10.05.2007 um 17:54
Hier ein Link zu der Online MSDN. Dort könnt ihr sehen, wie man den Computer in den Ruhezustand und in den Stand-By-Zustand versetzt.
http://www.microsoft.com/germany/msdn/library/visualtools/vb6/WindowsindenRuhezustandversetzen.mspx?mfr=true
MFG
Dominik
Kommentar von Franz am 08.05.2007 um 14:47
Hat funktioniert!
Frage:
Wie kann ich Windows in den Ruhezustand schicken?
Kommentar von Diana am 07.05.2007 um 11:31
Hallo,
wie kann ich auch Windows Server 2003, ohne die Abfrage nach dem Grund, herunterfahren ?
Kommentar von Café-dot-neT am 15.10.2005 um 13:27
Seas aus Salzburg!
Ich wollte auch mal Fragen wie des is mit dem "InitiateSystemShutdown" Funktioniert! Ich bzw Wir haben 2 mal im Monat eine "große" (15 PCs) Lan-Party und da bin ich immer der Verwalter. Da da oft auch fremde leute kommen können müssen mir immer neue bestrafungen einfallen. und PC's runterfahren ist doch a supa Idee! allerdings habe ich keine ahnung wie das geht! habe mich schon mal gespielt aber nix is gegangen!
Wenn ihr mir den code vielleicht als email schickt, hat auch nicht jeder einsicht dafür! und das problem mit Trojanern... ist auch gelöst!
Ich für meinen Teil werde das Programm nur für den obigen Zweck benutzen! (klingt scheinheilig, is aber ernst gemeint)
GreeZ Sebi
Kommentar von Alfred Hellmüller am 10.02.2005 um 23:49
Mir fehlt hier die Hibernate-Funktion; EWX_HYBERNATE suche ich seit längerem vergeblich im API-Tschungel. Wäre ein Segen für Schnell-Booter, wird aber nicht von allen Motherboards unterstützt.
Freue mich auf einen Update des Tipps 0418...
Kommentar von E.Karus Kohl am 27.01.2005 um 19:57
Hallo habe Probleme kann meinen Computer nicht ausschalten
bzw runterfahren,bitte aber so erklären das ich es auch
verstehen kann. Bin Neuling was Computer anbelangt.
Hoffentlich kann mir jemand Helfen ?
Kommentar von @MessageBox am 30.12.2004 um 07:56
Bestimmt nich, du willst doch nur einen Trojaner coden, das kannste dir abschminken, keiner wird dir den Source geben!
Kommentar von MessageBox am 27.08.2004 um 12:41
frage:
kann mir jemand den source geben womit man fremde systeme über die ip herunterfährt?
Kommentar von Peyman am 12.07.2004 um 13:04
Hallo Hotte_K,
Wenn du auf einem alten Rechner xp installiert hast dann gehe mal in die Systemsteuerung zu Energieoptionen.
Unter dem Punkt "APM" musst Du den Haken wieder reinnehmen- XP scheint den bei manchen Rechnern nicht automatisch zu setzen.
Dann sollte der Rechner sich wieder abschalten.
Hoffe es hilft!
Kommentar von Peyman am 12.07.2004 um 11:51
Eine Neue Verknüfung auf dem Desktop erstellen mit dem folgendem Inhalt. Je nachdem was man machen möchte.
Workstation schlißen:
%windir%\system32\rundll32.exe\ user32.dll, LockWorkStation
PC Runterfahren:
%windir%\system32\shutdown -s -t 00 -f
PC Neustarten:
%windir%\system32\shutdown -r -t 00 -f
XP Windir=C:\Windows
W2K Windir=C:\Winnt
Es funtioniert unter XP und W2K
Kommentar von Hotte_K. am 22.06.2004 um 21:52
Hi miteinander!
Ich hab nun schon seit Tagen versucht, das Problem bei WIN XP PROF zu lösen, dass der Rechner einfach von selbst ganz herunter fährt.
Nach vielen Versuchen mit BIOS oder diversen Einstellungsänderungen geht es immer noch nicht. Es kommt immer noch die üble Mitteilung:"Sie können den Computer nun ausschalten" und dann muss ich noch 4 sec. auf den Ausknopf drücken, damit er sich ehrlich abschaltet.
Der Script hier sieht ja toll aus, doch wie baue ich so einen Script überhaupt ein? Hab NULL - Ahnung! Bitte um Hiiiilllllfffffeeeeee bitte, bitte.... will endlich, dass die Kiste normal runter fährt, sonst dreh ich durch ... uaaahhhhhhhh !
Kommentar von Thammi am 14.06.2004 um 14:51
@Rick:
Wie wäre es wenn du einen Timer mit dem Interval der Zeit bis zum gewünschten Shutdown machst, wenn du nen Zeitpunkt haben willst kannst du den Intervall ja über die Systemzeit beim Programmstart berechnen.
Kommentar von David Rosier am 13.05.2004 um 12:50
Das ist ja schon ein ganz tolles script.
ich selber bin leider total unbewandert mit vb.
mache eigentlich nur as.
ich habe aber ein problem was warscheinlich nur mit vb am elegantesten zu lösen ist.
ich möchte das per knopfdruck der pc neu startet und beim neutstart eine dosanwendung unter dos aufruft und nach dem beenden der anwendung wieder ins windows hochfährt.
symantec hat diese funktion bei norton ghost.
ich hab leider keine ahnung wie ich das lösen soll.
das eigentliche problem ist das ich bei einem bekannten einen e-prom programm in dos benutzen will. jedoch unter windows lässt er mich nicht auf den printerport zugreifen.
wenn natürlich jemand weiss wie ich das hinbekomme wäre das problem auch gelöst. es ist egal welchen port ich nehme 278 oder 378 irq und dma konflikte gibt es nicht.
vielleicht aber die möglichkeit diese ports irgenwohin zu mappen. os ist win2000
vielen dank im voraus für etwaige antworten ! :-)
Kommentar von Rick am 20.04.2004 um 00:48
Hi,
ich würde gerne wissen, wie ich diesen Tip umsetzen kann, dass WinXP zu einer bestimmten Zeit heruntergefahren wird, ohne dass das System bzw. andere Programme vor dieser Zeit ausgebremst werden.
Gruß Rick
Kommentar von Thomas Wittig am 27.01.2004 um 23:47
Hallo,
mein XP rechner schaltet beim herunterfahren auch nicht aus. Kann ich das Problem mit dem obigen Script lösen und wie muss ich das mnachen, habe keine Erfahrung ím Umgang mit Scripts.
Danke
Thomas
Kommentar von am 14.01.2004 um 14:04
Das der Pc kann aus geht und die Sach mit Standby sind nicht selbstverständlich , geht mal in die Systemsteuerung zu eurem Netzteil , dort kann man was ändern an modi und einstellungen
Kommentar von ralf am 13.05.2003 um 13:36
Leider wurde ich auch ein bißchen von dem Begriff Standby getäuscht. Ich suche händeringend nach einer Möglichkeit, um Windows 2000 per Progi oder Link in den Standbymodus zu versetzen.
Vielleicht weiß ja jemand Rat.
Danke
Kommentar von Eckhart Wörner am 06.04.2003 um 15:51
An alle, die möchten, dass sich ihr PC gleich ausschaltet und nicht die Meldung "Sie können den Computer jetzt ausschalten" anzeigt:
HKEY_LOCAL_MACHINE\Software\Microsoft\WindowsNT\Current Version\Winlogon muss auf 1 gesetzt werden!
Kommentar von Uwe am 20.03.2003 um 11:55
Leider habe ich auch das Problem, das sich der Computer ganz ausschalten sollte, und nicht mit dem Text "Sie können Ihren Computer jetzt ausschalten" stehen bleibt. Kann mir jemand helfen????
Danke
Kommentar von Christian Dresing am 02.12.2002 um 15:04
Frage: wie funktioniert der Shutdown von WinXP in vb.net?
Wäre über eine Antwort auch an meine Email-Adresse (c.dresing@simeonsbetriebe.de)sehr erfreut.
Danke schonmal im Voraus
MfG Chris
Kommentar von c:r:e:a:m2k2 am 12.06.2002 um 23:27
oh mann ! WIN XP herunterfahren.. das is ja so´n thema.. ich jedenfalls hatte zunächst kein problem, meiner ist sogar nach knopfdruck auf den ausschalter komplett heruntergefahren..alles super. doch ich hatte ärger mit meiner besonderen soundkarte, die nicht so recht mit acpi wollte. also hab ich es deaktiviert auf "standard-pc" modus. doch jetzt fährt er nur runter mit der elenden message "sie können den scheiss jetzt abschalten" ... ich seh kein standby button, kein apm, HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon funzt nicht....... nix klappt....wer hat ne idee...
Kommentar von Horst am 14.04.2002 um 13:42
Hatte unter WinXP
das Problem, dass ich
3 X !!!!!runterfahren
musste, bis die Kiste abschaltete.
Hiermit gehts
mit einem Mal.
Fehler sind nicht feststellbar.
Gratulation!!!!!
Kommentar von Ruru am 05.04.2002 um 16:55
mit InitiateSystemShutdownlassen sich auch andere Rechner herunterfahren ;)
Kommentar von Steffen Alexander am 02.04.2002 um 11:17
Danke für den Tipp,
ich habe mir das Prog. modifiziert damit immmer PowerOff gemacht wird und keine Form gezeigt wird. Unter NT mit angemeldeten User geht alles prima (auch über geplanten Vorgang).
Wenn ich mein prog über einen geplanten Vorgang starte und kein User angemeldet ist schaltet NT den Rechner nicht aus sondern bleibt im Dialog "Sie können den Rechner jetzt abschalten" stehen.
Wer kennt das Problem und weiß eine Lösung.
Danke Steffen
Kommentar von M. Zimmerbeutel am 05.02.2002 um 10:33
Der Tip funktioniert spitzenmässig, solange ich kein WinME verwende ... dann bleibt das System mit blinkendem Cursor stehen bei den PowerOff und Shutdown Optionen. Vieleicht hat ja jemand einen Tip für mich.
Gruss
Martin
Kommentar von Kurt am 10.12.2001 um 10:34
Geht der Tipp auch für Windows XP?
Kommentar von Roadrunner am 23.08.2001 um 22:29
Danke für diesen tollen Tipp ! Hat mir einiges an Arbeit erspart...