Câu trả lời:
Hoạt động bắt đầu với windows XP, không khả dụng trong win 2000 hoặc thấp hơn:
Đây là cách nhanh nhất để làm điều đó:
Process.Start("shutdown","/s /t 0");
Nếu không, sử dụng P / Gọi hoặc WMI như những người khác đã nói.
Chỉnh sửa: làm thế nào để tránh tạo cửa sổ
var psi = new ProcessStartInfo("shutdown","/s /t 0");
psi.CreateNoWindow = true;
psi.UseShellExecute = false;
Process.Start(psi);
Lấy từ: một bài Geekpedia
Phương pháp này sử dụng WMI để tắt các cửa sổ.
Bạn sẽ cần thêm một tham chiếu đến System.Man Management vào dự án của bạn để sử dụng cái này.
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);
}
}
Chủ đề này cung cấp mã cần thiết: http://bytes.com/forum/thread251367.html
nhưng đây là mã có liên quan:
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 );
}
Sử dụng:
DoExitWin( EWX_SHUTDOWN );
hoặc là
DoExitWin( EWX_REBOOT );
Các phương pháp khác nhau:
A. System.Diagnostics.Process.Start("Shutdown", "-s -t 10");
B. Thiết bị quản lý Windows (WMI)
C. System.R.78.InteropService Pinvoke
D. Quản lý hệ thống
Sau khi tôi gửi, tôi đã thấy rất nhiều người khác cũng đã đăng ...
Phương pháp cũ xấu xí. Sử dụng ExitWindowsEx
chức năng từ API Win32.
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);
Trong mã sản xuất, bạn nên kiểm tra các giá trị trả về của các lệnh gọi API, nhưng tôi đã bỏ qua nó để làm cho ví dụ rõ ràng hơn.
Ngắn và ngọt. Gọi một chương trình bên ngoài:
using System.Diagnostics;
void Shutdown()
{
Process.Start("shutdown.exe", "-s -t 00");
}
Lưu ý: Điều này gọi chương trình Shutdown.exe của Windows, vì vậy nó sẽ chỉ hoạt động nếu chương trình đó khả dụng. Bạn có thể gặp sự cố trên Windows 2000 (trong đó shutdown.exe chỉ khả dụng trong bộ tài nguyên) hoặc XP Embedded .
System.Diagnostics.Process.Start("shutdown", "/s /t 0")
Nên làm việc.
Để khởi động lại, nó / r
Điều này sẽ khởi động lại hộp PC trực tiếp và sạch sẽ, không có hộp thoại.
shutdown /s /t 0 //For shutdown
shutdown /r /t 0 //For restart
shutdown /h /t 0 //For hibernate
Ngoài ra, hãy thử nhập chúng vào CMD để có kết quả tương tự.
Lưu ý rằng đó shutdown.exe
chỉ là một trình bao bọc xung quanh InitiateSystemShutdownEx
, cung cấp một số chi tiết bị thiếu trongExitWindowsEx
Tôi gặp khó khăn khi cố gắng sử dụng phương pháp WMI được chấp nhận ở trên vì tôi luôn có quyền riêng tư không có ngoại lệ mặc dù chạy chương trình với tư cách quản trị viên.
Giải pháp là cho quá trình yêu cầu đặc quyền cho chính nó. Tôi đã tìm thấy câu trả lời tại http://www.dotnet247.com/247reference/msgs/58/292150.aspx được viết bởi một chàng trai tên là Richard Hill.
Tôi đã dán cách sử dụng cơ bản giải pháp của anh ấy bên dưới trong trường hợp liên kết đó đã cũ.
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;
}
}
}
Tôi đã thử phương pháp WMI của roomaroo để tắt Windows 2003 Server, nhưng nó sẽ không hoạt động cho đến khi tôi thêm `[STAThread] '(tức là mô hình luồng" Căn hộ một luồng ") vào khai báo Main ():
[STAThread]
public static void Main(string[] args) {
Shutdown();
}
Sau đó, tôi đã cố gắng tắt máy từ một luồng và để nó hoạt động, tôi cũng phải đặt "Trạng thái căn hộ" của luồng thành STA:
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
}
}
Tôi là một C # noob, vì vậy tôi không hoàn toàn chắc chắn về tầm quan trọng của các luồng STA trong việc tắt hệ thống (ngay cả sau khi đọc liên kết tôi đã đăng ở trên). Có lẽ ai đó khác có thể giải thích ...?
Main()
không cần [STAThread]
.
** Trả lời được xây dựng ...
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);
}
}
}
}
Sử dụng shutdown.exe. Để tránh sự cố khi truyền đối số, thực thi phức tạp, thực thi từ WindowForms sử dụng tập lệnh thực thi 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.Man Quản.Automation.dll nên được cài đặt trên HĐH và có sẵn trong GAC.
Xin lỗi vì tiếng Anh của tôi.
Không có phương thức riêng .net để tắt máy tính. Bạn cần P / Gọi lệnh gọi API ExitWindows hoặc ExitWindowsEx.
Nếu bạn muốn tắt máy tính từ xa thì bạn có thể sử dụng
Using System.Diagnostics;
trên bất kỳ nút bấm nào
{
Process.Start("Shutdown","-i");
}