Jawaban:
Bekerja dimulai dengan windows XP, tidak tersedia di win 2000 atau lebih rendah:
Ini adalah cara tercepat untuk melakukannya:
Process.Start("shutdown","/s /t 0");
Kalau tidak, gunakan P / Invoke atau WMI seperti yang dikatakan orang lain.
Sunting: cara menghindari membuat jendela
var psi = new ProcessStartInfo("shutdown","/s /t 0");
psi.CreateNoWindow = true;
psi.UseShellExecute = false;
Process.Start(psi);
Diambil dari: sebuah posting Geekpedia
Metode ini menggunakan WMI untuk mematikan windows.
Anda harus menambahkan referensi ke System.Management ke proyek Anda untuk menggunakan ini.
using System.Management;
void Shutdown()
{
ManagementBaseObject mboShutdown = null;
ManagementClass mcWin32 = new ManagementClass("Win32_OperatingSystem");
mcWin32.Get();
// You can't shutdown without security privileges
mcWin32.Scope.Options.EnablePrivileges = true;
ManagementBaseObject mboShutdownParams =
mcWin32.GetMethodParameters("Win32Shutdown");
// Flag 1 means we want to shut down the system. Use "2" to reboot.
mboShutdownParams["Flags"] = "1";
mboShutdownParams["Reserved"] = "0";
foreach (ManagementObject manObj in mcWin32.GetInstances())
{
mboShutdown = manObj.InvokeMethod("Win32Shutdown",
mboShutdownParams, null);
}
}
Utas ini menyediakan kode yang diperlukan: http://bytes.com/forum/thread251367.html
tapi ini kode yang relevan:
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential, Pack=1)]
internal struct TokPriv1Luid
{
public int Count;
public long Luid;
public int Attr;
}
[DllImport("kernel32.dll", ExactSpelling=true) ]
internal static extern IntPtr GetCurrentProcess();
[DllImport("advapi32.dll", ExactSpelling=true, SetLastError=true) ]
internal static extern bool OpenProcessToken( IntPtr h, int acc, ref IntPtr
phtok );
[DllImport("advapi32.dll", SetLastError=true) ]
internal static extern bool LookupPrivilegeValue( string host, string name,
ref long pluid );
[DllImport("advapi32.dll", ExactSpelling=true, SetLastError=true) ]
internal static extern bool AdjustTokenPrivileges( IntPtr htok, bool disall,
ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen );
[DllImport("user32.dll", ExactSpelling=true, SetLastError=true) ]
internal static extern bool ExitWindowsEx( int flg, int rea );
internal const int SE_PRIVILEGE_ENABLED = 0x00000002;
internal const int TOKEN_QUERY = 0x00000008;
internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
internal const string SE_SHUTDOWN_NAME = "SeShutdownPrivilege";
internal const int EWX_LOGOFF = 0x00000000;
internal const int EWX_SHUTDOWN = 0x00000001;
internal const int EWX_REBOOT = 0x00000002;
internal const int EWX_FORCE = 0x00000004;
internal const int EWX_POWEROFF = 0x00000008;
internal const int EWX_FORCEIFHUNG = 0x00000010;
private void DoExitWin( int flg )
{
bool ok;
TokPriv1Luid tp;
IntPtr hproc = GetCurrentProcess();
IntPtr htok = IntPtr.Zero;
ok = OpenProcessToken( hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok );
tp.Count = 1;
tp.Luid = 0;
tp.Attr = SE_PRIVILEGE_ENABLED;
ok = LookupPrivilegeValue( null, SE_SHUTDOWN_NAME, ref tp.Luid );
ok = AdjustTokenPrivileges( htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero );
ok = ExitWindowsEx( flg, 0 );
}
Pemakaian:
DoExitWin( EWX_SHUTDOWN );
atau
DoExitWin( EWX_REBOOT );
Metode yang berbeda:
SEBUAH. System.Diagnostics.Process.Start("Shutdown", "-s -t 10");
B. Instrumentasi Manajemen Windows (WMI)
C. System.Runtime.InteropServices Pinvoke
D. Manajemen Sistem
Setelah saya kirim, saya telah melihat begitu banyak orang lain juga telah diposting ...
Metode jelek jadul. Gunakan ExitWindowsEx
fungsi dari Win32 API.
using System.Runtime.InteropServices;
void Shutdown2()
{
const string SE_SHUTDOWN_NAME = "SeShutdownPrivilege";
const short SE_PRIVILEGE_ENABLED = 2;
const uint EWX_SHUTDOWN = 1;
const short TOKEN_ADJUST_PRIVILEGES = 32;
const short TOKEN_QUERY = 8;
IntPtr hToken;
TOKEN_PRIVILEGES tkp;
// Get shutdown privileges...
OpenProcessToken(Process.GetCurrentProcess().Handle,
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, out hToken);
tkp.PrivilegeCount = 1;
tkp.Privileges.Attributes = SE_PRIVILEGE_ENABLED;
LookupPrivilegeValue("", SE_SHUTDOWN_NAME, out tkp.Privileges.pLuid);
AdjustTokenPrivileges(hToken, false, ref tkp, 0U, IntPtr.Zero,
IntPtr.Zero);
// Now we have the privileges, shutdown Windows
ExitWindowsEx(EWX_SHUTDOWN, 0);
}
// Structures needed for the API calls
private struct LUID
{
public int LowPart;
public int HighPart;
}
private struct LUID_AND_ATTRIBUTES
{
public LUID pLuid;
public int Attributes;
}
private struct TOKEN_PRIVILEGES
{
public int PrivilegeCount;
public LUID_AND_ATTRIBUTES Privileges;
}
[DllImport("advapi32.dll")]
static extern int OpenProcessToken(IntPtr ProcessHandle,
int DesiredAccess, out IntPtr TokenHandle);
[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool AdjustTokenPrivileges(IntPtr TokenHandle,
[MarshalAs(UnmanagedType.Bool)]bool DisableAllPrivileges,
ref TOKEN_PRIVILEGES NewState,
UInt32 BufferLength,
IntPtr PreviousState,
IntPtr ReturnLength);
[DllImport("advapi32.dll")]
static extern int LookupPrivilegeValue(string lpSystemName,
string lpName, out LUID lpLuid);
[DllImport("user32.dll", SetLastError = true)]
static extern int ExitWindowsEx(uint uFlags, uint dwReason);
Dalam kode produksi Anda harus memeriksa nilai kembali panggilan API, tetapi saya mengabaikannya untuk membuat contoh lebih jelas.
Pendek dan manis. Panggil program eksternal:
using System.Diagnostics;
void Shutdown()
{
Process.Start("shutdown.exe", "-s -t 00");
}
Catatan: Ini menyebut program Windows Shutdown.exe, jadi itu hanya akan berfungsi jika program itu tersedia. Anda mungkin memiliki masalah pada Windows 2000 (di mana shutdown.exe hanya tersedia di kit sumber daya) atau XP Embedded .
System.Diagnostics.Process.Start("shutdown", "/s /t 0")
Harus bekerja
Untuk restart, ini / r
Ini akan memulai ulang kotak PC secara langsung dan bersih, tanpa dialog.
shutdown /s /t 0 //For shutdown
shutdown /r /t 0 //For restart
shutdown /h /t 0 //For hibernate
Juga, coba ketikkan ke CMD untuk hasil yang sama.
Perhatikan bahwa shutdown.exe
ini hanyalah pembungkus saja InitiateSystemShutdownEx
, yang menyediakan beberapa barang hilangExitWindowsEx
Saya mengalami kesulitan mencoba menggunakan metode WMI yang diterima di atas karena saya selalu mendapat hak istimewa tidak memegang pengecualian meskipun menjalankan program sebagai administrator.
Solusinya adalah proses meminta hak istimewa itu untuk dirinya sendiri. Saya menemukan jawabannya di http://www.dotnet247.com/247reference/msgs/58/292150.aspx ditulis oleh seorang pria bernama Richard Hill.
Saya telah menempelkan penggunaan dasar saya atas solusinya di bawah jika tautannya menjadi tua.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Management;
using System.Runtime.InteropServices;
using System.Security;
using System.Diagnostics;
namespace PowerControl
{
public class PowerControl_Main
{
public void Shutdown()
{
ManagementBaseObject mboShutdown = null;
ManagementClass mcWin32 = new ManagementClass("Win32_OperatingSystem");
mcWin32.Get();
if (!TokenAdjuster.EnablePrivilege("SeShutdownPrivilege", true))
{
Console.WriteLine("Could not enable SeShutdownPrivilege");
}
else
{
Console.WriteLine("Enabled SeShutdownPrivilege");
}
// You can't shutdown without security privileges
mcWin32.Scope.Options.EnablePrivileges = true;
ManagementBaseObject mboShutdownParams = mcWin32.GetMethodParameters("Win32Shutdown");
// Flag 1 means we want to shut down the system
mboShutdownParams["Flags"] = "1";
mboShutdownParams["Reserved"] = "0";
foreach (ManagementObject manObj in mcWin32.GetInstances())
{
try
{
mboShutdown = manObj.InvokeMethod("Win32Shutdown",
mboShutdownParams, null);
}
catch (ManagementException mex)
{
Console.WriteLine(mex.ToString());
Console.ReadKey();
}
}
}
}
public sealed class TokenAdjuster
{
// PInvoke stuff required to set/enable security privileges
[DllImport("advapi32", SetLastError = true),
SuppressUnmanagedCodeSecurityAttribute]
static extern int OpenProcessToken(
System.IntPtr ProcessHandle, // handle to process
int DesiredAccess, // desired access to process
ref IntPtr TokenHandle // handle to open access token
);
[DllImport("kernel32", SetLastError = true),
SuppressUnmanagedCodeSecurityAttribute]
static extern bool CloseHandle(IntPtr handle);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern int AdjustTokenPrivileges(
IntPtr TokenHandle,
int DisableAllPrivileges,
IntPtr NewState,
int BufferLength,
IntPtr PreviousState,
ref int ReturnLength);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern bool LookupPrivilegeValue(
string lpSystemName,
string lpName,
ref LUID lpLuid);
[StructLayout(LayoutKind.Sequential)]
internal struct LUID
{
internal int LowPart;
internal int HighPart;
}
[StructLayout(LayoutKind.Sequential)]
struct LUID_AND_ATTRIBUTES
{
LUID Luid;
int Attributes;
}
[StructLayout(LayoutKind.Sequential)]
struct _PRIVILEGE_SET
{
int PrivilegeCount;
int Control;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] // ANYSIZE_ARRAY = 1
LUID_AND_ATTRIBUTES[] Privileges;
}
[StructLayout(LayoutKind.Sequential)]
internal struct TOKEN_PRIVILEGES
{
internal int PrivilegeCount;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
internal int[] Privileges;
}
const int SE_PRIVILEGE_ENABLED = 0x00000002;
const int TOKEN_ADJUST_PRIVILEGES = 0X00000020;
const int TOKEN_QUERY = 0X00000008;
const int TOKEN_ALL_ACCESS = 0X001f01ff;
const int PROCESS_QUERY_INFORMATION = 0X00000400;
public static bool EnablePrivilege(string lpszPrivilege, bool
bEnablePrivilege)
{
bool retval = false;
int ltkpOld = 0;
IntPtr hToken = IntPtr.Zero;
TOKEN_PRIVILEGES tkp = new TOKEN_PRIVILEGES();
tkp.Privileges = new int[3];
TOKEN_PRIVILEGES tkpOld = new TOKEN_PRIVILEGES();
tkpOld.Privileges = new int[3];
LUID tLUID = new LUID();
tkp.PrivilegeCount = 1;
if (bEnablePrivilege)
tkp.Privileges[2] = SE_PRIVILEGE_ENABLED;
else
tkp.Privileges[2] = 0;
if (LookupPrivilegeValue(null, lpszPrivilege, ref tLUID))
{
Process proc = Process.GetCurrentProcess();
if (proc.Handle != IntPtr.Zero)
{
if (OpenProcessToken(proc.Handle, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
ref hToken) != 0)
{
tkp.PrivilegeCount = 1;
tkp.Privileges[2] = SE_PRIVILEGE_ENABLED;
tkp.Privileges[1] = tLUID.HighPart;
tkp.Privileges[0] = tLUID.LowPart;
const int bufLength = 256;
IntPtr tu = Marshal.AllocHGlobal(bufLength);
Marshal.StructureToPtr(tkp, tu, true);
if (AdjustTokenPrivileges(hToken, 0, tu, bufLength, IntPtr.Zero, ref ltkpOld) != 0)
{
// successful AdjustTokenPrivileges doesn't mean privilege could be changed
if (Marshal.GetLastWin32Error() == 0)
{
retval = true; // Token changed
}
}
TOKEN_PRIVILEGES tokp = (TOKEN_PRIVILEGES)Marshal.PtrToStructure(tu,
typeof(TOKEN_PRIVILEGES));
Marshal.FreeHGlobal(tu);
}
}
}
if (hToken != IntPtr.Zero)
{
CloseHandle(hToken);
}
return retval;
}
}
}
Saya mencoba metode WMI roomaroo untuk mematikan Windows 2003 Server, tetapi tidak akan berfungsi sampai saya menambahkan `[STAThread] '(yaitu model threading " Single Threaded Apartment ") ke deklarasi Main ():
[STAThread]
public static void Main(string[] args) {
Shutdown();
}
Saya kemudian mencoba untuk mematikan dari utas, dan untuk membuatnya berfungsi saya harus mengatur "Apartemen Negara" dari utas ke STA juga:
using System.Management;
using System.Threading;
public static class Program {
[STAThread]
public static void Main(string[] args) {
Thread t = new Thread(new ThreadStart(Program.Shutdown));
t.SetApartmentState(ApartmentState.STA);
t.Start();
...
}
public static void Shutdown() {
// roomaroo's code
}
}
Saya seorang C # noob, jadi saya tidak sepenuhnya yakin akan pentingnya thread STA dalam hal mematikan sistem (bahkan setelah membaca tautan yang saya posting di atas). Mungkin orang lain bisa menguraikan ...?
Main()
tidak perlu [STAThread]
.
** Jawaban Terinci ...
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
// Remember to add a reference to the System.Management assembly
using System.Management;
using System.Diagnostics;
namespace ShutDown
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnShutDown_Click(object sender, EventArgs e)
{
ManagementBaseObject mboShutdown = null;
ManagementClass mcWin32 = new ManagementClass("Win32_OperatingSystem");
mcWin32.Get();
// You can't shutdown without security privileges
mcWin32.Scope.Options.EnablePrivileges = true;
ManagementBaseObject mboShutdownParams = mcWin32.GetMethodParameters("Win32Shutdown");
// Flag 1 means we want to shut down the system
mboShutdownParams["Flags"] = "1";
mboShutdownParams["Reserved"] = "0";
foreach (ManagementObject manObj in mcWin32.GetInstances())
{
mboShutdown = manObj.InvokeMethod("Win32Shutdown", mboShutdownParams, null);
}
}
}
}
Gunakan shutdown.exe. Untuk menghindari masalah dengan melewatkan argumen, eksekusi kompleks, eksekusi dari WindowForms menggunakan skrip eksekusi PowerShell:
using System.Management.Automation;
...
using (PowerShell PowerShellInstance = PowerShell.Create())
{
PowerShellInstance.AddScript("shutdown -a; shutdown -r -t 100;");
// invoke execution on the pipeline (collecting output)
Collection<PSObject> PSOutput = PowerShellInstance.Invoke();
}
System.Management.Automation.dll harus diinstal pada OS dan tersedia di GAC.
Maaf untuk bahasa Inggris saya.
Tidak ada metode .net asli untuk mematikan komputer. Anda perlu P / Panggil panggilan API ExitWindows atau ExitWindowsEx.
Jika Anda ingin mematikan komputer dari jarak jauh maka Anda dapat menggunakannya
Using System.Diagnostics;
pada tombol apa saja klik
{
Process.Start("Shutdown","-i");
}