views:

3500

answers:

3

Hi,

I have an application in C# (2.0 running on XP embedded) that is communicating with a 'watchdog' that is implemented as a Windows Service. When the device boots, this service typically takes some time to start. I'd like to check, from my code, if the service is running. How can I accomplish this? Thanks

+4  A: 

Please have a look on the ServiceController object in .NET.

controlbreak
Oooh...even better than rolling your own via WMI. I'll remove my answer.
EBGreen
@EBGreen - I don't know, the WMI route may be useful for someone else in future, there's more than one way to skin a cat, and all that....
Carl
Ya, but I really do think ServiceController is better over all, so I think I will leave it deleted. I never would have even suggested WMI if I hadn't just woken up. :)
EBGreen
+22  A: 

I guess something like this would work:

using System.ServiceProcess;

ServiceController sc = new ServiceController(SERVICENAME);

switch (sc.Status)
{
    case ServiceControllerStatus.Running:
        return "Running";
    case ServiceControllerStatus.Stopped:
        return "Stopped";
    case ServiceControllerStatus.Paused:
        return "Paused";
    case ServiceControllerStatus.StopPending:
        return "Stopping";
    case ServiceControllerStatus.StartPending:
        return "Starting";
    default:
        return "Status Changing";
}

Edit: There is also a method sc.WaitforStatus() that takes a desired status and a timeout, never used it but it may suit your needs.

Edit: Once you get the status, to get the status again you will need to call sc.Refresh() first.

Carl
ServiceController.GetServices() retrieves a array that contains all the installed service as ServiceController object. This may help a lot.
controlbreak
Good call, I don't know if I've ever used that. Even if you never use it, I guess that it would be useful for debugging if nothing else
Carl
sc.WaitforStatus() was exactly what I need. Thx
edosoft
Add reference to System.ServiceProcess and add the statement:using System.ServiceProcess;
NealWalters
If I passed a bad service name, it seemed to lock up instead of throwing an error. I added this code: catch (System.Exception ex) { return "Not found"; }
NealWalters
NealWalters: How do you know the exception was thrown just because the service was not found? Isn't there a more suitable exception type to catch?
Patrik
A: 
int __fastcall MyServiceStatus(AnsiString aServiceName){

//SERVICE_CONTINUE_PENDING 0x00000005 The service continue is pending.
//SERVICE_PAUSE_PENDING 0x00000006 The service pause is pending.
//SERVICE_PAUSED 0x00000007 The service is paused.
//SERVICE_RUNNING 0x00000004 The service is running.
//SERVICE_START_PENDING 0x00000002 The service is starting.
//SERVICE_STOP_PENDING 0x00000003 The service is stopping.
//SERVICE_STOPPED 0x00000001 The service is not running.

DWORD dwResult      = 0;
SC_HANDLE hSCM      = NULL;
SC_HANDLE hService  = NULL;
do{
// Connect to the SCM
hSCM = ::OpenSCManager( NULL, NULL, SC_MANAGER_CONNECT );
if( hSCM == NULL){
dwResult = GetLastError();
return dwResult;
}
// Open the service
hService = ::OpenService( hSCM, aServiceName.c_str(), SERVICE_STOP | SERVICE_QUERY_STATUS ); //Null not exist
if( hService == NULL ){
dwResult = GetLastError();
return dwResult;
}
// Ask the service to the status
_SERVICE_STATUS pss;

if(!QueryServiceStatus(hService, &pss)){
DWORD dwErrCode = GetLastError();
if( dwErrCode != ERROR_SERVICE_NOT_ACTIVE ){
dwResult = dwErrCode;
return dwResult;
}
}
dwResult = pss.dwCurrentState;
}while(0);

// Cleanup

if( hService != NULL )
CloseServiceHandle( hService );

if( hSCM != NULL )
CloseServiceHandle( hSCM );

return dwResult;
}
Ali Abdalaziz