【发布时间】:2015-03-08 12:55:47
【问题描述】:
我创建了一个将在启动时自动运行的服务 exe。
我正在使用这个例子来创建服务: http://www.cromis.net/blog/2011/04/how-to-make-a-very-small-windows-service-executable/
效果很好。该服务需要“监控”PC 的状态,例如检查 PC 是否连接到电源。如果发生变化,例如从连接电源变为电池或电池电量不足,它将发送有关设备严重状态的紧急电子邮件。
当作为普通 exe 而不是作为服务运行时,这非常有效。目标是能够在 PC 的任何状态(登录或未登录)下执行此操作,因此必须作为服务运行。
我已经创建了一个窗口句柄来接收 WM_POWERBROADCAST 消息,例如:
procedure TEventAlerter.wndProc(var Msg : TMessage);
var
handled: Boolean;
begin
log( 'wndProc processed - '+intToStr( Msg.Msg ));
// Assume we handle message
handled := TRUE;
case( Msg.Msg ) of
WM_POWERBROADCAST : begin
case( Msg.WParam ) of
PBT_APMPOWERSTATUSCHANGE : powerChangeEvent(Msg.WParam);
PBT_APMBATTERYLOW : powerLowEvent(Msg.WParam);
else powerEvent(Msg.WParam);
end;
end;
else handled:= FALSE;
end;
if( handled ) then
begin
// We handled message - record in message result
Msg.Result := 0
end
else
begin
// We didn't handle message
// pass to DefWindowProc and record result
Msg.Result := DefWindowProc(fHWnd, Msg.Msg, Msg.WParam, Msg.LParam);
end;
end;
要初始化我正在使用这个:
FHwnd:=AllocateHWnd(wndProc);
因为我在作为服务运行时知道 0 隔离状态,所以我更改了 RegisterService() 函数的一些示例代码:
ServiceStatus.dwServiceType := SERVICE_WIN32_OWN_PROCESS or SERVICE_INTERACTIVE_PROCESS;
ServiceStatus.dwCurrentState := SERVICE_START_PENDING;
ServiceStatus.dwControlsAccepted := SERVICE_ACCEPT_STOP or
SERVICE_ACCEPT_PAUSE_CONTINUE or
SERVICE_ACCEPT_POWEREVENT;
但没有任何成功。我还使用线程从窗口中使用 Windows API 函数getMessage() 轮询消息,但结果是相同的。
我可以做些什么来捕捉 powerstate 事件?服务无法对电源状态更改做出反应,这有点奇怪?
【问题讨论】:
-
询问 WMI -> Win32_Battery
-
您需要“Ex”版本 (RegisterServiceCtrlHandlerEx),而不是消息泵和窗口。请参阅文档。
-
请原谅我的回复晚了,但有人可以向我解释一下为什么对这个问题投反对票是值得的吗?
标签: windows api delphi service power-state