簡體   English   中英

如何以編程方式檢測操作系統(Windows)何時喚醒或進入睡眠狀態

[英]How to programmatically detect when the OS (Windows) is waking up or going to sleep

背景

我的兒子喜歡在他不應該使用他的筆記本電腦時,我只是覺得如果我能寫一個應用程序,只要他打開/關閉他的筆記本電腦就會給我發電子郵件,這會很方便。

(我甚至會滿足於在機器上有網絡流量時通知我的事情)

如何以編程方式檢測操作系統何時喚醒或進入睡眠狀態? 我在這篇 相關文章中找到了這個鏈接 但這涵蓋了OS X.我正在為Windows 7尋找相同的東西。

(如果可能的話,我想用Java做這個,但我會選擇C#/ C ++)

最簡單的方法是不寫任何代碼,即使這是堆棧溢出。 單擊開始,鍵入計划,然后選擇計划任務。 設置一個(單擊“創建任務”)並在機器解鎖時設置觸發器。 對於Action,請讓它給您發送電子郵件。

新的觸發器新行動

如果需要,重復啟動和用戶登錄時。 完成。

您將要創建一個窗口並觀察WM_POWERBROADCAST消息( http://msdn.microsoft.com/en-us/library/aa373248%28v=vs.85%29.aspx )並檢查wParam你想要的行動。 例如,當系統即將進入掛起狀態(即關閉筆記本電腦)時,窗口應該收到帶有PBT_APMSUSPEND的WM_POWERBROADCAST作為wParam。 恢復似乎有幾個不同的wParam值:PBT_APMRESUMESUSPEND,PBT_APMRESUMECRITICAL和PBT_APMRESUMEAUTOMATIC

我搜索了很長時間,發現這是最好的方式,'睡眠'事件以前從未工作過:

 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();
    }

一個非常簡單,也許粗糙但有效的方法可能是讓程序每分鍾都有一個計時器。 如果計時器觸發並且比如上次執行后的5分鍾實時,那么您可能會認為計算機正在睡眠,因為您的線程不太可能無法安排這么長時間。

差異的另一個原因可能是時鍾調整,如DST或手動更改,但在您的方案中,這種“噪音”應該非常低。

您可以編寫一個簡單的應用程序並將其注冊為Windows服務,以便在系統啟動時自動啟動。 這個應用程序可以在它啟動時做任何你想做的事情。 如果它是一個合適的Windows應用程序,它可以注冊以獲得有關即將發生的系統關閉的通知(我不記得詳細信息,但我多年前在C ++ MFC應用程序中實現了這一點)。

如果你更喜歡Java,你可以通過像Tanuki這樣的合適的服務包裝器將你的應用程序注冊為服務(似乎他們有免費的社區許可證選項)。 雖然這可能有點過頭了。 並且有可能在系統關閉時獲得關於JVM關閉的通知(但我沒有具體的經驗)。

http://www.pinvoke.net/default.aspx/powrprof.CallNtPowerInformation - 查看鏈接。 它幾乎都具有所有windows功能的win32api。 您可以直接在Windows 7筆記本電腦中調用電源管理功能。 為此創建一個Windows服務,它將使用這些特定的api來通知機器狀態。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM