Windows关机方法

一般关机用Shutdown便已足够,在xp下运行中输入shutdown -f -s -t 0便是0秒关机。在windows 7下则也可以输入shutdown -s -p

相应的,在程序中使用这个方法,在C++中很简单

 

 
  
char buf[ 40 ];

strcpy(buf,
" shutdown -f -s -t 0 " );

system(buf);

在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
NTSTATUS
NTAPI

NtShutdownSystem(


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是这样的

 

 
  
NTSYSAPI
NTSTATUS
NTAPI
NtSetSystemPowerState(
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以上的系统中,应该都可以起作用。

转载于:https://www.cnblogs.com/archen1983/archive/2010/10/26/1861925.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值