I\'m trying to write a program in C, that can detect when some Windows services (aka. NT services) are started or stopped.
There seems to be a function NotifyService
You will need to do it by polling. Place the code in a separate thread and send it to sleep for as long as reasonable. Say every second, perhaps even 5 seconds to minimize system performance.
As a 'c' example for a single service:
// various handles and strings plus... SERVICE_STATUS ssStatus; ...
schSCManager = OpenSCManager( ServiceComputerNameStr,
NULL,
SC_MANAGER_ALL_ACCESS );
if ( schSCManager == NULL )
{
// ... error stuff
goto cleanup;
}
scphService = OpenService( schSCManager,
ServiceNameStr,
// SERVICE_QUERY_STATUS );
SERVICE_ALL_ACCESS );
if ( scphService == NULL )
{
// ... error stuff
goto cleanup;
}
if ( !QueryServiceStatus(scphService, ssStatus) )
{
// ... error stuff
goto cleanup;
}
The result you want will be in the ssStatus.dwCurrentState.
Looks like the closest you can get in XP is QueryServiceStatusEx (single service) or EnumServicesStatusEx (multiple services).
To avoid repeatedly calling either of these, some recommend a WMI setup, querying Win32_Service
's state
property. See the bottom of this thread for more details.
The following is a (basic) WMI script to monitor the alerter service's status:
strComputer = "."
Set objSWbemServices = GetObject("winmgmts:" &_
"{impersonationLevel=impersonate}!" &_
"\\" & strComputer & "\root\cimv2")
Set objEventSource = objSWbemServices.ExecNotificationQuery( _
"SELECT * FROM __InstanceModificationEvent " &_
"WITHIN 10 " &_
"WHERE TargetInstance " &_
"ISA 'Win32_Service' " &_
"AND TargetInstance.Name = 'alerter'")
Set objEventObject = objEventSource.NextEvent()
Wscript.Echo "The status of the alerter service just changed."
The above, and additional examples, may be found on this TechNet page.