Hallo Zusammen!
Nach erfolglosem googlen brauche ich mal einen Gedankenanstoß!
Ich möchte durch einen Button in einer Form meinen Rechner runterfahren können.
Kann mir jmd da auf die Sprünge helfen? Wäre echt nett!
LG Toto
Hi,
unter mentalis.org findest du eine fertige Klasse genannt WindowsController. Damit kannst du ohne problem den Rechner Runtefahren / Neu starten usw.
Gruß
LordK
Programmieren in C# hält die grauen Zellen am Leben.
Es schärft alle fünf Sinne: den Schwachsinn, den Blödsinn, den Wahnsinn, den Unsinn und den Stumpfsinn.
ansonsten gehts per ExitWindowsEx API oder per WMI "Win32_OperatingSystem.Win32ShutDown" bzw. "Win32_OperatingSystem.ShutDown".
für beide vorgänge benötigt der user das SE_SHUTDOWN_NAME privilege (standardmässig gewährt)...
grtz
chief
Beispiel aus dem C# Codebook:
public static void ShutdownSystem(string hostName, string remoteAuthUser, string remoteAuthPassword, bool reboot)
{
// Den Hostnamen auf localhost setzen, wenn keiner übergeben wurde
if (hostName == null || hostName == "")
hostName = "localhost";
// ManagementScope-Objekt erzeugen, damit die EnablePrivileges-Eigenschaft
// gesetzt und die Authentifizierungs-Informationen übergeben werden können
ManagementScope scope = new ManagementScope(@"\\" + hostName + "\\root\\cimv2");
scope.Options.EnablePrivileges = true;
scope.Options.Username = remoteAuthUser;
scope.Options.Password = remoteAuthPassword;
// Win32_OperatingSystem-Instanz für das aktive Betriebssystem ermitteln
ManagementClass mc = new ManagementClass(scope, new ManagementPath("Win32_OperatingSystem"), new ObjectGetOptions());
ManagementObjectCollection moc = mc.GetInstances();
ManagementObjectCollection.ManagementObjectEnumerator mocEnumerator = moc.GetEnumerator();
mocEnumerator.MoveNext();
ManagementObject mo = (ManagementObject)mocEnumerator.Current;
// Rechner über die Win32Shutdown-Methode neu starten oder herunterfahren
if (reboot)
mo.InvokeMethod("Reboot", null);
else
mo.InvokeMethod("Shutdown", null);
// WMI-Objekte freigeben um den Speicher möglichst schnell zu entlasten
mo.Dispose();
moc.Dispose();
mc.Dispose();
}
ansonsten gehts per ExitWindowsEx API oder per WMI "Win32_OperatingSystem.Win32ShutDown" bzw. "Win32_OperatingSystem.ShutDown".
Im endeffekt macht die Klasse von Mentalis.org nichts anderes als dir den Zugriff auf die ExitWindowsEx API zu vereinfachen.
Programmieren in C# hält die grauen Zellen am Leben.
Es schärft alle fünf Sinne: den Schwachsinn, den Blödsinn, den Wahnsinn, den Unsinn und den Stumpfsinn.
Hallo LordK,
zu ExitWindowEx etwas Code für Win NT/Win2k/WinXP:
//==========================================================================
[StructLayout (LayoutKind.Sequential, Pack=1)]
public struct TOKEN_PRIVILEGES // tp
{
public int PrivilegeCount;
// Statt des zweite Elements:
// LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY];
// setze ich die Definition der Struktur LUID_AND_ATTRIBUTES direkt ein,
// da ANYSIZE_ARRAY = 1
public long Luid;
public int Attributes;
}
//==========================================================================
[DllImport ("user32.dll", CharSet=CharSet.Ansi, ExactSpelling=true,
SetLastError=true, CallingConvention=CallingConvention.Winapi)]
private static extern bool ExitWindowsEx (
int ulFlags,
int dwReserved
);
//==========================================================================
[DllImport ("kernel32.dll", CharSet=CharSet.Ansi, ExactSpelling=true,
SetLastError=false, CallingConvention=CallingConvention.Winapi)]
private static extern IntPtr GetCurrentProcess (
);
//==========================================================================
[DllImport ("advapi32.dll", CharSet=CharSet.Ansi, ExactSpelling=false,
SetLastError=true, CallingConvention=CallingConvention.Winapi)]
private static extern bool LookupPrivilegeValue (
string lpSystemName, // address of string specifying the system
string lpName, // address of string specifying the privilege
ref long lpLuid // address of locally unique identifier
);
//==========================================================================
[DllImport ("advapi32.dll", CharSet=CharSet.Ansi, ExactSpelling=true,
SetLastError=true, CallingConvention=CallingConvention.Winapi)]
private static extern bool OpenProcessToken (
IntPtr hProcess, // handle of process
int dwAccessMask, // desired access to process
ref IntPtr phToken // address of handle of open access token
);
//==========================================================================
[DllImport ("advapi32.dll", CharSet=CharSet.Ansi, ExactSpelling=true,
SetLastError=true, CallingConvention=CallingConvention.Winapi)]
private static extern bool AdjustTokenPrivileges (
IntPtr hTokenHandle, // handle of token that contains privileges
bool fDisableAllPrivileges, // flag for disabling all privileges
ref TOKEN_PRIVILEGES NewState, // address of new privilege information
int dwBufferLength, // size of previous information buffer
// Eigentlich kommt jetzt
// ref TOKEN_PRIVILEGES PreviousState, // address of previous information
// ref int pdwReturnLength // address of required buffer size
// Aber das wir fr beides null bergeben wollen, schreiben wir stattdessen
IntPtr PreviousState, // address of previous information
IntPtr pdwReturnLength // address of required buffer size
);
//==========================================================================
public const int EWX_LOGOFF = 0x00;
public const int EWX_SHUTDOWN = 0x01;
public const int EWX_REBOOT = 0x02;
public const int EWX_FORCE = 0x04;
public const int EWX_POWEROFF = 0x08;
private const int SE_PRIVILEGE_ENABLED = 0x00000002;
private const int TOKEN_QUERY = 0x0008;
private const int TOKEN_ADJUST_PRIVILEGES = 0x0020;
private const string SE_SHUTDOWN_NAME = "SeShutdownPrivilege";
//==========================================================================
public bool Shutdown (int iFlags)
{
bool fOK;
TOKEN_PRIVILEGES tp;
long luid;
IntPtr hToken;
int dwErrNo;
//-----------------------------------------------------------------------
// Vorgepl„nkel
//-----------------------------------------------------------------------
luid = 0;
fOK = LookupPrivilegeValue (null, SE_SHUTDOWN_NAME, ref luid);
if (!fOK) {
dwErrNo = Marshal.GetLastWin32Error ();
return false;
}
hToken = IntPtr.Zero;
fOK = OpenProcessToken (GetCurrentProcess (),
TOKEN_ADJUST_PRIVILEGES,
ref hToken);
if (!fOK) {
dwErrNo = Marshal.GetLastWin32Error ();
return false;
}
tp.PrivilegeCount = 1;
tp./*Privileges [0].*/Luid = luid;
tp./*Privileges [0].*/Attributes = SE_PRIVILEGE_ENABLED;
fOK = AdjustTokenPrivileges (hToken, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
if (!fOK) {
dwErrNo = Marshal.GetLastWin32Error ();
return false;
}
//-----------------------------------------------------------------------
// Jetzt wird's ernst
//-----------------------------------------------------------------------
fOK = ExitWindowsEx (iFlags, 0);
if (!fOK) {
dwErrNo = Marshal.GetLastWin32Error ();
return false;
}
return true;
}
}
herbivore
Suchhilfe: 1000 Worte
Hallo Herbivore,
hab Deinen Code in mein Projekt eingebunden und rufe ihn so auf
if (cb_shutdown.Checked) { bool b = Shutdown(1); }
Der Rechner fährt herunter und zeigt mir dann in VGA-Auflösung, dass ich den Rechner jetzt ausschalten könnte (Win2000). Drücken des Netzschalters bringt aber nichts, erst 4 Sekunden drücken.
Das will ich aber alles nicht, der Rechner soll einfach ausgehen. Dies ist auch möglich, wird Win über das Startmenü beendet, geht er auch aus.
Was muss ich ändern und was macht eigentlich der integer Parameter im Aufruf?
Gruß 11.08.2006
Versuch mal
Process.Start("cmd.exe shutdown -s");
oder so...
Klingt gut!
Wie kann ich auf die Cmd.exe zugreifen? So gehts nicht:
Process.Start("c:\WINNT\System32\cmd.exe shutdown -s");
In Deiner Version findet er es auch nicht.
EWX_POWEROFF ist Dein Freund ... also herbivore's Shutdown mit 8 statt mit 1 aufrufen...
Code kopieren ist das eine.... ihn zu verstehen was anderes...
Edit: Nachtrag
The flag passed to the ExitWindowsEx function determines whether the function performs a forced or normal log off, shutdown, or a restart. You can pass the following flags to this function:
EWX_FORCE - Forcibly terminates processes that do not respond to a shut down command.
NOTE: Using this flag can cause data loss because Windows does not send the messages WM_QUERYENDSESSION and WM_ENDSESSION to applications currently running in the computer. Use this flag only in cases where data loss is not critical.
EWX_LOGOFF - terminates all processes and then logs off the computer.
EWX_POWEROFF - shuts down the computer and turns off the power in systems with a power-off feature. Under Windows NT and Windows 2000, the process that calls the ExitWindowsEx function with this flag must have the SE_SHUTDOWN_NAME privilege. Windows 95, Windows 98, and Windows Me do not support or require this privilege.
EWX_REBOOT [ASCII 150] shuts down and then restarts the computer. Under Windows NT and Windows 2000, the process that calls the ExitWindowsEx function with this flag must have the SE_SHUTDOWN_NAME privilege. Windows 95, Windows 98, and Windows Me do not support or require this privilege.
EWX_SHUTDOWN - shuts down the computer to a point that is safe to turn off the power. All file buffers have been flushed to disk, and all running processes have stopped. Under Windows NT and Windows 2000, the process that calls the ExitWindowsEx function with this flag must have the SE_SHUTDOWN_NAME privilege. Windows 95, Windows 98, and Windows Me do not support or require this privilege.
Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...
Process.Start("c:\WINNT\System32\cmd.exe" , " shutdown -s");
so?
Kanns jetzt nicht testen....
Das Ganze soll natürlicha uch funktionieren, wenn der Rechner gesperrt ist. Meine Anwendung rechnte sehr lange und soll den Rechner runtefahren, wenn es fertig ist. Der Rechner sperrt sich nach 15 Minuten und das kann ich nicht aufheben. Die Variante mit if (cb_shutdown.Checked) { bool b = Shutdown(8); } funktioniert so leider nicht.
Auch das hier mag er nicht: Process.Start("c:\WINNT\System32\cmd.exe" , " shutdown -s");
Er ruft es zwar auf, aber er fährt nicht runter. Logge ich mich wieder ein, ist die Eingabeaufforderung noch offen.
Ok - Teilerfolg. Mit dem Tool DShutdown.exe kann man auch gesperrte Rechner runterfahren. Mir ist nur noch nicht klar, wie ich die Datei mit den entsprechenden Paramtern aufrufen soll:
string Pfad = Application.StartupPath.ToString() + "\\DShutdown.exe /NOW /FORCE";
Process.Start(Pfad);
So soll man aufrufen:
DShutdown.EXE [/Hn] [/Mn] [/DAYn] [/MONTH-n1-n2...] [IP:pcname] [/type] [OPTIONS] [/Fashions]
Mn: n = Minutes
Hn: n = Hour
DAYn: n = Day of the week (Mon-Sat) or of the month (1-31)
MONTHn: n = Month (Jan-Dec | All)
IP:pcname: pcname = name (or IP address) of remote computer
TYPE: LOGOFF
SHUTDOWN
REBOOT
FORCE
POWEROFF
FORCEIFHUNG
HIBERNATE
STANDBY
FORCEAFTERWAIT
HANGUP
DISABLELAN
CANCELIFUSERISLOGGED
STARTPROGRAM "ProgramPath | FilePath"
WRITELOG
SOUNDADVISE
EXITPROGRAM
WAKEONLAN: "Mac-Address"
WAKEUP
OPTIONS: SAVEONEXIT
SOUNDSTART
MODE: SHUTDOWNAFTER|SHUTDOWNAT|SHUTDOWNON
NOW
HIDDEN
SERVERMODE
NOCOUNTDOWN
INTERCEPTSHUTDOWN
Den Parameter /FORCE muss ich benutzen, so wie ich es angegeben habe, klappts aber nicht, er erkennt nicht, dass ich Parameter angebe.
Aber wenn das Tool das kann, dann sollte es eigentlich auch direkt aus C# gehen...
Ruf mal herbivore's code mit 12 auf (8+4)
Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...
Auch das hier mag er nicht: Process.Start("c:\WINNT\System32\cmd.exe" , " shutdown -s");
entweder
Process.Start("shutdown.exe" , "-s");
oder
Process.Start("cmd.exe" , "/c shutdown -s");
oder noch besser, nimm einafch eine von den klassen die dir angeboten wurden =)
mfG b3nJ
-edit-
Ok - Teilerfolg. Mit dem Tool DShutdown.exe kann man auch gesperrte Rechner runterfahren. Mir ist nur noch nicht klar, wie ich die Datei mit den entsprechenden Paramtern aufrufen soll:
string Pfad = Application.StartupPath.ToString() + "\\DShutdown.exe /NOW /FORCE"; Process.Start(Pfad);
[...]
Den Parameter /FORCE muss ich benutzen, so wie ich es angegeben habe, klappts aber nicht, er erkennt nicht, dass ich Parameter angebe.
so sollte es gehen:
Process.Start(pplication.StartupPath.ToString() + "\\DShutdown.exe", "/NOW /FORCE");
mfG b3nJ
Danke, mit dem Parameter "12" von Herbivores Code klappt es wie gewünscht, d.h. der Rechner fäht auch gesperrt runter.
Mich würde alledings einmal die Bedeutung aller möglichen Parameter interessieren.
Hallo 11.08.2006,
die Bedeutung der Parameter hat Programmierhans oben gepostet.
herbivore
Wenn du den shutdown Befehl von Windows benutzen willst musst das so machen:
Process.Start("shutdown -s -t 0")
-s steht für Herunterfahren und -t 0 steht für die Zeit, in diesem Fall 0 Sekunden.
Und man muss auch nicht vorher cmd.exe angeben
wie ich hier sehe gibs auch den command "WAKEONLAN" sowie "WAKEUP" auf der Shutdown.exe
Verfolge zurzeit auch die Idee den PC (oder die PC's) automatisch herunterfahren zu lassen, aber möchte auch das diese wieder automatisch hochkommen. Ist es mit obigen Befehlen also theoretisch möglich, wenn mind. 1 PC läuft, von diesem die anderen PC's zu "Wecken" ?? wäre natürlich sehr sehr geil 🙂
Hi
du kannst das auch direkt über C# realisieren.
--> http://dotnet-snippets.de/dns/wake-on-lan-SID608.aspx