You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C++中启用SE_SHUTDOWN_NAME权限?按MSDN操作仍无法关机

在C++中启用SE_SHUTDOWN_NAME权限并实现系统关机的解决方法

标准权限流程的常见疏漏排查

如果你按照MSDN文档操作仍失败,先检查以下细节:

  • 调用OpenProcessToken时,必须传入TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY权限,且确保当前进程句柄有效
  • LookupPrivilegeValue的系统名称参数传NULL(指向本地系统),权限名称严格使用SE_SHUTDOWN_NAME
  • 执行AdjustTokenPrivileges后,不要只看返回值,必须通过GetLastError()确认:若返回ERROR_NOT_ALL_ASSIGNED,说明当前用户根本没有被分配关机权限
  • 关机函数参数要正确:比如ExitWindowsEx需传入EWX_SHUTDOWN | EWX_FORCE(强制关闭未响应程序),远程桌面环境可能需要额外参数

可运行的完整代码示例

#include <windows.h>
#include <iostream>

bool EnableShutdownPrivilege() {
    HANDLE hToken;
    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
        std::cerr << "OpenProcessToken 失败,错误码:" << GetLastError() << std::endl;
        return false;
    }

    LUID luid;
    if (!LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &luid)) {
        std::cerr << "LookupPrivilegeValue 失败,错误码:" << GetLastError() << std::endl;
        CloseHandle(hToken);
        return false;
    }

    TOKEN_PRIVILEGES tp;
    tp.PrivilegeCount = 1;
    tp.Privileges[0].Luid = luid;
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

    if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) {
        std::cerr << "AdjustTokenPrivileges 失败,错误码:" << GetLastError() << std::endl;
        CloseHandle(hToken);
        return false;
    }

    DWORD err = GetLastError();
    if (err == ERROR_NOT_ALL_ASSIGNED) {
        std::cerr << "当前用户未被分配关机权限" << std::endl;
        CloseHandle(hToken);
        return false;
    }

    CloseHandle(hToken);
    return true;
}

int main() {
    if (EnableShutdownPrivilege()) {
        if (!ExitWindowsEx(EWX_SHUTDOWN | EWX_FORCE, SHTDN_REASON_MAJOR_OPERATINGSYSTEM | SHTDN_REASON_MINOR_UPGRADE)) {
            std::cerr << "ExitWindowsEx 失败,错误码:" << GetLastError() << std::endl;
            return 1;
        }
    } else {
        return 1;
    }
    return 0;
}

替代方法与额外处理

如果标准流程仍无效,尝试以下方案:

  • 改用InitiateSystemShutdownEx函数:该函数权限控制更灵活,支持强制关机和远程操作,示例代码:
    if (!InitiateSystemShutdownEx(NULL, L"系统即将关机", 0, TRUE, TRUE, SHTDN_REASON_MAJOR_OPERATINGSYSTEM | SHTDN_REASON_MINOR_UPGRADE)) {
        std::cerr << "InitiateSystemShutdownEx 失败,错误码:" << GetLastError() << std::endl;
    }
    
  • 检查本地安全策略:打开「本地安全策略」→「本地策略」→「用户权限分配」→「关闭系统」,确保当前用户或所属组在列表中
  • 强制管理员权限运行:在VS项目属性中设置「链接器」→「清单文件」→「UAC执行级别」为requireAdministrator,或右键程序选择「以管理员身份运行」
  • 远程桌面适配:若在远程会话中,需添加EWX_LOGOFF参数,或确认远程桌面服务允许关机操作

内容的提问来源于stack exchange,提问作者Kaarthikeyan K

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 02:41:05