简介

说到代码控制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 >>>>>>>>>>>>>>>>>\n*\n");
printf("* 1. Power_Off\n*\n");
printf("* 2. Log_Off\n*\n");
printf("* 3. ReBoot\n*\n");
printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
ch = getch();
while (1)
{
switch (ch)
{
case '1':
if (!powerOffProc())
{
printf("Process Error!\n");
continue;
}
return 0;
case '2':
if (!logOffProc())
{
printf("Process Error!\n");
continue;
}
return 0;
case '3':
if (!reBootProc())
{
printf("Process Error!\n");
continue;
}
return 0;
default:
printf("Error!\n");
}
}
system("pause");
return 0;
}

C/C++控制Windows关机/注销/重启的正确姿势的更多相关文章

  1. 编程实现Windows关机、重启、注销

    要想编程使Windows关机.重启或者注销,可以使用ExWindowsEx这个API函数,该函数只有两个参数,第一个表示关机动作的标志,也就是你要让该函数关机呢,还是重启,还是注销等.可以使用EWX_ ...

  2. [置顶] 手机通过socket控制电脑关机,重启,注销等功能

    服务端 package com.pc; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOE ...

  3. php -- php控制linux关机、重启、注销

        php 里面有个 system(exec) 方法, 可以调用系统命令.     重启先建立一个脚本(比喻 /root/reboot_server.sh ),重启用的.//路径可随便,但最少必须 ...

  4. c++ win32 关机 注销 重启

    #include <iostream> #include <Windows.h> #pragma comment(lib, "user32.lib") #p ...

  5. 在Windows中安装NodeJS的正确姿势

    NodeJS已经非常流行了,而且可以预见他将继续受到追捧.这确实是一个不错的创举,想想看他现在能做什么吧 1.服务器程序(典型的就是用来做网站或者restful服务,主打就是多线程,非阻塞,最后,一个 ...

  6. Linux常用命令——关机与重启命令

    1.shutdown命令 shutdown [选项] 时间 --使用shutdown进行关机或重启会正确保存正在使用的服务,其他命令有一定的危险性,建议最好使用shutdown命令进行关机重启 选项: ...

  7. C#实现控制Windows系统关机、重启和注销的方法:

    shutdown命令的参数: shutdown.exe -s:关机shutdown.exe -r:关机并重启shutdown.exe -l:注销当前用户 shutdown.exe -s -t 时间:设 ...

  8. C#实现控制Windows系统关机、重启和注销的方法

    shutdown命令的参数: shutdown.exe -s:关机shutdown.exe -r:关机并重启shutdown.exe -l:注销当前用户 shutdown.exe -s -t 时间:设 ...

  9. 使用c#对windows进行关机、重启或注销

    方法一:调用windows自带的shutdown.exe (缺点:会出现倒计时窗口) System.Diagnostics.Process.Start("shutdown.exe" ...

随机推荐

  1. TDSQL“相似查询工具MSQL+”入选VLDB论文

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由腾讯云数据库 TencentDB发表于云+社区专栏 作者介绍:王晓宇,腾讯数据库TDSQL团队成员,目前参与TDSQL数据库内核研发工 ...

  2. [转]SQL Server 2008 如何配置报表管理器

    本文转自:https://docs.microsoft.com/zh-cn/previous-versions/sql/sql-server-2008/cc281384%28v%3dsql.100%2 ...

  3. Async和await关键字的用法

    async & await 的前世今生(Updated) 1. 方法打上Async关键字, 就可以使用await调用别的Async方法了 2. 记得在需要异步执行的方法里面调用await或者n ...

  4. 处理html内容,获取纯文本

    import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import java.util.rege ...

  5. VB.NET的MsgBox

    一.可用按钮(指定消息框显示哪些按钮) MsgBoxStyle.OkOnly = vbOKOnly = 0(确定按钮) MsgBoxStyle.OkCancel = vbOKCancel = 1(确定 ...

  6. winform窗体 控件 【ListView】

      ListView  表格试图 1.设置视图属性 Details     试图可见 2.设置列      Columns集合 编辑列——  添加列,修改列名 3.添加行数据      Items 集 ...

  7. SpringBoot,Vue前后端分离开发首秀

    需求:读取数据库的数据展现到前端页面 技术栈:后端有主要有SpringBoot,lombok,SpringData JPA,Swagger,跨域,前端有Vue和axios 不了解这些技术的可以去入门一 ...

  8. Android-Messenger跨进程通信

    http://blog.csdn.net/lmj623565791/article/details/47017485 一.概述 我们可以在客户端发送一个Message给服务端,在服务端的handler ...

  9. Windows Server 2008R2常见的500错误

    每次公司服务器装系统后再去部署服务,都会碰到这个问题,这里记录一下问题的解决方法 遇到“500 – 内部服务器错误. 您查找的资源存在问题,因而无法显示.”的问题. 解决办法: 1.解决方法:打开II ...

  10. CSS计数器(序列数字字符自动递增)详解———张鑫旭

    by zhangxinxu from http://www.zhangxinxu.com本文地址:http://www.zhangxinxu.com/wordpress/?p=4303 一.挖坟不可耻 ...