我正在寻找“RunOnceEx”的反向版本。
RunOnceEx 确实在用户的外壳(桌面和任务栏)启动之前运行了一些程序。在 runonceex 完成之前,登录进度将不会继续。
我想做完全相同的事情,但在用户注销时。当她/他注销时,所有正在运行的程序都关闭,离开shell(桌面和任务栏),然后“我希望我的程序在这一刻执行”,最后注销。
我认为这是可能的,因为“mobsync.exe”正在这样做。但我找不到在哪里以及如何做。
我正在寻找“RunOnceEx”的反向版本。
RunOnceEx 确实在用户的外壳(桌面和任务栏)启动之前运行了一些程序。在 runonceex 完成之前,登录进度将不会继续。
我想做完全相同的事情,但在用户注销时。当她/他注销时,所有正在运行的程序都关闭,离开shell(桌面和任务栏),然后“我希望我的程序在这一刻执行”,最后注销。
我认为这是可能的,因为“mobsync.exe”正在这样做。但我找不到在哪里以及如何做。
警告,如此处所述,将允许您为所有用户gpedit.msc
配置注销脚本。
如果您只需要一个用户的脚本,您需要直接在注册表中声明它,在HKCU
和HKLM
.
To run this only for the current user, you can use WMI to get an information when a shutdown/logout occurs.
Either you write a small C# (or any other language that can use WMI) application or vbs script to listen on the Win32_ComputerShutdownEvent WMI event.
An example C# app can be found here in this question: Get Log off event from system
如果您希望正在运行的程序在注销时执行代码,那么您应该挂钩该WM_QUERYENDSESSION
消息并查找(0x80000000)的lParam
值。ENDSESSION_LOGOFF
测试这个lParam
值很重要,因为其他值表示“强制关闭” - 即您的进程可能在您的代码甚至被允许运行之前被终止。事实上,大多数关闭/会话结束消息只是为了让您有机会运行最后一分钟的清理代码,并且对长时间运行的操作进行响应并不安全;但是这种特殊的组合应该没问题。
Note: I've never tried to actually run a separate process in response to the WM_QUERYENDSESSION
message. It's possible that the window manager will disallow this, like it does during shutdown. Try it and see, I guess.
If you're in a .NET environment (you didn't specify), a quicker way is to add an event handler to the Microsoft.Win32.SystemEvents.SessionEnding
event.
您需要的是GINA的实现。您可以在WlxIsLogoffOk函数中运行自定义命令,该函数在用户启动注销时调用
创建正确的 GINA dll 后,您可以在此处注册它:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\@GinaDLL
这是一个可能满足您需求的实现(它提供了一个注销注册表项,您可以在其中指定您的命令): http ://wwwthep.physik.uni-mainz.de/~frink/newgina_pre09/readme.html
正如 VonC 和 TFD 已经提到的,组策略编辑器只是操纵注册表的另一种方式。
只需使用 gpedit 进行您喜欢的更改(在 Userconfig - Windows 设置 - 脚本中),然后查看注册表[HKEY_CURRENT_USER\Software\Policies\Microsoft\Windows\System\Scripts]
以了解如何直接执行此操作。
在我的 PC 上(挂在域中)还有一个隐藏文件夹C:\WINDOWS\System32\GroupPolicy
,其中包含用于用户和机器的子文件夹。两者都有额外的子文件夹,称为 Shutdown 和 Startup。也许你也可以使用这些。
如果您需要一些简单的东西并为单个(或任何)用户工作,您可以使用 C++ 或 C# 制作一个简单的应用程序。
最简单的方法是在托盘中有一个 C#(只需将托盘组件添加到表单中),并为FormClosing事件注册和事件处理程序。它看起来像这样:
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (e.CloseReason != CloseReason.UserClosing)
{
// It's not the user closing the application,
// Let's do whatever you want here, for example starting a process
Process notePad = new Process();
notePad.StartInfo.FileName = "notepad.exe";
notePad.StartInfo.Arguments = "ProcessStart.cs";
notePad.Start();
}
}
因此,您的应用程序将使用 Windows 或用户启动。它会等待(使用一点内存)并在系统关闭或用户注销等时执行某些操作(通过检查上面的“CloseReason”)。