【Delphi】程序实现Windows电脑关机、重启、注销(源代码)

目录

一、API函数说明

1. GetCurrentProcess

2. OpenProcessToken

3. LookupPrivilegeValue

4. AdjustTokenPrivileges

5. ExitWindowsEx

二、Delphi实现源代码


        在日常软件开发中,可能会遇到通过程序自动关闭电脑,在早期Windows 9x下,可以直接调用ExitWindowsEx函数实现关机或重新启动。但是在Windows 2000/XP以及最新的win10和win11下,在调用ExitWindowsEx函数之前,需要先调用AdjustTokenPrivileges函数来获得关机特权。

        否则将无法实现程序关机 !       

首先需要介绍几个windows API函数:

一、API函数说明

1. GetCurrentProcess

GetCurrentProcess是一个Windows API函数,用于获取当前进程的句柄。该句柄是一个伪句柄,只能在进程内部使用,离开当前进程就没有意义了。

函数的原型如下:

HANDLE GetCurrentProcess(void);

该函数返回一个句柄,该句柄表示当前进程的伪句柄。这个伪句柄不需要使用CloseHandle函数来关闭,因为它在进程结束时自动关闭。

这个函数主要用于在进程内部使用,以便于访问和操作当前进程的相关资源。例如,可以使用这个句柄来获取当前进程的名称、PID等。

请注意,这个函数只能用于获取当前进程的伪句柄,不能用于获取其他进程的句柄。如果需要获取其他进程的句柄,需要使用其他相应的API函数,例如OpenProcess

2. OpenProcessToken

OpenProcessToken用于打开与进程相关联的访问令牌。这个函数可以用于获取对其他进程的访问权限,以便进行进程间通信、调试或其他需要访问其他进程资源的操作。

函数的原型如下:

BOOL OpenProcessToken(  
  HANDLE  ProcessHandle,  
  DWORD   DesiredAccess,  
  PHANDLE TokenHandle  
);

参数说明:

  1. ProcessHandle:一个指向要打开访问令牌的进程的句柄。这个进程必须具有PROCESS_QUERY_LIMITED_INFORMATION访问权限。
  2. DesiredAccess:一个访问掩码,用于指定请求的访问类型。这些请求的访问类型与令牌的自由访问控制列表(DACL)进行比较,以确定授予或拒绝了哪些访问。
  3. TokenHandle:一个指向句柄的指针,该句柄标识函数返回时新打开的访问令牌。

函数的返回值是一个布尔值,指示操作是否成功。如果成功,则返回值为非零;如果失败,则返回值为零。

使用OpenProcessToken函数可以获取对其他进程的访问令牌,然后可以使用其他Windows API函数来执行相应的操作,例如读取或修改令牌的权限等。需要注意的是,在调用OpenProcessToken函数之前,需要了解相关的安全性和访问权限,以及如何使用返回的访问令牌执行其他操作。

3. LookupPrivilegeValue

LookupPrivilegeValue用于查找指定进程的特权值。这个函数用于确定当前进程是否具有某个特定的特权,以便执行某些操作或访问某些资源。

函数的原型如下:

BOOL LookupPrivilegeValue(  
  LPCWSTR lpSystemName,  
  LPCWSTR lpName,  
  PLUID   lpLuid  
);

参数说明:

  1. lpSystemName:一个指向字符串的指针,该字符串指定了要查询的特权所属的系统的名称。通常,这个参数设置为NULL,表示使用本地系统。
  2. lpName:一个指向字符串的指针,该字符串指定了要查询的特权的名称。
  3. lpLuid:一个指向LUID结构的指针,该结构用于接收查询到的特权值。

函数返回一个布尔值,指示是否成功找到指定的特权值。如果函数成功找到特权值,则返回值为非零;如果未找到特权值或发生错误,则返回值为零。

使用LookupPrivilegeValue函数可以帮助确定当前进程是否具有执行特定操作所需的特权。这对于进程安全性和权限管理非常重要,因为只有具有适当特权的进程才能执行敏感操作或访问受保护的资源。

4. AdjustTokenPrivileges

AdjustTokenPrivileges用于调整与访问令牌相关联的特权状态。这个函数允许进程修改其令牌的特权集合,以便启用或禁用特定的特权。

函数的原型如下:

BOOL AdjustTokenPrivileges(  
  HANDLE  TokenHandle,  
  BOOL    DisableAllPrivileges,  
  LPTOKEN_PRIVILEGES NewState,  
  DWORD   BufferLength,  
  LPTOKEN_PRIVILEGES PreviousState,  
  PDWORD  ReturnLength  
);

参数说明:

  1. TokenHandle:一个指向访问令牌句柄的指针,该令牌包含要更改的特权集合。
  2. DisableAllPrivileges:一个布尔值,指示是否禁用所有特权。如果为TRUE,则禁用所有特权;如果为FALSE,则启用所有特权。
  3. NewState:一个指向TOKEN_PRIVILEGES结构的指针,该结构指定要更改的特权集合的新状态。如果DisableAllPrivileges参数为TRUE,则此参数必须设置为NULL。
  4. BufferLength:一个指向DWORD类型的指针,该值指定NewState缓冲区的大小。如果NewState参数为NULL,则此参数必须设置为0。
  5. PreviousState:一个指向TOKEN_PRIVILEGES结构的指针,该结构用于接收更改之前的特权集合状态。此参数可以为NULL。
  6. ReturnLength:一个指向DWORD类型的指针,该值接收返回的特权集合状态的大小。如果PreviousState参数不为NULL,则此参数将接收更改之前的特权集合的大小。

函数返回一个布尔值,指示操作是否成功。如果函数成功地更改了特权状态,则返回值为非零;如果发生错误或未更改任何特权,则返回值为零。

使用AdjustTokenPrivileges函数可以控制进程的特权级别,以执行敏感操作或访问受保护的资源。通过启用或禁用特定的特权,可以控制进程的安全行为和权限,从而提高系统的安全性。

5. ExitWindowsEx

ExitWindowsEx是一个Windows API函数,用于控制Windows的开关,如关闭Windows、重新启动Windows等。

在Win9x下,可以直接调用ExitWindowsEx函数实现关机或重新启动。但在Win 2000/XP以及win10和win11下,调用此函数时,还需要先调用AdjustTokenPrivileges函数。

这个函数的原型如下:

BOOL ExitWindowsEx(  
  UINT uFlags, // 关闭参数  
  DWORD dwReserved // 系统保留,一般取0  
);

参数说明:

  • uFlags:指定关闭的类型。此参数必须有下列值的组合:
    • EWX_FORCE:强制终止进程。当此标志设置,Windows不会发送消息WM_QUERYENDSESSION和WM_ENDSESSION给目前在系统中运行的程序。这可能会导致应用程序丢失数据。因此,应该在紧急情况下使用此标志。
    • EWX_LOGOFF:关闭所有进程,然后注销用户。
    • EWX_POWEROFF:关闭系统并关闭电源。该系统必须支持断电。
    • EWX_REBOOT:关闭系统,然后重新启动系统。所有文件缓冲区已经刷新到磁盘上,所有正在运行的进程已经停止。
  • dwReserved:系统保留,一般取0。

使用ExitWindowsEx函数时,应确保理解每个标志的含义和影响,并谨慎使用强制终止进程的标志(EWX_FORCE),以避免数据丢失或其他潜在问题。

二、Delphi实现源代码

{ 电脑关机函数,根据其他语言代码改写
  sensor 2024-01-25
}

unit uPowerOFF;

interface
uses
  Winapi.Windows;
//  Winapi.Messages,
//  System.SysUtils,
//  System.Variants,
//  System.Classes;

{
const
  SE_PRIVILEGE_ENABLED = $00000002;
  TOKEN_QUERY          = $00000008;
  TOKEN_ADJUST_PRIVILEGES = $00000020;
  SE_SHUTDOWN_NAME        = 'SeShutdownPrivilege';
  EWX_LOGOFF       = $00000000;
  EWX_SHUTDOWN    = $00000001;
  EWX_REBOOT      = $00000002;
  EWX_FORCE       = $00000004;
  EWX_POWEROFF    = $00000008;
  EWX_FORCEIFHUNG = $00000010;
}
//内部函数
function DoExitWin(flag : Integer) : Boolean;

//公共函数,实际外部调用函数
procedure PowerOff;
procedure LogOff;
procedure Reboot;

implementation

//内部函数
function DoExitWin(flag : Integer) : Boolean;
var
  tp           : TTokenPrivileges;
  hproc        : THandle;
  htok         : THandle;
  ok           : Boolean;
  ReturnLength : DWORD;
begin
  hproc := GetCurrentProcess();
  ok := OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES + TOKEN_QUERY,htok);
  if not ok then Exit(False);


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

  ok := LookupPrivilegeValue(nil, SE_SHUTDOWN_NAME,  tp.Privileges[0].Luid);
  if not ok then Exit(False);
  ok := AdjustTokenPrivileges(htok, false, tp, 0, nil, ReturnLength);
  if not ok then Exit(False);
  Result := ExitWindowsEx(flag, 0);
end;

//公共函数
procedure PowerOff;
begin
  DoExitWin(EWX_FORCE + EWX_POWEROFF);//关机
end;

procedure LogOff;    //注销
begin
  DoExitWin(EWX_FORCE + EWX_LOGOFF);
end;

procedure Reboot;  //重启
begin
   DoExitWin(EWX_FORCE + EWX_REBOOT);
end;


end.

以上函数在win10和win11上测试通过!

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/349880.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

西安石油大学C++上机实验汇总

考试题难度就像第三章第五章课后题的难度 基础知识一定要掌握!!! 上机一:类与对象程序设计(2 学时) 上机目的 掌握声明类的方法。掌握类和类的成员的概念以及定义对象的方法。掌握构造函数和析构函数的…

家居图册制作方法,快来看看

​随着家居设计的流行,越来越多的人开始关注家居装饰和家居用品。据统计,家居市场每年的销售额逐年增长。而家居图册作为家居装饰的重要组成部分,其制作方法也备受关注。 那要怎么制作呢?准备好这个工具:FLBOOK在线制作…

百度Apollo | 实车自动驾驶:感知、决策、执行的无缝融合

🎬 鸽芷咕:个人主页 🔥 个人专栏:《linux深造日志》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! ⛳️ 推荐 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下…

风口抓猪-借助亚马逊云科技EC2服务器即刻构建PalWorld(幻兽帕鲁)私服~~~持续更新中

Pocketpair出品的生存类游戏《幻兽帕鲁》最近非常火,最高在线人数已逼近200万。官方服务器亚历山大,游戏开发商也提供了搭建私人专用服务器的方案,既可以保证稳定的游戏体验,也可以和朋友一起联机游戏,而且还能自定义经…

大创项目推荐 题目:基于LSTM的预测算法 - 股票预测 天气预测 房价预测

文章目录 0 简介1 基于 Keras 用 LSTM 网络做时间序列预测2 长短记忆网络3 LSTM 网络结构和原理3.1 LSTM核心思想3.2 遗忘门3.3 输入门3.4 输出门 4 基于LSTM的天气预测4.1 数据集4.2 预测示例 5 基于LSTM的股票价格预测5.1 数据集5.2 实现代码 6 lstm 预测航空旅客数目数据集预…

1.25 C++ day2

思维导图 自己封装一个矩形类(Rect),拥有私有属性:宽度(width)、高度(height), 定义公有成员函数: 初始化函数:void init(int w, int h) 更改宽度的函数:set_w(int w) 更改高度的函数:set_h(int h) 输出该矩形的周长和面积函数:void show() 代码&a…

vue实现甘特图

目录 实现效果 一、安装依赖 二、使用 二、绕过license 实现效果 一、安装依赖 npm i --save vue-gantt-schedule-timeline-calendar 实现甘特图需先安装上述依赖,安装依赖实际上是通过gantt-schedule-timeline-calendar来实现的。所以node_module中因包含以下…

SpringBlade微服务开发平台

采用前后端分离的模式,前端开源两个框架:Sword (基于 React、Ant Design)、Saber (基于 Vue、Element-UI)后端采用SpringCloud全家桶,并同时对其基础组件做了高度的封装,单独开源出一个框架:BladeToolBladeTool已推送至…

视频占内存太大如何压缩?3种简单有效的方法~

很多时候我们需要压缩视频大小,比如节省存储空间、满足平台上传要求等,下面就给大家总结了几个简单且好用的视频压缩技巧,需要的朋友快来学起来~ 方法一:嗨格式压缩大师 嗨格式压缩大师是一款专业的压缩软件,可以压缩…

2024年新提出的算法:一种新的基于数学的优化算法——牛顿-拉夫森优化算法|Newton-Raphson-based optimizer,NRBO

1、简介 开发了一种新的元启发式算法——Newton-Raphson-Based优化器(NRBO)。NRBO受到Newton-Raphson方法的启发,它使用两个规则:Newton-Raphson搜索规则(NRSR)和Trap Avoidance算子(TAO&#…

【JavaSE】P114~P147 ArrayList集合,Scanner类,Random,字符串及相关常用方法,静态static

目录 1 ArrayList 集合装箱,拆箱及包装类 2 API 概述和使用Scanner类匿名对象Random生成随机数 3 字符串字符串的31种构造方法字符串的常量池equals和 字符串的获取相关方法字符串的截取方法字符串的转换相关方法字符串的分割方法 4 静态static关键字静态static的内…

【python】爬取豆瓣影评保存到Excel文件中【附源码】

欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 【往期相关文章】 爬取豆瓣电影排行榜Top250存储到Excel文件中 爬取豆瓣电影排行榜TOP250存储到CSV文件中 爬取知乎热榜Top50保存到Excel文件中 爬取百度热搜排行榜Top50可视化 爬取斗鱼直播照片保存到本地目录 爬…

qwt的极坐标画雷达方向图

qwt的极坐标画天线方向图 请先看这位博主的专业文章,上面有权威讲解 方向图 曲线方程:matlab,引用博主的公式 f3e10;lamda(3e8)/f;beta2.*pi/lamda; n2; t0:0.01:2*pi;dlamda/4; Wbeta.*d.*cos(t);z1((n/2).*W)-n/2*beta*d;z2((1/2).*W)-1/2…

node.js漏洞总结

js开发的web应用和php/Java最大的区别就是js可以通过查看源代码的方式查看到编写的代码,但是php/Java的不能看到,也就是说js开发的web网页相当于可以进行白盒测试。 流行的js框架有: 1. AngularJS 2. React JS 3. Vue 4. jQuery 5. Backbone…

ChatGPT 和文心一言 | 两大AI助手哪个更胜一筹

欢迎来到英杰社区: https://bbs.csdn.net/topics/617804998 欢迎来到阿Q社区: https://bbs.csdn.net/topics/617897397 📕作者简介:热爱跑步的恒川,致力于C/C、Java、Python等多编程语言,热爱跑步&#xff…

C++ qt标题栏组件绘制

本博文源于笔者在学习C qt制作的标题栏组件,主要包含了,最小化,最大化,关闭。读者在看到这篇博文的时候,可以直接查看如何使用的,会使用了,然后进行复制粘贴源码部分即可。 问题来源 想要制作…

JS-M端事件

移动端也有自己独特的地方。比如触屏事件touch(也称触摸事件),Android和IOS都有。 1)touch对象代表一个触摸点。触摸点可能是一根手指,也可能是一根触摸笔。触屏事件可响应用户手指(或触控笔)对…

mysql高可用设计,主库挂了怎么办

实际上高可用就是系统能提供的一种无故障服务能力,就是避免宕机出现不能服务的场景。 首先来说对于无状态服务的高可用设计是比较简单的,发现有不能用的就直接停了换别的服务器就行,比如Nginx。这里说一下无状态服务就是不需要记录你的状态、…

redo log

问:redo log是什么?拿来干嘛的? 现象:如果提交一个事务,就刷新一次磁盘。那么会存在如下问题: 1、单改一条记录,至少都是刷新一个页,造成大量的磁盘I/O浪费 2、随机I/O比连续I/O慢&a…

智能洗地机哪款好用?全能型洗地机推荐

家庭清洁产品是我们生活中熟悉的存在,对于注重清洁的家庭来说,在选择清洁用品时不可避免地会考虑洗地机。相比传统的拖把,使用洗地机确实给人更好的体验。从理论上来说,洗地机作为一种吸尘和拖地一体的清洁工具,能够应…