电脑软硬件应用网
当前位置: 电脑软硬件应用网 > 设计学院 > 网络编程 > C语言 > 正文
C#实现Windows关机的代码
C#实现Windows关机的代码
2010-10-27 13:28:53  文/网络收集   出处:电脑软硬件应用网   

本文和大家分享一下使用C#编写实现关机的方法。一般关机用Shutdown便已足够,在xp下运行中输入shutdown -f -s -t 0便是0秒关机。在windows 7下则也可以输入shutdown -s -p
在C#中

ProcessStartInfo shutdown = new ProcessStartInfo();
           shutdown.FileName = "shutdown.exe";
            shutdown.Arguments = "-f -s -t 0";
            Process.Start(shutdown);

但是这都是调用系统的关机程序来关机,那我们的进程可不可以自己关机呢?答案是肯定的。
系统关机需要若干步骤,前几步大概都是退出进程,退出用户之类的系统操作,和关机这个主题关系不大。不执行顶多损失未保存数据,但是有的时候关机本身比较重要,需要优先执行,那么就要提到windows的关闭系统的函数NtShutdownSystem();
要让自己的进程执行关机操作,首先要让自己的进程有关机的权限,系统的权限种类在MSDN的Privilege Constants中有详细叙述,具体定义在windows sdk的winNT.h文件中7806行的位置。
关机所需的权限是SeShutdownPrivilege,我们在C++中可以这样获得
if(OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,   
             &hToken))   
     {   
         TOKEN_PRIVILEGES tkp;   
         LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);   
         tkp.PrivilegeCount = 1;   
         tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;   
         AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, NULL, 0);   
         CloseHandle(hToken);   
     }   
 
在也可以使用API来改变权限,这个例子用C#来写
 
 [DllImport("ntdll.dll")]        private static extern void RtlAdjustPrivilege(int Privilege, bool Enable, bool Thread, out bool OldValue);其中Privilege是权限的枚举值,Enable是表示开启还是关闭, Thread表示是改变当前线程权限还是改变整个进程权限,最后一个输出是原来此权限的值。
SeShutdownPrivilege的枚举值是19,那么执行如下代码就可以让此线程获得关机的能力
 
bool a;RtlAdjustPrivilege(19, true, false, out a);
 
关闭系统的话调用NtShutdownSystem即可,此函数不载于MSDN中,其描述可见MSDN未载之API,摘录如下
 
NTSYSAPI NTSTATUSNTAPINtShutdownSystem(  IN SHUTDOWN_ACTION      Action );
 
其中Shutdown_action是一个枚举 其枚举类型为
 
 enum SHUTDOWN_ACTION {    ShutdownNoReboot,    ShutdownReboot,    ShutdownPowerOff} 
 
相应的,调用此API的C++代码为

代码
DWORD (__stdcall *NtShutdownSystem)(SHUTDOWN_ACTION);    HMODULE hMod;         hMod = LoadLibraryA("ntdll.dll");        if(hMod)         {             NtShutdownSystem = (DWORD(__stdcall *)(SHUTDOWN_ACTION))GetProcAddress(hMod, "NtShutdownSystem");             NtShutdownSystem(ShutdownNoReboot);         }    
C#代码为
 
  [DllImport("NTDLL.dll")]        public static extern int NtShutdownSystem(SHUTDOWN_ACTION action);NtShutdownSystem(SHUTDOWN_ACTION.ShutdownNoReboot);NtShutdownSystem其实算比较正常的关机,毕竟还是执行了关闭硬盘,清空页面文件和缓冲区等操作,WINNT还提供一个API,可以使我们设置电源状态,这个API就是NtSetSystemPowerState
NtSetSystemPowerState这个API不载于MSDN也不载于NTInternal,但是网上仍然能找到这个API的描述,这个API是这样的
 
NTSYSAPINTSTATUSNTAPINtSetSystemPowerState(IN POWER_ACTION SystemAction,IN SYSTEM_POWER_STATE MinSystemState,IN ULONG Flags); 
其中POWER_ACTION表示关机动作,SYSTEM_POWER_STATE表示系统电源状态,Flags则表示系统关机原因。这三者在MSDN中都有详细记载,Flags的值则在Windows SDK的Reason.h中定义。
他们的值是这样的
 
代码
 enum SYSTEM_POWER_STATE {  PowerSystemUnspecified   = 0,  PowerSystemWorking       = 1,  PowerSystemSleeping1     = 2,  PowerSystemSleeping2     = 3,  PowerSystemSleeping3     = 4,  PowerSystemHibernate     = 5,  PowerSystemShutdown      = 6,  PowerSystemMaximum       = 7 }      enum POWER_ACTION {  PowerActionNone            = 0,  PowerActionReserved,  PowerActionSleep,  PowerActionHibernate,  PowerActionShutdown,  PowerActionShutdownReset,  PowerActionShutdownOff,  PowerActionWarmEject } 
在C#中调用NtSetSystemPowerState来关机的代码如下
 
代码
[DllImport("NTDLL.dll")]        public static extern int NtSetSystemPowerState(POWER_ACTION action, SYSTEM_POWER_STATE status, uint flag);... NtSetSystemPowerState(POWER_ACTION.PowerActionShutdownOff, SYSTEM_POWER_STATE.PowerSystemShutdown, 0x80000000);
如此便可以实现快速的关机了。但是除此之外,我想windows的关机方法还有很多,应该有更加便捷的关机方法,来为日常应用提供方便。文本中提到的关机方法,在Windows7和XP下测试通过,在2000以上的系统中,应该都可以起作用。

  • 上一篇文章:

  • 下一篇文章:
  • 最新热点 最新推荐 相关文章
    用C语言实现的闹钟程序
    用动态规划法求组和数的算法
    循环结构程序具有哪3个组成部分?
    const成员函数有什么特点?
    c语言求平均分程序
    一道关于指针的C语言题
    C语言求3个整数的最大公约数
    BM模式匹配算法C语言实现
    从键盘输入任意5个4位整数存入数组a…
    求1到1000之间能被7和11整除,但不能…
    关于45IT | About 45IT | 联系方式 | 版权声明 | 网站导航 |

    Copyright © 2003-2011 45IT. All Rights Reserved 浙ICP备09049068号