leibin0121 发表于 2013-10-3 16:17:59

如何准备获取用户是关机还是重启或者注销?

如何准备获取用户是关机还是重启或者注销?

xms77 发表于 2013-10-4 22:19:41

这个好像不是容易做到的,我原先也想侦测关机或者重启命令来着,但是不知道怎么做。

qhdpc 发表于 2013-10-15 15:19:57

回复 1# leibin0121

关机,重启,注销,如果通过你的软件点击的话你可以获取,如果通过系统自带,这个真不知道了,,

不会,能做到吗?不知道

wuyaqi 发表于 2013-10-15 21:27:05

1. 用户发起关机指令以后,发起关机指令的程序会通知Windows子系统CSRSS.EXE,CSRSS.EXE收到通知以后会和Winlogon.EXE做一个数据交换,接着由Winlogon.EXE通知CSRSS.EXE开始关闭系统的流程 。
  
  2. CSRSS.EXE收到Winlogon.EXE的通知以后,会依次查询拥有顶层窗口的用户进程,让这些用户进程退出。如果某一个用户进程在一个默认的超时时间5000毫秒(可以通过修改注册表键值HKEY_CURRENT_USER/Cont rol Panel/Desktop/ HungAppTimeout设定超时时间)内没有退出的话,Windows会显示一个结束任务对话框用于询问用户是否结束这个任务。默认情况下将显示这个对话框并一直保持而不会自动关闭。对于控制台程序来说,基本情况类似,只不过Windows使用HK EY_CURRENT_USER/Control Panel/Desktop/ WaitToKillAppTimeout值来设置超时时间。
  
  3. 接着是轮到终止系统进程了。系统进程包括SMSS.EXE、Winlogon.EXE、Lsass.EXE等。Windows在终止系统进程的时候并不像终止用户进程那样如果无法在规定时间内终止则提示用户,而是跳过这个进程,去执行下一个系统 进程的终止操作。使用的超时时间和第2步使用的时间相同。
  
  上述3个步骤是整个Windows关机过程中最耗费时间的一段,大多数关机缓慢的原因都是因为这3个步骤引起的。完成前3个步骤以后,进入了关机操作的第4个阶段,也是最后一个阶段。
  
  4. Winlogon.EXE调用一个原生API函数NtShutdownSystem()来命令系统执行后面的扫尾工作。在这个阶段里面,Windows执行子系统会完成最后的关机操作,例如:设备驱动在这个阶段里面完成一些驱动设定的特殊操作; 也是在这个阶段,配置管理系统将被修改过的注册表数据会写到磁盘里面。等除了电源管理以后的全部子系统完成退出以后,电源管理完成最后的操作:如重启、关机等。

wuyaqi 发表于 2013-10-15 21:28:50

你可以监控最后那个函数,看看传过来的参数,如果有什么发现,建议写博客,让大家共享.

user3000 发表于 2013-10-15 21:48:28

回复 2# xms77

论坛上有过示例:
;http://msdn.microsoft.com/en-us/library/ms686227(v=vs.85).aspx
DllCall("Kernel32", "ubyte", "SetProcessShutdownParameters", "dword", 1024, "dword", 1) ;更改关机级别 0 - 1024 级别越高程序在系统关闭时越早关闭
#cs
BOOL WINAPI SetProcessShutdownParameters(
__inDWORD dwLevel,
__inDWORD dwFlags
);
#ce

;http://msdn.microsoft.com/en-us/library/aa376889(v=vs.85).aspx
;http://msdn.microsoft.com/en-us/library/aa376890(v=vs.85).aspx

GUIRegisterMsg(0x0011, "WindowProc") ; WM_QUERYENDSESSION
GUIRegisterMsg(0x0016, "WindowProc") ; WM_ENDSESSION

#cs
#define WM_QUERYENDSESSION 0x0011
#define WM_ENDSESSION 0x0016
#ce

#cs
LRESULT CALLBACK WindowProc(
HWND hwnd,      // handle to window
UINT uMsg,      // message identifier
WPARAM wParam,// not used
LPARAM lParam   // logoff option
);
#ce

GUICreate("test")
$Edit = GUICtrlCreateEdit("", 50, 35, 300, 330)

GUISetSTate()
Do
Until GUIGetMsg() = -3

Func WindowProc($hWnd, $MsgID, $WParam, $LParam)
      GUICtrlSetData($Edit,GUICtrlRead($Edit) & "Time: " & StringFormat("%2d:%2d:%2d",@HOUR,@MIN,@SEC) & @CRLF& "Msg: 0x" & Hex($MsgID) & @CRLF& "LParam: 0x" & Hex($LParam) & @CRLF)
    Return False
EndFunc

benkel 发表于 2013-10-17 10:11:48

回复 6# user3000

大大这个只能监听到关机信息,但是无法识别是关机、注销还是重启,要识别还是要用到HOOK吧!之前写过HOOK的东东,但是识别也不太准确,期待大牛!

chishingchan 发表于 2013-10-20 12:59:21

顶起!这个我也想知道!
页: [1]
查看完整版本: 如何准备获取用户是关机还是重启或者注销?