Cod*_*eat 0 windows delphi api service power-state
我已经创建了一个服务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;
Run Code Online (Sandbox Code Playgroud)
要初始化我正在使用这个:
FHwnd:=AllocateHWnd(wndProc);
Run Code Online (Sandbox Code Playgroud)
因为我在作为服务运行时意识到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;
Run Code Online (Sandbox Code Playgroud)
但没有任何成功.我还使用一个线程getMessage()
从窗口轮询带有Windows API函数的消息,但结果是一样的.
我能做些什么来捕捉powerstate事件?有些奇怪的是服务无法对powertate的变化做出反应?
当服务使用时SERVICE_ACCEPT_POWEREVENT
,服务必须使用HandlerEx()
回调RegisterServiceCtrlHandlerEx()
来接收SERVICE_CONTROL_POWEREVENT
来自SCM的通知.但是,您链接到的示例代码(以及Delphi自己的TService
框架)使用过时的Handler()
回调来RegisterServiceCtrlHandler()
代替,它不接收此类通知.因此,您需要更新代码以使用HandlerEx()
回调.
或者,要在不使用SCM回调的情况下接收电源通知,请查看RegisterPowerSettingNotification()
或PowerSettingRegisterNotification()
分别向HWND或回调函数发送电源通知.
归档时间: |
|
查看次数: |
1181 次 |
最近记录: |