GreenMonitor:一款节能软件的开发之旅

作为一名软件工程师,在一家软件公司工作,一直致力于通过GreenUtils项目来推动能源的节约。

大多数信息技术公司都有相应的电力政策。例如,如果计算机在10分钟内处于空闲状态,则自动关闭显示器;如果20分钟内未操作,则使系统进入待机状态。这些设置通过Windows电源策略进行配置,有助于节省大量电力。

根据观察,还可以在其他方面实施电力节省措施,例如在系统锁定时立即关闭显示器。锁定计算机是几乎所有信息技术公司都遵循的常见做法。因此,如果考虑这个因素,可以实现相当可观的能源节省。

GreenMonitor

将这个应用程序命名为GreenMonitor,并且可以从GreenUtils免费下载。

通过本文,想分享开发GreenMonitor的经验。

使用了Windows终端服务来捕获系统锁定和解锁事件。可以使用WTSRegisterSessionNotification()注册以接收Windows终端服务通知。之所以没有使用全局键盘钩子,有两个原因:

  • 系统安全性的妥协
  • 系统性能的妥协

以下是使用WTSRegisterSessionNotification()的代码片段:

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { HWND hWnd; hInst = hInstance; hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); if (!hWnd) { return FALSE; } UpdateWindow(hWnd); WTSRegisterSessionNotification(hWnd, NOTIFY_FOR_THIS_SESSION); return TRUE; }

在InitInstance()方法中使用了WTSRegisterSessionNotification(),就在创建窗口成功后。从InitInstance()中移除了ShowWindow()调用,因为应用程序在后台运行,用户不应该看到任何用户界面。

一旦将应用程序的句柄注册到终端服务,系统就会发送以下通知:

WTS_CONSOLE_CONNECT WTS_CONSOLE_DISCONNECT WTS_REMOTE_CONNECT WTS_REMOTE_DISCONNECT WTS_SESSION_LOGON WTS_SESSION_LOGOFF WTS_SESSION_LOCK WTS_SESSION_UNLOCK WTS_SESSION_REMOTE_CONTROL

这些通知被发送到WndProc方法,其句柄已使用WTSRegisterSessionNotification()注册。

一旦能够捕获Windows锁定/解锁通知,就使用了简单的Windows SendMessage()来发送系统命令关闭显示器。

以下是如何使用SendMessage关闭显示器的代码片段。有关如何使用SendMessage进行各种显示器操作的更多信息,请。

SendMessage(HWND_BROADCAST, WM_SYSCOMMAND, SC_MONITORPOWER, (LPARAM)2);

以下代码片段显示了WndProc方法:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_DESTROY: WTSUnRegisterSessionNotification(hWnd); PostQuitMessage(0); break; case WTS_SESSION_LOCK: SendMessage(HWND_BROADCAST, WM_SYSCOMMAND, SC_MONITORPOWER, (LPARAM)2); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }

架构

最初,考虑将整个应用程序作为一个服务来创建。软件的第一个版本实际上是一个服务,但当尝试将服务从XP移植到Vista和Win 7时,开始遇到复杂的问题。

从Vista开始,微软严格实施了会话隔离的概念。每个用户都在一个单独的会话中运行。服务在会话零中运行。服务不应该与用户互动。因此,微软使会话零变得不互动。会话隔离的概念在XP中已经存在,但微软并没有严格实施。

应用程序不应该作为服务运行有两个原因:

  • 在Windows中发送关闭显示器的消息是每个会话的。
  • 检索系统上最后一次交互活动也是每个会话的。使用了GetLastInputInfo()来确定用户最后一次与系统交互的时间。找到最后一次输入时间很重要,以防有人不小心敲击键盘或移动鼠标时系统处于锁定状态。

因此,决定使应用程序特定于会话。应用程序的每个实例在每个会话下运行。

相信文章将帮助开发人员在服务变得互动时可能出现的复杂问题上做出早期决策。还附带了文章的源代码。如果直接想下载安装程序,可以从下载。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485