windows c++ 关机、重启、注销功能的实现(附带源码)
windows c++ 关机、重启、注销功能的实现(附带源码)
一、Windows 实现关机/重启/注销的基本原理
在 Windows 中,关机、重启、注销属于系统级操作,普通程序不能直接调用,必须:
-
获取进程的关机权限(SE_SHUTDOWN_NAME)
-
调用系统 API 执行操作
Windows 提供了两类常见方式:
| 方式 | 特点 |
|---|---|
ExitWindowsEx |
官方 API,推荐、规范 |
system("shutdown ...") |
简单粗暴,依赖命令 |
InitiateSystemShutdownEx |
更高级,服务器常用 |
教学和开发中最推荐:👉 ExitWindowsEx
二、必须解决的问题:权限(非常关键)
如果你直接调用关机 API,大概率会失败,原因是:
❌ 当前进程没有 “关机权限”
所以第一步必须做:
启用关机权限(SE_SHUTDOWN_NAME)
流程是:
-
打开当前进程的访问令牌
-
查找关机权限的 LUID
-
调整进程权限
三、核心 API 介绍
1️⃣ AdjustTokenPrivileges(开启权限)
AdjustTokenPrivileges
用于临时提升当前进程的系统权限。
2️⃣ ExitWindowsEx(执行操作)
BOOL ExitWindowsEx( UINT uFlags, DWORD dwReason );
常用 uFlags 参数:
| 功能 | 参数 |
|---|---|
| 注销 | EWX_LOGOFF |
| 关机 | EWX_SHUTDOWN |
| 重启 | EWX_REBOOT |
| 强制 | EWX_FORCE / EWX_FORCEIFHUNG |
四、三种功能的实现方式(核心逻辑)
✔ 注销
ExitWindowsEx(EWX_LOGOFF, 0);
✔ 关机
ExitWindowsEx(EWX_SHUTDOWN, 0);
✔ 重启
ExitWindowsEx(EWX_REBOOT, 0);
⚠ 注意
如果不加EWX_FORCE,系统会尝试正常关闭程序(更安全)
五、完整 C++ 示例源码
/*************************************************
* 文件名:system_power.cpp
* 功能:Windows 关机 / 重启 / 注销
*************************************************/
#include <windows.h>
#include <iostream>
#pragma comment(lib, "advapi32.lib")
/* 启用关机权限 */
bool EnableShutdownPrivilege()
{
HANDLE hToken;
TOKEN_PRIVILEGES tkp;
// 打开当前进程的访问令牌
if (!OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
{
return false;
}
// 获取关机权限的 LUID
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);
return GetLastError() == ERROR_SUCCESS;
}
int main()
{
int choice;
std::cout << "============================\n";
std::cout << "1. 注销\n";
std::cout << "2. 关机\n";
std::cout << "3. 重启\n";
std::cout << "请选择:";
std::cin >> choice;
if (!EnableShutdownPrivilege())
{
std::cout << "权限获取失败!\n";
return 0;
}
switch (choice)
{
case 1:
ExitWindowsEx(EWX_LOGOFF, 0);
break;
case 2:
ExitWindowsEx(EWX_SHUTDOWN, 0);
break;
case 3:
ExitWindowsEx(EWX_REBOOT, 0);
break;
default:
std::cout << "无效选择\n";
break;
}
return 0;
}
七、常见问题与解决办法
Q1:程序运行了但没反应?
✔ 原因:
-
没有启用
SE_SHUTDOWN_NAME权限
✔ 解决:
-
必须调用
AdjustTokenPrivileges
Q2:为什么注销不需要管理员权限?
✔ 因为:
-
注销当前用户不涉及系统级关闭
Q3:如何强制关闭所有程序?
ExitWindowsEx(EWX_SHUTDOWN | EWX_FORCE, 0);
⚠ 慎用,可能丢失数据
Q4:Windows 11 可用吗?
✔ 完全可用
✔ 官方 API,长期稳定
八、可扩展方向(很适合课程设计)
-
定时关机 / 重启(Sleep + ExitWindowsEx)
-
GUI 版(Win32 / MFC / Qt)
-
托盘程序
-
远程控制(Socket + 关机)
-
权限检测与失败提示
九、总结一句话
Windows 下的关机、重启、注销,本质就是:
👉 开启关机权限 + 调用 ExitWindowsEx
更多推荐
所有评论(0)