zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    古谚、评论与论断、名篇与名言
    重读《西游记》
    重读《西游记》
    命名之法 —— 时间、季节、地点
    命名之法 —— 时间、季节、地点
    文言的理解 —— 古时的称谓、别称、别名
    文言的理解 —— 古时的称谓、别称、别名
    Oracle GoldenGate for Oracle 11g to PostgreSQL 9.2.4 Configuration
    瀑布 敏捷 文档
    POJ 1325 ZOJ 1364 最小覆盖点集
  • 原文地址:https://www.cnblogs.com/csnd/p/12897017.html
Copyright © 2011-2022 走看看