• C/C++控制Windows关机/注销/重启的正确姿势


    简介

    说到代码控制Windows关机/注销/重启的方式,有很多种,最简单的不过就是控制命令行,使用system(“pause”)函数执行一个shutdown -s -t 0,关机就完成了。但这种方式还要借助于命令行的方式解决问题。而Windows早就提供给我们直接控制关机/注销/重启的API了,在WindwosNT系统之前,只需调用ExitWindowsEx()就OK了。但自从出现了WindowsNT系统后,权限意识大大提高,为了提高系统的安全性,微软要求Windows执行关机/重启这类命令时一定要先提升进程权限,再执行ExitWindowsEx()函数。所以在NT代表的系统中,提升权限就得用到OpenProcessToken()函数打开进程的权限令牌,然后使用LookupPrivilegeValue()函数提取出关机权限所对应的Luid,再调用AdjustTokenPrivileges()函数修改对应权限即可。虽然操作繁琐了一些,但是并不复杂,相对于执行命令行的关机指令而言更加具有健壮性,不容易被拦截。

    C++代码样例

    /*
    本程序只演示关机,注销,重启三种功能,主要目的是理解进程权限的控制,其他功能可详见MSDN文档说明
    */
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <conio.h>
    #include <ctype.h>
    #include <iostream>
    #include <windows.h>
    
    using namespace std;
    
    /*
    提升进程权限
    */
    bool improvePv()
    {
        HANDLE hToken;
        TOKEN_PRIVILEGES tkp;
        if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken)) return false;
        if (!LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid)) return false;
        tkp.PrivilegeCount = 1;
        tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
        if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, NULL, NULL, NULL)) return false;
        return true;
    }
    
    /*
    关机
    */
    bool powerOffProc()
    {
        if (!improvePv() || !ExitWindowsEx(EWX_POWEROFF | EWX_FORCE, SHTDN_REASON_MAJOR_APPLICATION)) return false;
        return true;
    }
    
    /*
    注销
    */
    bool logOffProc()
    {
        if (!improvePv() || !ExitWindowsEx(EWX_LOGOFF | EWX_FORCE, SHTDN_REASON_MAJOR_APPLICATION)) return false;
        return true;
    }
    
    /*
    重启
    */
    bool reBootProc()
    {
        if (!improvePv() || !ExitWindowsEx(EWX_REBOOT | EWX_FORCE, SHTDN_REASON_MAJOR_APPLICATION)) return false;
        return true;
    }
    
    int main(void)
    {
        CHAR ch;
        printf(">>>>>>>>>>>>>>>>>>>>>> Demo >>>>>>>>>>>>>>>>>
    *
    ");
        printf("* 1. Power_Off
    *
    ");
        printf("* 2. Log_Off
    *
    ");
        printf("* 3. ReBoot
    *
    ");
        printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    ");
        ch = getch();
        while (1)
        {
            switch (ch)
            {
            case '1':
                if (!powerOffProc())
                {
                    printf("Process Error!
    ");
                    continue;
                }
                return 0;
            case '2':
                if (!logOffProc())
                {
                    printf("Process Error!
    ");
                    continue;
                }
                return 0;
            case '3':
                if (!reBootProc())
                {
                    printf("Process Error!
    ");
                    continue;
                }
                return 0;
            default:
                printf("Error!
    ");
            }
        }
        system("pause");
        return 0;
    }
  • 相关阅读:
    No.013-Python-学习之路-Day10-事件驱动及异步IO
    No.012-Python-学习之路-Day9-GIL|Thread|Process|Coroutine
    No.011-Python-学习之路-Day8-Socket网络编程
    No.010-Python-学习之路-Day7-面向对象的进阶<类中高级方法|类创建及实例的生成过程|反射>|异常处理|动态的模块导入|断言
    Python-Modules-pygame的学习记录
    No.009-Python-学习之路-Day6-面向对象的特性及语法
    No.008-Python-学习之路-Day5-random|os|sys|shutil|shelve|xml|PyYAML|ConfigParser|hashlib|RE
    No.007-Python-学习之路-Day5-模块简介|time&datetime
    【转】git使用教程
    web调试工具
  • 原文地址:https://www.cnblogs.com/csnd/p/12897017.html
Copyright © 2020-2023  润新知