VC中使用ExitWindowsEx重启电脑

发布时间:2016年4月1日 作者:未知 查看次数:1262

VC中使用ExitWindowsEx重启电脑

自:
http://blog.sina.com.cn/s/blog_5406392d0100dhsg.html

当用户修改了Windows里面的一些设置,Windows经常会提问是否要重新启动计算机,当用户点Yes的时候,计算机将会自动重启。这个就是API函数ExitWindowsEx的一个典型的应用。
  ExitWindowsEx,顾名思义就是退出Windows的函数,它有两个参数,第一个是退出Windows的选项,常用的有:EWX_REBOOT(重新启动计算机),EWX_SHUTDOWN(关闭计算机),EWX_LOGOFF(注销当前用户),第二个参数系统保留没有使用,可设为0。
  在自编的程序中(如:注册表修改程序),当用户修改了某项设置需要重新启动计算机的时候,就要使用EWX_REBOOT选项重启计算机,如:
ExitWindowsEx(EWX_REBOOT,0);
使用WX_SHUTDOWN选项,可以实现关机,如:
ExitWindowsEx(EWX_SHUTDOWN,0);
当需要注销的时候,就使用EWX_LOGOFF选项,如:
ExitWindowsEx(EWX_LOGOFF,0);
windows95/98/me中直接调用就可以了
ExitWindowsEx(EWX_SHUTDOWN, 0); //关机
ExitWindowsEx(EWX_REBOOT, 0); //重启
Windows NT/2000 及后续版本则有安全性要求,程序必须拥有SE_SHUTDOWN_NAME权限才能成功调用ExitwindowsEx
要提高权限就要使用AdjustTokenPrivileges 。
提高本进程权限代码:
HANDLE hToken;
TOKEN_PRIVILEGES tkp,tkpNew;
LUID int64LpUid;
OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken)
LookupPrivilegue(NULL,"SeShutdownPrivilege",&int64LpUid);
tkp.PrivilegeCount=1;
tkp.Privileges[0].Liud=int64LpUid;
tkp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken,FALSE,&tkp,sizeof(tkp),&tkpNew,&dwSize);

Windows NT/2000 关机函数
BOOL MySystemShutdown()
{
 HANDLE hToken;
 TOKEN_PRIVILEGES tkp;
 // Get a token for this process.
 if (!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
 return( FALSE );
 // Get the LUID for the shutdown privilege.
 LookupPrivilegue(NULL, SE_SHUTDOWN_NAME,&tkp.Privileges[0].Luid);
 tkp.PrivilegeCount = 1; // one privilege to set
 tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
 // Get the shutdown privilege for this process.
 AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,(PTOKEN_PRIVILEGES)NULL, 0);
 if (GetLastError() != ERROR_SUCCESS)
  return FALSE;
 // Shut down the system and force all applications to close.
 if (!ExitWindowsEx(EWX_SHUTDOWN | EWX_FORCE, 0))
  return FALSE;
 return TRUE;
}

=======================
上面代码中的LookupPrivilegue在VC6中编译通不过,经查,改为LookupPrivilegeValue后通过。

 

LookupPrivilegeValue 函数查看系统权限的特权值,返回信息到一个LUID结构体里。

BOOL LookupPrivilegeValue(LPCTSTR lpSystemName,LPCTSTR lpName,PLUID lpLuid);

第一个参数表示所要查看的系统,本地系统直接用NULL

第二个参数指向一个以零结尾的字符串,指定特权的名称,如在WinNT h头文件定义。例如,此参数可指定常数,se_security_name,或其对应的字符串,“sesecurityprivilege "。

第三个参数用来接收所返回的制定特权名称的信息。

函数调用成功后,信息存入第三个类型为LUID的结构体中,并且函数返回非0。

函数定义在winbase.h中,链接使用advapi32.lib库。

 

示例:

CString str;

LUID Luid; //LUID 就是LARGE_INTEGER的定义

LookupPrivilegeValue(NULL,"SeDebugPrivilege",&Luid);

str.Format("%d,%d\n",Luid.HighPart,Luid.LowPart);

MessageBox(str);



版权所有!www.sieye.cn
E.Mail:sieye@sohu.com QQ:66697110