What's the best way to shut down the computer from a C# program?
从C#程序关闭计算机的最佳方法是什么?
I've found a few methods that work - I'll post them below - but none of them are very elegant. I'm looking for something that's simpler and natively .net.
我发现了一些有用的方法 - 我会在下面发布它们 - 但它们都不是很优雅。我正在寻找更简单和原生的东西.net。
18 个解决方案
#1
Works starting with windows XP, not available in win 2000 or lower:
从Windows XP开始,在win 2000或更低版本中不可用:
This is the quickest way to do it:
这是最快的方法:
Process.Start("shutdown","/s /t 0");
Otherwise use P/Invoke or WMI like others have said.
否则像其他人一样使用P / Invoke或WMI说。
Edit: how to avoid creating a window
编辑:如何避免创建窗口
var psi = new ProcessStartInfo("shutdown","/s /t 0");psi.CreateNoWindow = true;psi.UseShellExecute = false;Process.Start(psi);
#2
Taken from: a Geekpedia post
取自:Geekpedia帖子
This method uses WMI to shutdown windows.
此方法使用WMI关闭窗口。
You'll need to add a reference to System.Management to your project to use this.
您需要向项目添加对System.Management的引用才能使用它。
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); }}
#3
This thread provides the code necessary: http://bytes.com/forum/thread251367.html
该线程提供了必要的代码:http://bytes.com/forum/thread251367.html
but here's the relevant code:
但这是相关的代码:
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 IntPtrphtok );[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 ); }
Usage:
DoExitWin( EWX_SHUTDOWN );
or
DoExitWin( EWX_REBOOT );
#4
Different methods:
A. System.Diagnostics.Process.Start("Shutdown", "-s -t 10");
A. System.Diagnostics.Process.Start(“Shutdown”,“ - - -t 10”);
B. Windows Management Instrumentation (WMI)
B. Windows管理规范(WMI)
- http://www.csharpfriends.com/Forums/ShowPost.aspx?PostID=36953
- http://www.dreamincode.net/forums/showtopic33948.htm
C. System.Runtime.InteropServices Pinvoke
C. System.Runtime.InteropServices Pinvoke
D. System Management
D.系统管理
After I submit, I have seen so many others also have posted...
在我提交之后,我看到很多其他人也发布了...
#5
The old-school ugly method. Use the ExitWindowsEx
function from the Win32 API.
老派难看的方法。使用Win32 API中的ExitWindowsEx函数。
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 callsprivate 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);
In production code you should be checking the return values of the API calls, but I left that out to make the example clearer.
在生产代码中,您应该检查API调用的返回值,但我将其留下以使示例更清晰。
#6
Short and sweet. Call an external program:
简短又甜蜜。调用外部程序:
using System.Diagnostics; void Shutdown() { Process.Start("shutdown.exe", "-s -t 00"); }
Note: This calls Windows' Shutdown.exe program, so it'll only work if that program is available.You might have problems on Windows 2000 (where shutdown.exe is only available in the resource kit) or XP Embedded.
注意:这会调用Windows的Shutdown.exe程序,因此只有在该程序可用时才会起作用。您可能在Windows 2000(其中shutdown.exe仅在资源工具包中可用)或XP Embedded中遇到问题。
#7
System.Diagnostics.Process.Start("shutdown", "/s /t 0")
Should work.
For restart, it's /r
重新启动时,它是/ r
This will restart the PC box directly and cleanly, with NO dialogs.
这将直接干净地重新启动PC盒,没有对话框。
#8
You can launch the shutdown process:
您可以启动关闭过程:
-
shutdown -s -t 0
- Shutdown -
shutdown -r -t 0
- Restart
shutdown -s -t 0 - 关机
shutdown -r -t 0 - 重启
#9
I had trouble trying to use the WMI method accepted above because i always got privilige not held exceptions despite running the program as an administrator.
我在尝试使用上面接受的WMI方法时遇到了麻烦,因为尽管以管理员身份运行程序,但我始终没有保留异常。
The solution was for the process to request the privilege for itself. I found the answer at http://www.dotnet247.com/247reference/msgs/58/292150.aspx written by a guy called Richard Hill.
解决方案是让流程为自己请求权限。我在http://www.dotnet247.com/247reference/msgs/58/292150.aspx上找到了一个叫Richard Hill的人写的答案。
I've pasted my basic use of his solution below in case that link gets old.
我已经粘贴了我对他的解决方案的基本用法,以防链接变旧。
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; } }}
#10
Note that shutdown.exe is just a wrapper around InitiateSystemShutdownEx, which provides some niceties missing in ExitWindowsEx
请注意,shutdown.exe只是InitiateSystemShutdownEx的包装,它提供了ExitWindowsEx中缺少的一些细节。
#11
Just to add to Pop Catalin's answer, here's a one liner which shuts down the computer without displaying any windows:
只是为了添加Pop Catalin的答案,这里是一个关闭计算机而不显示任何窗口的单行程序:
Process.Start(new ProcessStartInfo("shutdown", "/s /t 0") { CreateNoWindow = true, UseShellExecute = false});
#12
There is no .net native method for shutting off the computer. You need to P/Invoke the ExitWindows or ExitWindowsEx API call.
关闭计算机没有.net本机方法。您需要P / Invoke ExitWindows或ExitWindowsEx API调用。
#13
I tried roomaroo's WMI method to shutdown Windows 2003 Server, but it would not work until I added `[STAThread]' (i.e. "Single Threaded Apartment" threading model) to the Main() declaration:
我尝试使用roomaroo的WMI方法来关闭Windows 2003 Server,但是直到我将'[STAThread]'(即“Single Threaded Apartment”线程模型)添加到Main()声明后它才会起作用:
[STAThread]public static void Main(string[] args) { Shutdown();}
I then tried to shutdown from a thread, and to get that to work I had to set the "Apartment State" of the thread to STA as well:
然后我尝试从一个线程关闭,为了使其工作,我必须将线程的“公寓状态”设置为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 }}
I'm a C# noob, so I'm not entirely sure of the significance of STA threads in terms of shutting down the system (even after reading the link I posted above). Perhaps someone else can elaborate...?
我是一个C#noob,所以我不完全确定STA线程在关闭系统方面的重要性(即使在阅读了我上面发布的链接之后)。也许别人可以详细阐述......?
#14
**Elaborated Answer...
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 assemblyusing 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); } } }}
#15
Use shutdown.exe. To avoid problem with passing args, complex execution, execution from WindowForms use PowerShell execute script:
使用shutdown.exe。为了避免传递args,复杂执行的问题,从WindowForms执行使用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 should be installed on OS and available in GAC.
System.Management.Automation.dll应安装在操作系统上,并在GAC中提供。
Sorry for My english.
对不起我的英语不好。
#16
If you want to shut down computer remotely then you can use
如果要远程关闭计算机,则可以使用
Using System.Diagnostics;
on any button click
在任何按钮点击
{ Process.Start("Shutdown","-i");}
#17
If you add the System.Windows.Forms reference to your project, then you can find in this namespace the Application class that has static methods. One of them is what you want/need/seeking, and it is called "SetSuspendState". I used this function in the past, and with it I succeed to shut down my computer easily. There are options how you want to shut down your computer with this function. It takes 3 parameters. First the enum PowerState (Hibernate or Suspend), second the bool force, and third the bool disableWakeEvent. You can read about this function more extendly in the internet. The following execution line will shut down your computer as you expected (I hope so):
如果将System.Windows.Forms引用添加到项目中,则可以在此命名空间中找到具有静态方法的Application类。其中一个是你想要/需要/寻求的东西,它被称为“SetSuspendState”。我过去使用过这个功能,有了它,我成功地轻松关闭了我的电脑。您可以选择使用此功能关闭计算机。它需要3个参数。首先是enum PowerState(Hibernate或Suspend),第二个是bool force,第三个是bool disableWakeEvent。您可以在互联网上更加了解这个功能。以下执行行将按预期关闭计算机(我希望如此):
System.Windows.Forms.Application.SetSuspendState(PowerState.Hibernate, true, false);
#18
#include<stdio.h>#include<stdlib.h>int main(){ system("C:\\Windows\\System32\\shutdown /s/t 0"); return 0;}
#1
Works starting with windows XP, not available in win 2000 or lower:
从Windows XP开始,在win 2000或更低版本中不可用:
This is the quickest way to do it:
这是最快的方法:
Process.Start("shutdown","/s /t 0");
Otherwise use P/Invoke or WMI like others have said.
否则像其他人一样使用P / Invoke或WMI说。
Edit: how to avoid creating a window
编辑:如何避免创建窗口
var psi = new ProcessStartInfo("shutdown","/s /t 0");psi.CreateNoWindow = true;psi.UseShellExecute = false;Process.Start(psi);
#2
Taken from: a Geekpedia post
取自:Geekpedia帖子
This method uses WMI to shutdown windows.
此方法使用WMI关闭窗口。
You'll need to add a reference to System.Management to your project to use this.
您需要向项目添加对System.Management的引用才能使用它。
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); }}
#3
This thread provides the code necessary: http://bytes.com/forum/thread251367.html
该线程提供了必要的代码:http://bytes.com/forum/thread251367.html
but here's the relevant code:
但这是相关的代码:
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 IntPtrphtok );[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 ); }
Usage:
DoExitWin( EWX_SHUTDOWN );
or
DoExitWin( EWX_REBOOT );
#4
Different methods:
A. System.Diagnostics.Process.Start("Shutdown", "-s -t 10");
A. System.Diagnostics.Process.Start(“Shutdown”,“ - - -t 10”);
B. Windows Management Instrumentation (WMI)
B. Windows管理规范(WMI)
- http://www.csharpfriends.com/Forums/ShowPost.aspx?PostID=36953
- http://www.dreamincode.net/forums/showtopic33948.htm
C. System.Runtime.InteropServices Pinvoke
C. System.Runtime.InteropServices Pinvoke
D. System Management
D.系统管理
After I submit, I have seen so many others also have posted...
在我提交之后,我看到很多其他人也发布了...
#5
The old-school ugly method. Use the ExitWindowsEx
function from the Win32 API.
老派难看的方法。使用Win32 API中的ExitWindowsEx函数。
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 callsprivate 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);
In production code you should be checking the return values of the API calls, but I left that out to make the example clearer.
在生产代码中,您应该检查API调用的返回值,但我将其留下以使示例更清晰。
#6
Short and sweet. Call an external program:
简短又甜蜜。调用外部程序:
using System.Diagnostics; void Shutdown() { Process.Start("shutdown.exe", "-s -t 00"); }
Note: This calls Windows' Shutdown.exe program, so it'll only work if that program is available.You might have problems on Windows 2000 (where shutdown.exe is only available in the resource kit) or XP Embedded.
注意:这会调用Windows的Shutdown.exe程序,因此只有在该程序可用时才会起作用。您可能在Windows 2000(其中shutdown.exe仅在资源工具包中可用)或XP Embedded中遇到问题。
#7
System.Diagnostics.Process.Start("shutdown", "/s /t 0")
Should work.
For restart, it's /r
重新启动时,它是/ r
This will restart the PC box directly and cleanly, with NO dialogs.
这将直接干净地重新启动PC盒,没有对话框。
#8
You can launch the shutdown process:
您可以启动关闭过程:
-
shutdown -s -t 0
- Shutdown -
shutdown -r -t 0
- Restart
shutdown -s -t 0 - 关机
shutdown -r -t 0 - 重启
#9
I had trouble trying to use the WMI method accepted above because i always got privilige not held exceptions despite running the program as an administrator.
我在尝试使用上面接受的WMI方法时遇到了麻烦,因为尽管以管理员身份运行程序,但我始终没有保留异常。
The solution was for the process to request the privilege for itself. I found the answer at http://www.dotnet247.com/247reference/msgs/58/292150.aspx written by a guy called Richard Hill.
解决方案是让流程为自己请求权限。我在http://www.dotnet247.com/247reference/msgs/58/292150.aspx上找到了一个叫Richard Hill的人写的答案。
I've pasted my basic use of his solution below in case that link gets old.
我已经粘贴了我对他的解决方案的基本用法,以防链接变旧。
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; } }}
#10
Note that shutdown.exe is just a wrapper around InitiateSystemShutdownEx, which provides some niceties missing in ExitWindowsEx
请注意,shutdown.exe只是InitiateSystemShutdownEx的包装,它提供了ExitWindowsEx中缺少的一些细节。
#11
Just to add to Pop Catalin's answer, here's a one liner which shuts down the computer without displaying any windows:
只是为了添加Pop Catalin的答案,这里是一个关闭计算机而不显示任何窗口的单行程序:
Process.Start(new ProcessStartInfo("shutdown", "/s /t 0") { CreateNoWindow = true, UseShellExecute = false});
#12
There is no .net native method for shutting off the computer. You need to P/Invoke the ExitWindows or ExitWindowsEx API call.
关闭计算机没有.net本机方法。您需要P / Invoke ExitWindows或ExitWindowsEx API调用。
#13
I tried roomaroo's WMI method to shutdown Windows 2003 Server, but it would not work until I added `[STAThread]' (i.e. "Single Threaded Apartment" threading model) to the Main() declaration:
我尝试使用roomaroo的WMI方法来关闭Windows 2003 Server,但是直到我将'[STAThread]'(即“Single Threaded Apartment”线程模型)添加到Main()声明后它才会起作用:
[STAThread]public static void Main(string[] args) { Shutdown();}
I then tried to shutdown from a thread, and to get that to work I had to set the "Apartment State" of the thread to STA as well:
然后我尝试从一个线程关闭,为了使其工作,我必须将线程的“公寓状态”设置为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 }}
I'm a C# noob, so I'm not entirely sure of the significance of STA threads in terms of shutting down the system (even after reading the link I posted above). Perhaps someone else can elaborate...?
我是一个C#noob,所以我不完全确定STA线程在关闭系统方面的重要性(即使在阅读了我上面发布的链接之后)。也许别人可以详细阐述......?
#14
**Elaborated Answer...
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 assemblyusing 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); } } }}
#15
Use shutdown.exe. To avoid problem with passing args, complex execution, execution from WindowForms use PowerShell execute script:
使用shutdown.exe。为了避免传递args,复杂执行的问题,从WindowForms执行使用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 should be installed on OS and available in GAC.
System.Management.Automation.dll应安装在操作系统上,并在GAC中提供。
Sorry for My english.
对不起我的英语不好。
#16
If you want to shut down computer remotely then you can use
如果要远程关闭计算机,则可以使用
Using System.Diagnostics;
on any button click
在任何按钮点击
{ Process.Start("Shutdown","-i");}
#17
If you add the System.Windows.Forms reference to your project, then you can find in this namespace the Application class that has static methods. One of them is what you want/need/seeking, and it is called "SetSuspendState". I used this function in the past, and with it I succeed to shut down my computer easily. There are options how you want to shut down your computer with this function. It takes 3 parameters. First the enum PowerState (Hibernate or Suspend), second the bool force, and third the bool disableWakeEvent. You can read about this function more extendly in the internet. The following execution line will shut down your computer as you expected (I hope so):
如果将System.Windows.Forms引用添加到项目中,则可以在此命名空间中找到具有静态方法的Application类。其中一个是你想要/需要/寻求的东西,它被称为“SetSuspendState”。我过去使用过这个功能,有了它,我成功地轻松关闭了我的电脑。您可以选择使用此功能关闭计算机。它需要3个参数。首先是enum PowerState(Hibernate或Suspend),第二个是bool force,第三个是bool disableWakeEvent。您可以在互联网上更加了解这个功能。以下执行行将按预期关闭计算机(我希望如此):
System.Windows.Forms.Application.SetSuspendState(PowerState.Hibernate, true, false);
#18
#include<stdio.h>#include<stdlib.h>int main(){ system("C:\\Windows\\System32\\shutdown /s/t 0"); return 0;}