Implementing this functionality is simple, and it is important to call a system API
ExitWindowsEx
The function is to log off the current user, shut down the system, or reboot the system.
It will send a wm_queryendsession message to all the applications and let them decide whether it can be closed.
Function Prototypes:
<span style="font-size:18px;">BOOL WINAPI ExitWindowsEx(
__in UINT uFlags,
__in DWORD dwReason
);
</span>
The first parameter is the closing type and the second is the reason for the shutdown
The first parameter can be:
Ewx_logoff
0
Ewx_poweroff
0x00000008
Ewx_reboot
0x00000002
Ewx_restartapps
0x00000040
Ewx_shutdown
0x00000001
This parameter can also optionally contain the following two values
Ewx_force
0X00000004 contains this parameter to force the system to shut down, which may cause the application to lose data
Ewx_forceifhung
0x00000010
if the application process still does not respond to wm_queryendsession or wm_endsession messages after the timeout period, then force them off.
return Value:
If successful, returns a value other than 0, failure returns 0
More error messages can be obtained by GetLastError ().
In addition to understanding this function, we should also be clear:
For Windows NT versions of the operating system, we need to elevate a se_shutdown permission to complete the shutdown operation.
NT is not required, for example 95,98,me
The above NT systems include:
Microsoft Windows $ (Windows NT 5.0) (1999) (2000-2010) Microsoft Windows XP (Windows NT 5.1) (2001-2014) Microsoft Win Dows Server 2003 (Windows NT 5.2) (2003-2015) Microsoft Windows Server 2003 R2 (Windows NT 5.2) (2006-2015) Microsoft Wind OWS Vista (Windows NT 6.0) (2006-2017) Microsoft Windows Server (Windows NT 6.0) (2008-2018) Microsoft Windows 7 (Win dows NT 6.1) (2009-2020)
Let's start with a concrete implementation:
Shutdown function Implementation
1. Check the system version to see if it is NT above, if yes, to elevate permissions
2. Call the system api,exitwindowsex.
#pragma region 功能实现
BOOL ReSetWindows(DWORD dwFlags,BOOL bForce)
{
//检查参数是否正确
if(dwFlags!=EWX_LOGOFF&&dwFlags!=EWX_REBOOT&&dwFlags!=EWX_SHUTDOWN)
return FALSE;
//获得系统的版本信息,让我们后面确定是否需要提升系统权限
OSVERSIONINFO osvi={0};
//获得参数的大小,以提供给GetVersionEx来判断这是一个新版本的OSVERSIONINFO,还是旧版本的
//新版本是OSVERSIONINFOEX。扩充版本
osvi.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
if(!GetVersionEx(&osvi))
{
return FALSE;
}
//检查操作系统的版本,如果是NT类型的系统,需要提升系统权限
if(osvi.dwPlatformId==VER_PLATFORM_WIN32_NT)
{
//EnableShutDownPriv();
}
//判断是否是强制关机,强制关闭系统进程。
dwFlags|=(bForce!=FALSE)?EWX_FORCE:EWX_FORCEIFHUNG;
//调用API
returnExitWindowsEx(dwFlags,0);
}
code to elevate permissions:
#pragma region 用来提升系统权限
//这是一个通用的提升权限函数,如果需要提升其他权限
//更改LookupPrivilegeValue的第二个参数SE_SHUTDOWN_NAME,即可
BOOL EnableShutDownPriv()
{
HANDLE hToken=NULL;
TOKEN_PRIVILEGES tkp={0};
//打开当前程序的权限令牌
if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken))
{
return FALSE;
}
//获得某一特定权限的权限标识LUID,保存在tkp中
if(!LookupPrivilegeValue(NULL,SE_SHUTDOWN_NAME,&tkp.Privileges[0].Luid))
{
CloseHandle(hToken);
return FALSE;
}
tkp.PrivilegeCount=1;
tkp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
//调用AdjustTokenPrivileges来提升我们需要的系统权限
if(!AdjustTokenPrivileges(hToken,FALSE,&tkp,sizeof(TOKEN_PRIVILEGES),NULL,NULL))
{
CloseHandle(hToken);
return FALSE;
}
return TRUE;
}
Call Method:
ReSetWindows(EWX_LOGOFF,false);//注销
ReSetWindows(EWX_REBOOT,true);//重启
ReSetWindows(EWX_SHUTDOWN,true);//关机
See your code for details, see attachment. Article excerpt from:http://blog.csdn.net/zy_dreamer/article/details/8948880
Null
List of attachments
Windows C + + implements logoff, restart, shutdown logoff reboot shutdown