关机实现详解

以前一直想自己写一个定时关机的程序,但一直没有实现,现在终于写好了
对于这样的一个功能,其实是很简单的。里面主要设计的技术就是怎样去写关机的代码段了。
因而我主要解析一下自动关机的具体实现。

对于这个功能的实现由四步实现:

1.      调用OpenProcessToken函数,实现设置关机进程的访问标识(access token)(MSDN解释:opens the access token associated with a process.)

 

       该函数总共有三个参数,HANDLE ProcessHandle参数用于当前程序的实例句柄,可用函数GetCurrentHandle( )获取,DWORD DesiredAcess参数用于标识要获取的权限, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY分别表示可以实现或是屏蔽优先权和可以实现获取访问标识,PHANDLE TokenHandle用于获取获取访问标识后的句柄

 

2.      调用LookupPrivilegeValue函数,获取本地计算机唯一标识(LUID),并且获取关机权限.(MSDN解释:retrieves the locally unique identifier (LUID) used on a specified system to locally represent the specified privilege name.)

 

       BOOL WINAPI LookupPrivilegeValue(LPCTSTR lpSystemName, LPCTSTR lpName  PLUID lpLuid)第一个参数为要获取优先权的计算机名称,NULL值表示本地计算机,第二个参数为标识优先权的名称,可以是ID也可以为相应的字符串, SE_SHUTDOWN_NAME(或是"SeShutdownPrivilege")表示该进程具有关机的权限,SE_SECURITY_NAME表示有管理审核和安全日志权限.第三个参数用于传进变量获取已标识计算机的LUID.

 

3.      调用AdjustTokenPrivileges函数,获取关机的权限.(MSDN解释: enables or disables privileges in the specified access token.)

 

       BOOL WINAPI AdjustTokenPrivileges( HANDLE TokenHandle,BOOL DisableAllPrivileges, PTOKEN_PRIVILEGES NewState, DWORD BufferLength,  PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength);第一个参数为一个需要被修改的指针,并且它需要具有SE_PRIVILEGE_ENABLED权限,第二个参数true表示屏蔽所有权限,忽略NewState参数,若为false则用NewState参数设置当前参数,指向一个TOKEN_PRIVILEGES指针,BufferLength参数指示PreviousState参数的长度,如果PreviousState参数为NULL,则其为0,PreviousState参数指示前一TOKEN_PRIVILEGES指针, ReturnLength 参数应为NULL如果PreviousState参数为NULL

 

4.      调用ExitWindowsEx或是InitiateSystemShutdown函数实现最后的关机功能.

 

       BOOL ExitWindowsEx(UINT uFlags,DWORD dwReserved);用于立即关机uFlags标识关机选项,EWX_POWEROFF为关机,EWX_REBOOT为重启,后一个参数被保留

       BOOL WINAPI InitiateSystemShutdown(LPTSTR lpMachineName,LPTSTR lpMessage, DWORD dwTimeout, BOOL bForceAppsClosed,  BOOL bRebootAfterShutdown);记录关机的原因,lpMachineName参数标识主机名,NULL为本机,或是网络中的一个主机名。lpMessage在关机对话框中显示信息,可以为NULL值,dwTimeout设置对话框的显示时间,即对话框出现后的关机剩余时间,bForceAppsClosed若要强制关机,则设置为TRUE,它强制关闭为保存的文件,否则设置为FALSE, bRebootAfterShutdownTRUE为重启,FALSE为关机

 

程序代码如下:

 

TOKEN_PRIVILEGES tkp;
HANDLE hToken;
   
  if (!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
  {
   MessageBox("OpenProcessToken failed!");
  }

  LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,&tkp.Privileges[0].Luid); //获得本地机唯一的标识
  tkp.PrivilegeCount = 1; 
  tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,(PTOKEN_PRIVILEGES) NULL, 0); //
调整获得的权限

  if (GetLastError() != ERROR_SUCCESS)
  {
   MessageBox("AdjustTokenPrivileges enable failed!");
  }

  bool fResult =InitiateSystemShutdown(
     NULL,                 //
要关的计算机用户名,可在局域网网中关掉对方的机器,NULL表示关本机
     "
定时关机已经启动,请做好保存工作!",  // 显示的消息
     10,                                //
关机所需的时间
     TRUE,                                
     FALSE);                             //
设为TRUE为重起,设为FALSE为关机

  if(!fResult)
  {
   MessageBox("InitiateSystemShutdown failed.");
  }

  tkp.Privileges[0].Attributes = 0;
  AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,(PTOKEN_PRIVILEGES) NULL, 0);

  if (GetLastError() != ERROR_SUCCESS)
  {
   MessageBox("AdjustTokenPrivileges disable failed.");
  }

  ExitWindowsEx(EWX_SHUTDOWN,0);     //开始关机 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值