简介

说到代码控制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. Dicom图像解析

    医疗图像解析 Dicom 后缀: .dcm..DCM Dicom中规定的坐标系是以人坐标系为绝对坐标系的,规定X轴正向指向病人的左侧,Y轴正向指向病人的背部,Z轴正向指向病人的头部.但是,坐标点的位置 ...

  2. POJ 1002 487-3279(map映照容器的使用)

    Description Businesses like to have memorable telephone numbers. One way to make a telephone number ...

  3. MVC用非Entity Framework将数据显示于视图(二)

    这篇<MVC用非Entity Framework将数据显示于视图> http://www.cnblogs.com/insus/p/3364235.html 也算是MVC视图显示数据库的数据 ...

  4. 50道sql练习题和答案

    最近两年的工作没有写过多少SQL,感觉水平下降十分严重,网上找了50道练习题学习和复习 原文地址:50道SQL练习题及答案与详细分析 1.0数据表介绍 --1.学生表 Student(SId,Snam ...

  5. Eclipse中导入外部jar包步骤

    昨天,学习了Jar包的打包过程,现在打算记录一下,如何在Eclipse中导入外部Jar包. 第一步:在项目中鼠标右键>>New>>点击Folder. 第二步:在弹出窗口将Fol ...

  6. windows下给redis添加密码

    在redis的安装目录下找到 redis.windows-service.conf 文件.用文本编辑器打开, 找到requirepass所在行,回车另起一行,输入requirepass 你的密码, # ...

  7. Java - "JUC线程池" ThreadPoolExecutor原理解析

    Java多线程系列--“JUC线程池”02之 线程池原理(一) ThreadPoolExecutor简介 ThreadPoolExecutor是线程池类.对于线程池,可以通俗的将它理解为"存 ...

  8. 服务注册中心Eureka vs Zookeeper vs Consul

    前言 在现在云计算和大数据快速发展的今天,业务快速发展和变化.我们以前的单一应用难以应对这种快速的变化, 因此我们需要将以前单一的大应用不断进行差分,分成若干微小的应用或者服务,这就是微服务的思想.但 ...

  9. HDU1024(DP)

    Max Sum Plus Plus Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others ...

  10. query 中 radio选中小技巧

    在php中经常,经常要用到radio选中按钮,下次再登录时默认记录用户选中的选项,在PHP判断的时候: 在input中不能加checked=“<?php ;?>”:否则失效