Als ich kürzlich ein Website-Backend-Verwaltungssystem entwarf, dachte ich darüber nach, ob ich den Windows-Server über die Seite neu starten könnte.
Ich habe bei Google einenCode
gefunden, der sehr häufig vorkommt
Wird beim Schreiben von Desktop-Anwendungen wie Konsolen- oder Windows Form-Programmen verwendet. Es kann normal ausgeführt werden, der Aufruf über ASP.NET kann jedoch nicht weitergeleitet werden
, da bis auf einige Zeilen die anderen Codes zum Neustarten erforderlich sind Erstellen Sie
eine neue Klasse und geben Sie den folgenden Code ein:
Beim Aufruf der Win-API ist InteropServices unverzichtbar.
Verwenden des Systems;
Verwenden von System.Runtime.InteropServices;
Dann gibt es eine Reihe von Konstantendeklarationen: protected const int SE_PRIVILEGE_ENABLED = 0x2;
protected const int TOKEN_QUERY = 0x8;
protected const int TOKEN_ADJUST_PRIVILEGES = 0x20;
protected const string SE_SHUTDOWN_NAME = "SeShutdownPrivilege";
protected const int EWX_LOGOFF = 0x0;
protected const int EWX_SHUTDOWN = 0x1;
protected const int EWX_REBOOT = 0x2;
protected const int EWX_FORCE = 0x4;
protected const int EWX_POWEROFF = 0x8;
protected const int EWX_FORCEIFHUNG = 0x10;
Definieren Sie die Luid-Struktur und achten Sie auf die Attribute: [StructLayout(LayoutKind.Sequential, Pack=1)]
geschützte Struktur LuidStruct {
public int Count;
öffentlicher langer Luid;
public int Attr;
}
Deklaration der externen nicht verwalteten DLL: [DllImport("kernel32.dll", ExactSpelling=true)]
protected static extern IntPtr GetCurrentProcess();
[DllImport("advapi32.dll", SetLastError=true)]
protected static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr phtok);
[DllImport("advapi32.dll", SetLastError=true)]
protected static extern bool LookupPrivilegeValue(string host, string name, ref long pluid);
[DllImport("advapi32.dll", SetLastError=true, ExactSpelling=true)]
protected static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall, ref LuidStruct newst, int len, IntPtr prev, IntPtr relen);
[DllImport("user32.dll", SetLastError=true, ExactSpelling=true)]
protected static extern bool ExitWindowsEx(int flg, int rea);
Auf Betriebssystemen auf NT-Ebene müssen Sie Windows zunächst darüber informieren, dass das System heruntergefahren wird, und die Berechtigung zum Herunterfahren einholen.
Folgendes ist die Implementierung von Herunterfahren, Neustart und Abmelden: protected static void DoExitWindows(int flg) {
LuidStructtp;
IntPtr hproc = GetCurrentProcess();
IntPtr htok = IntPtr.Zero;
OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok);
tp.Count = 1;
tp.Luid = 0;
tp.Attr = SE_PRIVILEGE_ENABLED;
LookupPrivilegeValue(null, SE_SHUTDOWN_NAME, ref tp.Luid);
AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
ExitWindowsEx(flg, 0);
}
public static void Shutdown() {
DoExitWindows(EWX_SHUTDOWN);
}
public static void Reboot() {
DoExitWindows(EWX_REBOOT | EWX_FORCE);
}
public static void Logoff() {
DoExitWindows(EWX_LOGOFF);
}
An diesem Punkt endet der Neustartcode. Dieser Code kann in einer interaktiven Umgebung gut funktionieren, das heißt, wenn sich der Benutzer bei Windows angemeldet hat,
ASP.NET jedoch in einer nicht interaktiven Umgebung ausgeführt wird, und suchen Sie nach ExitWindowsEx Funktionsdefinition. Ich habe diese Passage unten gefunden:
Die ExitWindowsEx-Funktion kehrt zurück, sobald sie den Herunterfahrvorgang eingeleitet hat. Die Funktion ist so konzipiert, dass sie alle Prozesse in der Anmeldesitzung des Aufrufers stoppt. Wenn Sie nicht der interaktive Benutzer sind, kann die Funktion daher erfolgreich ausgeführt werden ohne den Computer tatsächlich herunterzufahren, verwenden Sie die Funktion „InitiateSystemShutdown“ oder „InitiateSystemShutdownEx
“
. DllImport("advapi32. dll", SetLastError=true, ExactSpelling=false)]
protected static extern bool InitiateSystemShutdown(string name, string msg, int timeout, bool force, bool reboot);
Parametererklärung:
Name: Maschinenname, der zum Neustarten anderer Maschinen im LAN verwendet wird. Wenn er null ist, handelt es sich um die lokale Maschine.
msg: Neustartmeldung, wird im Neustartmeldungsfeld angezeigt und auch als Meldungsprotokoll in Windows 2003 und XP gespeichert
Timeout: Wenn es nicht 0 ist, wird ein Neustart-Meldungsfeld angezeigt und der Countdown wird nach Timeout-Sekunden neu gestartet.
erzwingen: Neustart erzwingen, nicht warten, bis die Anwendung fragt, ob die Arbeit gespeichert werden soll, für den Server sollte dies wahr sein
reboot: Handelt es sich um einen Neustart? Führen Sie den Shutdown-Vorgang für den Server durch.
Rufen Sie zunächst AdjustTokenPrivileges auf, um das Privileg abzurufen die ASP.NET-Seite: InitiateSystemShutdown(null,null,0, true,true);
Das System wird neu gestartet.
Wenn Sie die Maschine neu starten, wird höchstwahrscheinlich ein Fehler „Dienst nicht verfügbar“ zurückgegeben. Dies liegt daran, dass das System begonnen hat, verschiedene Prozesse zu beenden, bevor die Ausführung von ASP.NET abgeschlossen ist Natürlich ist der ASP.NET-Prozess normal, obwohl die Leistung etwas unangenehm erscheint.
Da ich den Test nur auf meinem eigenen Computer bestanden habe, habe ich das Berechtigungsproblem nicht im Detail untersucht und kann daher nicht sicher sein Ob es auf einem allgemeinen Server normal ausgeführt werden kann,
dachte ich zunächst nur, dass es durch Berechtigungssimulation gelöst werden könnte, d. h. in den Abschnitt system.web der Datei web.config, schreiben Sie <identity impersonate="true" userName="Administrator" passwort="pass">, aber es wurde nicht bestätigt. Ich werde es versuchen, wenn ich Zeit habe. web.config ist nicht sehr sicher, daher müssen Sie hier möglicherweise DPAPI verwenden, was etwas weit hergeholt ist, also lassen Sie uns hier zunächst aufhören.