系统关机函数ExitWindowsEx详解

“系统ShutDown”属于Windows系统的一种基本服务。功能上有“关闭系统”,“注销用户”,“锁定工作站”三种操作。SDK中提供了几个函数,来对此服务进行调用。

“关闭系统”功能使计算机可以被安全的关闭。所有在文件系统里缓冲的内容都被强制写入磁盘;然后,显示相应的对话框,提示用户计算机将被关闭或者已经准备好被关闭。可选的情况一般是计算机在关闭后重起,而不是直接切断电源。

如果一个进程调用“注销”功能函数,则该进程所在的安全环境范围内的所有进程都被终止,使当前的用户退出系统。一个登陆对话框被显示,期待新用户的登陆。

“锁定工作站”功能使你可以在离开计算机的时候,保护计算机屏幕不被未授权的用户看到。要解除锁定,必须用管理员或着授权用户的帐号和密码重新登陆。

如何关闭系统:

程序可以用两种方式关闭本地或远程计算机 :

1. 直接关闭系统 

2. 关闭系统并重启 

Windows NT/2000 及后续版本:程序必须拥有SE_SHUTDOWN_NAME权限才能成功调用关闭函数。

ExitWindowsEx函数可以用来关闭系统。如函数成功调用,系统对每个窗口发送WM_QUERYENDSESSION 消息,询问窗口所属的程序是否可以被终止。收到此消息的程序应该进行响应,清除环境释放资源,然后返回TRUE表示自己可以被终止。然而调用ExitWindowEx的时候如果指定了EXW_FORCE,则系统强行终止相关的进程并关闭,这样可能导致数据的丢失。

这是一段在NT/2000中调用ExitWindowEx关闭系统的程序(强制关闭所有程序)。

在windows95/98/me中直接调用ExitWindowEx即可。

HANDLE hToken;

TOKEN_PRIVILEGES tkp;

// Get a token for thisprocess.

if(!OpenProcessToken(GetCurrentProcess(),

TOKEN_ADJUST_PRIVILEGES |TOKEN_QUERY, &hToken))

Error("OpenProcessToken");

// Get the LUID for theshutdown privilege.

LookupPrivilegeValue(NULL,SE_SHUTDOWN_NAME,

&tkp.Privileges[0].Luid);

tkp.PrivilegeCount = 1;// one privilege to set

tkp.Privileges[0].Attributes= SE_PRIVILEGE_ENABLED;

// Get the shutdownprivilege for this process.

AdjustTokenPrivileges(hToken,FALSE, &tkp, 0,

(PTOKEN_PRIVILEGES)NULL,0);

// Cannot test the returnvalue of AdjustTokenPrivileges.

if (GetLastError() !=ERROR_SUCCESS)

error("AdjustTokenPrivileges");

// Shut down the systemand force all applications to close.

if(!ExitWindowsEx(EWX_SHUTDOWN | EWX_FORCE, 0))

error("ExitWindowsEx");

Windows NT/2000以及后续版本:

InitiateSystemShutdown函数可以指定一段延时,在进行延时计数的时候,在将被关闭的目标计算机上显示一个对话框,提示用户尽快注销。一旦计数结束,系统则立刻被关闭。在此之前,可以调用AbortSystemShutdown函数停止计数,取消相应的关闭操作。InitiateSystemShutdown也可以指定让系统重启。

InitiateSystemShutdown有一个参数LPTSTR lpMachineName,可以指定为网络上的计算机名字,也就是说,可以关闭网络上的他计算机(如果你的用户在该计算机上有足够的权限的话)。

以下这个例子调用InitiateSystemShutdown函数关闭用户已经登陆的本地计算机(要关闭远程计算机将InitSystemShutdown第一个参数由NULL改为正确的计算机名字或)。同样的,也需要先获得SE_SHUTDOWN_NAME权限。

HANDLE hToken; // handleto process token

TOKEN_PRIVILEGES tkp; //pointer to token structure

BOOL fResult; // systemshutdown flag

// Get the currentprocess token handle so we can get shutdown

// privilege.

if(!OpenProcessToken(GetCurrentProcess(),

TOKEN_ADJUST_PRIVILEGES |TOKEN_QUERY, &hToken))

ErrorHandler("OpenProcessTokenfailed.");

// Get the LUID forshutdown privilege.

LookupPrivilegeValue(NULL,SE_SHUTDOWN_NAME,

&tkp.Privileges[0].Luid);

tkp.PrivilegeCount = 1;// one privilege to set

tkp.Privileges[0].Attributes= SE_PRIVILEGE_ENABLED;

// Get shutdown privilegefor this process.

AdjustTokenPrivileges(hToken,FALSE, &tkp, 0,

(PTOKEN_PRIVILEGES) NULL,0);

// Cannot test the returnvalue of AdjustTokenPrivileges.

if (GetLastError() !=ERROR_SUCCESS)

ErrorHandler("AdjustTokenPrivilegesenable failed.");

// Display the shutdowndialog box and start the time-out countdown.

fResult =InitiateSystemShutdown( NULL, // shut down local computer

"Click on the mainwindow and press \

the Escape key to cancelshutdown.", // message to user

20, // time-out period

FALSE, // ask user toclose apps

TRUE); // reboot aftershutdown

if (!fResult)

{

ErrorHandler("InitiateSystemShutdownfailed.");

}

// Disable shutdownprivilege.

tkp.Privileges[0].Attributes= 0;

AdjustTokenPrivileges(hToken,FALSE, &tkp, 0,

(PTOKEN_PRIVILEGES) NULL,0);

if (GetLastError() !=ERROR_SUCCESS)

{

ErrorHandler("AdjustTokenPrivilegesdisable failed.");

}

而使用AbortSystemShutoown取消InitialSystemShutdown操作的代码如下(记住要在延时结束前执行才能起作用。

// Get the currentprocess token handle so we can get shutdown

// privilege.

if(!OpenProcessToken(GetCurrentProcess(),

TOKEN_ADJUST_PRIVILEGES |TOKEN_QUERY, &hToken))

{

ErrorHandler("OpenProcessTokenfailed.");

}

// Get the LUID forshutdown privilege.

LookupPrivilegeValue(NULL,SE_SHUTDOWN_NAME,

&tkp.Privileges[0].Luid);

tkp.PrivilegeCount = 1;// one privilege to set

tkp.Privileges[0].Attributes= SE_PRIVILEGE_ENABLED;

// Get shutdown privilegefor this process.

AdjustTokenPrivileges(hToken,FALSE, &tkp, 0,

(PTOKEN_PRIVILEGES)NULL,0);

// Cannot test the returnvalue of AdjustTokenPrivileges.

if (GetLastError() !=ERROR_SUCCESS)

{

ErrorHandler("AdjustTokenPrivilegesenable failed.");

}

// Prevent the systemfrom shutting down.

fResult =AbortSystemShutdown(NULL);

if (!fResult)

{

ErrorHandler("AbortSystemShutdownfailed.");

}

// Disable shutdownprivilege.

tkp.Privileges[0].Attributes= 0;

AdjustTokenPrivileges(hToken,FALSE, &tkp, 0,

(PTOKEN_PRIVILEGES) NULL,0);

if (GetLastError() !=ERROR_SUCCESS)

{

ErrorHandler("AdjustTokenPrivilegesdisable failed.");

}

break;

关于用户权限(Privileges)的详细信息,可以参见MSDN。

如何注销当前用户

可以使用ExitWindows或ExitWindowsEx函数注销当前用户。

在默认的情况下,当程序调用ExitWindows或ExitWindowsEx注销的时候,WM_QUERYENDSESSION消息也被发送到系统内的每个窗口。窗口所属的程序响应此消息并且返回TRUE表示可以被关闭,如果任意一个程序返回FALSE,注销操作将被取消。

Windows NT/2000以及后续版本:

当一个程序响应WM_QUERYENDSESSION并返回TRUE,那么它就会立刻接受到WM_ENDSESSION消息并马上结束,而不管其他的程序是怎么样回应WM_QUERYENDSESSION消息的。

Windows 95/98/Me:只有当系统内所有的程序都对WM_QUERYENDSESSION消息回应TRUE之后,他们才会一起接受到WM_ENDSESSION 消息,然后结束。

如果要强制关闭所有的程序,使用ExitWindowsEx函数,指定EXW_FORCE标志。如果这样做,系统不发送WM_QUERYENDSESSION 消息,而直接终止正在运行的程序。

在注销的时候,系统还向每一个进程发送CTRL_LOGOFF_EVENT 控制码。控制台程序可以注册一个HandlerRoutine例程来处理这个控制码(使用SetConsoleCtrlHandler函数)。(更多的关于控制台的控制码,参见MSDN里“HandlerRoutine”有关章节)。

综上所述:只有所有的程序都允许退出,注销操作才能成功。如果某一个程序响应WM_QUERYENDSESSION并返回FALSE ,用户则不能被注销。这样就可以写出防止用户注销或关闭的程序(非强制情况)。

//这是注销当前用户的代码

ExitWindows(0, 0);

//响应WM_QUERYENDSESSION消息,如果在弹出消息框里选择NO,则取消注销。

case WM_QUERYENDSESSION:

{

int r;

r = MessageBox(NULL,"Shut down?","WM_QUERYENDSESSION", MB_YESNO);

// Return TRUE to allowshutdown, FALSE to stop.

return r == IDYES;

break;

}

如何锁定工作站

使用LockWorkStation函数即可锁定工作站。系统会显示一个锁定对话框,告诉用户此工作站正在使用并且已经被锁定,可以被执行锁定的用户或管理员解锁,解锁的方式是按下CTRL_ALT_DEL并用正确的帐号和密码登陆。

LockWorkStation函数成功调用的条件是:

1. 调用者必须是运行在系统交互桌面上的一般进程。

2. 必须已经有用户登陆到系统

3. 工作站未被锁定。

拥有正常窗口和消息队列的程序通过WM_QUERYENDSESSION或WM_ENDSESSION消息获得关闭通知。

控制台则是在其控制流程(Handle Routines)里接受关闭通知。要注册一个控制台控制流程,应该使用SetConsoleCtrlHandler函数

服务程序在其控制流程里接受退出通知。要注册一个服务控制流程,应该使用RegisterServiceCtrlHandlerEx函数。

关闭系统函数列表

函数名          函数功能描述

AbortSystemShutdown    取消由InitSystemShutdown引起的系统关闭操作

ExitWindows                    注销当前用户

ExitWindowsEx               注销用户,关闭计算机,关闭计算机并且重启

InitiateSystemShutdown  发起关闭系统操作,可以选择关闭后重启

InitiateSystemShutdownEx     同InitiateSystemShutdown,扩展的功能是可以在系统 事件日志(事件号6006)中写入一个用户指定的双字节码

LockWorkStation             锁定工作站

系统关闭消息                  WM_ENDSESSION

wParam:表示是否要终止程序。如果是TRUE:指令该程序终止,否则是FALSE。

lParam:表示用户注销还是系统被关闭。如果此参数包含ENDSESSION_LOGOFF(lParam在这里是按位取值的)位,则表示是用户注销。

Windows 2000 以及后续版本:如果lParam==0,则表示系统被关闭。

程序收到此消息,如果wParam为TRUE,在完成消息处理后,程序随时都有可能被关闭。所以在此消息的处理过程里,应该尽量完成程序销毁前所需要进行的工作。

WM_QUERYENDSESSION

wParam

保留,未使用

lParam

同WM_ENDSESSION;

DefWindowProc默认返回:TRUE。

系统关机函数ExitWindowsEx详解相关推荐

  1. C 语言中获取系统时间的函数,C/C++如何获取当前系统时间的实例详解

    C/C++如何获取当前系统时间的实例详解 C库中与系统时间相关的函数定义在头文件中, C++定义在头文件中. 一.time(time_t*)函数 函数定义如下: time_t time (time_t ...

  2. 2010年系统架构师考试题详解

    原文地址为: 2010年系统架构师考试题详解 考试科目一:综合知识 采用微内核结构的操作系统提高了系统的灵活性和可扩展性,(1) (1)A.并增强了系统的可靠性和可移植性,可运行于分布式系统中 B.并 ...

  3. python int函数详解_Python内置函数OCT详解

    英文文档:oct ( x ) Convert an integer number to an octal string. The result is a valid Python expression ...

  4. ioctl 函数 参数 详解

    2019独角兽企业重金招聘Python工程师标准>>> ioctl 函数 参数 详解 2009-04-24 11:55 ioctl函数 本函数影响由fd参数引用的一个打开的文件. # ...

  5. python getopt_python 5种 statsPython中的getopt函数使用详解

    函数原型: getopt.getopt(args, shortopts, longopts=[]) 参数解释: args:args为需要解析的参数列表.一般使用sys.argv[1:],这样可以过滤掉 ...

  6. php symlink,php函数symlink详解

    php函数symlink详解 建立符号链接 (symbolic link),类似于Windows里头常用的.lnk快捷方式 symlink语法: int symlink(string target, ...

  7. mysql字段uuid_MySQL UUID函数的详解(转)

    MySQL UUID函数的详解 MySQL中可以有二类用于生成唯一值性质的工具:UUID()函数和自增序列,那么二者有何区别呢?我们就此对比下各自的特性及异同点: l  都可以实现生成唯一值的功能: ...

  8. 2015年系统架构师考试题详解

    原文地址为: 2015年系统架构师考试题详解 考试科目一:综合知识 某航空公司机票销售系统有n个售票点,该系统为每个售票点创建一个进程Pi(i=1,2,-,n)管理机票销售.假设Tj(j=1,2,-, ...

  9. python text函数_python可视化text()函数使用详解

    python可视化text()函数使用详解 这篇文章主要介绍了python可视化text()函数使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考 ...

最新文章

  1. php 快速导出csv,php快速导出csv格式数据程序代码
  2. 怎么把项目推到gitlab上_将本地项目添加到 GitLab 上管理
  3. 采购订单的审批状态异常的处理,审批状态为:预审批或是处理中的单据
  4. 64位linux下was宕机,was7经常自动宕机,前方告急,工程师面临崩溃.小弟跪上
  5. Java 性能优化实战记录(1)---定位并分析耗cpu最多的线程
  6. java biginterger_Java BigInteger类知识点总结
  7. C++ Primer ----- 关于初始化
  8. 利用Bing翻译API简单的实现一个翻译工具
  9. SpringMVC子父容器源码剖析
  10. thinkpad重装系统不引导_4个步骤,轻松解决电脑重装系统【蓝屏】
  11. 02-创建hibernate工程
  12. mac 设置环境变量path的几种方法
  13. z变换解差分方程例题_Z变换及差分方程的求解
  14. Docker 容器内体验 WebSSH
  15. 访问网络计算机提示0 80070035,win7访问局域网共享文件出现 0x80070035错误的解决办法...
  16. Qt编写水波进度条控件
  17. Unity2D学习笔记Day12:敌人统一死亡动画+Class的继承(含虚函数virtual,重写override)
  18. matlab 7x5 棋盘格,matlab画棋盘格程序
  19. AWS全球年度技术大会--上海站、广州站
  20. rsvp.exe,AdskScSrv.exe ,avp.exe

热门文章

  1. scrapy爬虫框架入门实战
  2. 微信公众平台客户端调试工具
  3. SQL_Server_2008完全学习之第六章数据查询和管理
  4. linux用户空间内存分布,了解linux 64位地址空间内存布局
  5. 互联网搜索的哪些环节 机器学习_什么是机器学习?有哪些分类?到底有什么用?终于有人讲明白了...
  6. tomcat相关问题汇总
  7. 云端部署大数据解决方案该用IaaS还是PaaS?
  8. SASS优化响应式断点管理
  9. C#中类的默认访问是私有的
  10. 88.http反向代理proxy处理请求的流程