I have created a service exe that will autourun at boot.
I am using this example to create the service: http://www.cromis.net/blog/2011/04/how-to-make-a-very-small-windows-service-executable/
Works pretty well. The service needs to 'monitor' the state of the PC, for example to check if the PC is connected to a powersupply or not. In case of a change, for example from connected power to battery or low battery status, it will send an emergency email about the critical state of the device.
This works pretty well when running as a normal exe but not as a service. The goal is to be able to do this at any state of the pc (logged in or not), so it is essential to be run as a service.
I have created a window handle to receive the WM_POWERBROADCAST message, for example:
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;
To initialize I am using this:
FHwnd:=AllocateHWnd(wndProc);
Because I am aware of 0-isolation state when running as a service, I changed some example code of RegisterService() function with this:
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;
But without any success. I have also use a thread to poll messages with windows API function getMessage()
from the window but the results are the same.
What can I do to catch powerstate events? It's kind of weird that services cannot react on powerstate changes or not?