Как программно определить, когда ОС (Windows) просыпается или идет спать - PullRequest
4 голосов
/ 14 января 2011

Фон

Мой сын любит использовать свой ноутбук, когда он не должен, и я просто подумал, что было бы удобно, если бы я мог написать приложение, которое будет отправлять мне электронное письмо всякий раз, когда он открывает / закрывает свой ноутбук.

(я бы даже согласился на то, что уведомляло меня, когда на машине был сетевой трафик)

Вопрос

Как вы программно определяете, когда ОС просыпается или спит? Я нашел эту ссылку от этот пост . Но это касается OS X. Я ищу то же самое для Windows 7.

(Я хотел бы сделать это на Java, если это возможно, но я бы согласился на C # / C ++)

Ответы [ 6 ]

7 голосов
/ 15 января 2011

Самый простой способ - вообще не писать никакого кода, даже если это переполнение стека.Нажмите Пуск, введите Расписание и выберите Запланированные задачи.Установите один (нажмите «Создать задачу») и установите триггер, когда машина разблокирована.Акция отправит вам электронное письмо.

new trigger new action

Повторите для запуска и при входе пользователя, если хотите.Готово.

5 голосов
/ 14 января 2011

Вы захотите создать окно и следить за сообщением 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

3 голосов
/ 06 февраля 2012

Я долго искал и обнаружил, что это был лучший способ, событие 'Sleep' никогда раньше не работало:

 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();
    }
1 голос
/ 14 января 2011

Очень простой, возможно грубый, но эффективный способ может заключаться в том, чтобы программа запускала таймер каждую минуту. Если таймер срабатывает и, скажем, прошло 5 минут реального времени с момента его последнего выполнения, то вы, вероятно, можете предположить, что компьютер спал, поскольку маловероятно, что ваш поток не может быть запланирован так долго.

Другой причиной такой разницы может быть настройка часов, такая как DST или ручное изменение, но этот тип "шума" должен быть очень низким, в вашем сценарии.

0 голосов
/ 14 января 2011

http://www.pinvoke.net/default.aspx/powrprof.CallNtPowerInformation - Проверить ссылку.Он имеет почти все win32api для всех функций Windows.Вы можете вызвать функцию управления питанием прямо на вашем ноутбуке с Windows 7.Для этого создайте службу Windows, которая будет использовать эти конкретные API для уведомления о состоянии компьютера.

0 голосов
/ 14 января 2011

Вы можете написать простое приложение и зарегистрировать его в качестве службы Windows, которое будет запускаться автоматически при запуске системы. Это приложение может затем делать все, что вы хотите, когда оно запускается. И если это правильное приложение для Windows, оно может зарегистрироваться, чтобы получать уведомления о предстоящем отключении системы (подробности не помню, но я реализовал это в приложении C ++ MFC много лет назад).

Если вы предпочитаете Java, вы можете зарегистрировать свое приложение в качестве службы с помощью подходящей оболочки службы, например Tanuki (похоже, у них есть бесплатная опция Community License). Хотя это может быть излишним. И может быть в состоянии получить уведомление о закрытии JVM, когда система закрывается (но у меня нет никакого конкретного опыта с этим).

...