如何以编程方式检测操作系统 (Windows) 何时唤醒或进入睡眠状态

发布于 2024-10-12 01:48:16 字数 401 浏览 1 评论 0原文

背景

我的儿子喜欢在不应该使用笔记本电脑的时候使用他的笔记本电脑,我只是认为如果我可以编写一个应用程序,每当他打开/关闭笔记本电脑时都会向我发送电子邮件,这会很方便。

(我什至愿意接受当机器上有网络流量时通知我的东西)

问题

如何以编程方式检测操作系统何时醒来或进入睡眠状态?我从 此相关帖子。但这涵盖了 OS X。我正在为 Windows 7 寻找同样的东西。

(如果可能的话,我想用 Java 来做这件事,但我会选择 C#/C++)

Background

My son likes to use his laptop when he's not supposed to and I just thought it would be handy if I could write an application that would email me whenever he opened / closed his laptop.

(I'd even settle for something that notified me when there was network traffic on the machine)

Question

How do you programmatically detect when an OS is waking up or going to sleep? I found this link from this related post. But that covers OS X. I'm looking for the same thing for Windows 7.

(I'd like to do this in Java, if possible, but I'd settle for C#/C++)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

滥情哥ㄟ 2024-10-19 01:48:16

最简单的方法是根本不编写任何代码,即使这是堆栈溢出。单击“开始”,键入“计划”并选择“计划任务”。设置一个(单击“创建任务”)并在机器解锁时设置一个触发器。对于操作,让它向您发送一封电子邮件。

新触发器
new action

如果需要,可在启动时和用户登录时重复此操作。完毕。

Easiest way is not to write any code at all, even though this is stack overflow. Click Start, type Schedule and choose Scheduled Tasks. Set one up (click Create Task) and set a Trigger when the machine is unlocked. For the Action, have it send you an email.

new trigger
new action

Repeat for startup and when a user logs in, if you want. Done.

深陷 2024-10-19 01:48:16

您需要创建一个窗口并监视 WM_POWERBROADCAST 消息 (http://msdn.microsoft.com/en-us/library/aa373248%28v=vs.85%29.aspx)并检查 wParam 以获得所需的操作。例如,当系统即将进入挂起状态(即关闭笔记本电脑)时,您的窗口应该收到 WM_POWERBROADCAST,并将 PBT_APMSUSPEND 作为 wParam。恢复似乎有几个不同的 wParam 值:PBT_APMRESUMESUSPEND、PBT_APMRESUMECRITICAL 和 PBT_APMRESUMEAUTOMATIC

You're going to want to create a window and watch for the WM_POWERBROADCAST message (http://msdn.microsoft.com/en-us/library/aa373248%28v=vs.85%29.aspx) and check the wParam for your desired action. For example, your window should receive a WM_POWERBROADCAST with PBT_APMSUSPEND as the wParam when the system is about to enter a suspended state (i.e. closing a laptop). Resuming seems to have a few different wParam values: PBT_APMRESUMESUSPEND, PBT_APMRESUMECRITICAL and PBT_APMRESUMEAUTOMATIC

最单纯的乌龟 2024-10-19 01:48:16

我搜索了很长时间,发现这是最好的方法,“睡眠”事件以前从未工作过:

 private ManagementEventWatcher managementEventWatcher;
    private readonly Dictionary<string, string> powerValues = new Dictionary<string, string>
                         {
                             {"4", "Entering Suspend"},
                             {"7", "Resume from Suspend"},
                             {"10", "Power Status Change"},
                             {"11", "OEM Event"},
                             {"18", "Resume Automatic"}
                         };
    public void InitPowerEvents()
    {
        var q = new WqlEventQuery();
        var scope = new ManagementScope("root\\CIMV2");

        q.EventClassName = "Win32_PowerManagementEvent";
        managementEventWatcher = new ManagementEventWatcher(scope, q);
        managementEventWatcher.EventArrived += PowerEventArrive;
        managementEventWatcher.Start();
    }
    private void PowerEventArrive(object sender, EventArrivedEventArgs e)
    {
        foreach (PropertyData pd in e.NewEvent.Properties)
        {
            if (pd == null || pd.Value == null) continue;
            var name = powerValues.ContainsKey(pd.Value.ToString())
                           ? powerValues[pd.Value.ToString()]
                           : pd.Value.ToString();
            Console.WriteLine("PowerEvent:"+name);
        }
    }
    public void Stop()
    {
        managementEventWatcher.Stop();
    }

I search for a long time and found that this was the best way, the 'Sleep'-event was never working before:

 private ManagementEventWatcher managementEventWatcher;
    private readonly Dictionary<string, string> powerValues = new Dictionary<string, string>
                         {
                             {"4", "Entering Suspend"},
                             {"7", "Resume from Suspend"},
                             {"10", "Power Status Change"},
                             {"11", "OEM Event"},
                             {"18", "Resume Automatic"}
                         };
    public void InitPowerEvents()
    {
        var q = new WqlEventQuery();
        var scope = new ManagementScope("root\\CIMV2");

        q.EventClassName = "Win32_PowerManagementEvent";
        managementEventWatcher = new ManagementEventWatcher(scope, q);
        managementEventWatcher.EventArrived += PowerEventArrive;
        managementEventWatcher.Start();
    }
    private void PowerEventArrive(object sender, EventArrivedEventArgs e)
    {
        foreach (PropertyData pd in e.NewEvent.Properties)
        {
            if (pd == null || pd.Value == null) continue;
            var name = powerValues.ContainsKey(pd.Value.ToString())
                           ? powerValues[pd.Value.ToString()]
                           : pd.Value.ToString();
            Console.WriteLine("PowerEvent:"+name);
        }
    }
    public void Stop()
    {
        managementEventWatcher.Stop();
    }
﹏半生如梦愿梦如真 2024-10-19 01:48:16

一个非常简单,也许粗暴,但有效的方法可能是让程序每分钟触发一次计时器。如果计时器触发,并且自上次执行以来已经过了 5 分钟的实时时间,那么您可能会认为计算机正在睡眠,因为您的线程不太可能无法调度这么长时间。

造成差异的另一个原因可能是时钟调整,例如夏令时或手动更改,但在您的情况下,这种“噪音”应该非常低。

A very simple, perhaps crude, but effective way may be to have a program with a timer firing every minute. If the timer fires and it's been, say, 5 minutes of real time since its last execution then you can likely assume that the computer was sleeping since it's unlikely that your thread was unable to be scheduled for so long.

The other reason for the difference may be a clock adjustment, like DST or a manual change, but that kind of "noise" should be very low, in your scenario.

无法言说的痛 2024-10-19 01:48:16

您可以编写一个简单的应用程序并将其注册为 Windows 服务,以便在系统启动时自动启动。这个应用程序启动后就可以做任何你想做的事情。如果它是一个合适的 Windows 应用程序,它也可以注册以获取有关即将发生的系统关闭的通知(我不记得详细信息,但我多年前在 C++ MFC 应用程序中实现了这一点)。

如果您更喜欢 Java,您可以通过合适的服务包装器将您的应用程序注册为服务,例如 Tanuki< /a> (似乎他们有免费的社区许可证选项)。尽管这可能有点矫枉过正。并且可能在系统关闭时收到有关JVM关闭的通知(但我对此没有具体经验)。

You could write a simple app and register it as a Windows service, to be started automatically at system startup. This app could then do whatever you want when it starts. And if it's a proper Windows app, it can register to get notification about impending system shutdown too (I don't remember the details but I implemented this in a C++ MFC app many years ago).

If you prefer Java, you could register your app as a service via a suitable service wrapper like Tanuki (it seems they have a free Community License option). Although this might be overkill. And it may be possible to get notification about the JVM shutting down when the system is closing (but I have no concrete experience with this).

无畏 2024-10-19 01:48:16

http://www.pinvoke.net/default.aspx/powrprof.CallNtPowerInformation - 查看链接。它几乎拥有所有windows功能的win32api。您可以直接在 Windows 7 笔记本电脑中调用电源管理功能。为此创建一个 Windows 服务,它将使用这些特定的 api 来通知机器状态。

http://www.pinvoke.net/default.aspx/powrprof.CallNtPowerInformation - Check out the link. It has almost all win32api for all windows function. You can call power management feature directly in your windows 7 laptop. For that create a Windows Service , that will use these specific api to notify the machine state.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文