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);