Note

Access to this page requires authorization. You can try signing in or .

Access to this page requires authorization. You can try .

Starting a Service

To start a service, a service control program opens a handle to an installed database and then specifies the handle in a call to the StartService function. After starting the service, the program uses the members of the SERVICE_STATUS_PROCESS structure returned by the QueryServiceStatusEx function to track the progress of the service.

The DoStartSvc function in the following example shows how to start a service. The szSvcName variable is a global variable that contains the name of the service to be started. For the complete example that sets this variable, see SvcControl.cpp.

//
// Purpose: 
// Starts the service if possible.
//
// Parameters:
// None
// 
// Return value:
// None
//
VOID __stdcall DoStartSvc()
{
 SERVICE_STATUS_PROCESS ssStatus; 
 DWORD dwOldCheckPoint; 
 DWORD dwStartTickCount;
 DWORD dwWaitTime;
 DWORD dwBytesNeeded;

 // Get a handle to the SCM database. 
 
 schSCManager = OpenSCManager( 
 NULL, // local computer
 NULL, // servicesActive database 
 SC_MANAGER_ALL_ACCESS); // full access rights 
 
 if (NULL == schSCManager) 
 {
 printf("OpenSCManager failed (%d)\n", GetLastError());
 return;
 }

 // Get a handle to the service.

 schService = OpenService( 
 schSCManager, // SCM database 
 szSvcName, // name of service 
 SERVICE_ALL_ACCESS); // full access 
 
 if (schService == NULL)
 { 
 printf("OpenService failed (%d)\n", GetLastError()); 
 CloseServiceHandle(schSCManager);
 return;
 } 

 // Check the status in case the service is not stopped. 

 if (!QueryServiceStatusEx( 
 schService, // handle to service 
 SC_STATUS_PROCESS_INFO, // information level
 (LPBYTE) &ssStatus, // address of structure
 sizeof(SERVICE_STATUS_PROCESS), // size of structure
 &dwBytesNeeded ) ) // size needed if buffer is too small
 {
 printf("QueryServiceStatusEx failed (%d)\n", GetLastError());
 CloseServiceHandle(schService); 
 CloseServiceHandle(schSCManager);
 return; 
 }

 // Check if the service is already running. It would be possible 
 // to stop the service here, but for simplicity this example just returns. 

 if(ssStatus.dwCurrentState != SERVICE_STOPPED && ssStatus.dwCurrentState != SERVICE_STOP_PENDING)
 {
 printf("Cannot start the service because it is already running\n");
 CloseServiceHandle(schService); 
 CloseServiceHandle(schSCManager);
 return; 
 }

 // Save the tick count and initial checkpoint.

 dwStartTickCount = GetTickCount();
 dwOldCheckPoint = ssStatus.dwCheckPoint;

 // Wait for the service to stop before attempting to start it.

 while (ssStatus.dwCurrentState == SERVICE_STOP_PENDING)
 {
 // Do not wait longer than the wait hint. A good interval is 
 // one-tenth of the wait hint but not less than 1 second 
 // and not more than 10 seconds. 
 
 dwWaitTime = ssStatus.dwWaitHint / 10;

 if( dwWaitTime < 1000 )
 dwWaitTime = 1000;
 else if ( dwWaitTime > 10000 )
 dwWaitTime = 10000;

 Sleep( dwWaitTime );

 // Check the status until the service is no longer stop pending. 
 
 if (!QueryServiceStatusEx( 
 schService, // handle to service 
 SC_STATUS_PROCESS_INFO, // information level
 (LPBYTE) &ssStatus, // address of structure
 sizeof(SERVICE_STATUS_PROCESS), // size of structure
 &dwBytesNeeded ) ) // size needed if buffer is too small
 {
 printf("QueryServiceStatusEx failed (%d)\n", GetLastError());
 CloseServiceHandle(schService); 
 CloseServiceHandle(schSCManager);
 return; 
 }

 if ( ssStatus.dwCheckPoint > dwOldCheckPoint )
 {
 // Continue to wait and check.

 dwStartTickCount = GetTickCount();
 dwOldCheckPoint = ssStatus.dwCheckPoint;
 }
 else
 {
 if(GetTickCount()-dwStartTickCount > ssStatus.dwWaitHint)
 {
 printf("Timeout waiting for service to stop\n");
 CloseServiceHandle(schService); 
 CloseServiceHandle(schSCManager);
 return; 
 }
 }
 }

 // Attempt to start the service.

 if (!StartService(
 schService, // handle to service 
 0, // number of arguments 
 NULL) ) // no arguments 
 {
 printf("StartService failed (%d)\n", GetLastError());
 CloseServiceHandle(schService); 
 CloseServiceHandle(schSCManager);
 return; 
 }
 else printf("Service start pending...\n"); 

 // Check the status until the service is no longer start pending. 
 
 if (!QueryServiceStatusEx( 
 schService, // handle to service 
 SC_STATUS_PROCESS_INFO, // info level
 (LPBYTE) &ssStatus, // address of structure
 sizeof(SERVICE_STATUS_PROCESS), // size of structure
 &dwBytesNeeded ) ) // if buffer too small
 {
 printf("QueryServiceStatusEx failed (%d)\n", GetLastError());
 CloseServiceHandle(schService); 
 CloseServiceHandle(schSCManager);
 return; 
 }
 
 // Save the tick count and initial checkpoint.

 dwStartTickCount = GetTickCount();
 dwOldCheckPoint = ssStatus.dwCheckPoint;

 while (ssStatus.dwCurrentState == SERVICE_START_PENDING) 
 { 
 // Do not wait longer than the wait hint. A good interval is 
 // one-tenth the wait hint, but no less than 1 second and no 
 // more than 10 seconds. 
 
 dwWaitTime = ssStatus.dwWaitHint / 10;

 if( dwWaitTime < 1000 )
 dwWaitTime = 1000;
 else if ( dwWaitTime > 10000 )
 dwWaitTime = 10000;

 Sleep( dwWaitTime );

 // Check the status again. 
 
 if (!QueryServiceStatusEx( 
 schService, // handle to service 
 SC_STATUS_PROCESS_INFO, // info level
 (LPBYTE) &ssStatus, // address of structure
 sizeof(SERVICE_STATUS_PROCESS), // size of structure
 &dwBytesNeeded ) ) // if buffer too small
 {
 printf("QueryServiceStatusEx failed (%d)\n", GetLastError());
 break; 
 }
 
 if ( ssStatus.dwCheckPoint > dwOldCheckPoint )
 {
 // Continue to wait and check.

 dwStartTickCount = GetTickCount();
 dwOldCheckPoint = ssStatus.dwCheckPoint;
 }
 else
 {
 if(GetTickCount()-dwStartTickCount > ssStatus.dwWaitHint)
 {
 // No progress made within the wait hint.
 break;
 }
 }
 } 

 // Determine whether the service is running.

 if (ssStatus.dwCurrentState == SERVICE_RUNNING) 
 {
 printf("Service started successfully.\n"); 
 }
 else 
 { 
 printf("Service not started. \n");
 printf(" Current State: %d\n", ssStatus.dwCurrentState); 
 printf(" Exit Code: %d\n", ssStatus.dwWin32ExitCode); 
 printf(" Check Point: %d\n", ssStatus.dwCheckPoint); 
 printf(" Wait Hint: %d\n", ssStatus.dwWaitHint); 
 } 

 CloseServiceHandle(schService); 
 CloseServiceHandle(schSCManager);
}

Related topics

Service Startup

The Complete Service Sample


Feedback

Was this page helpful?

Additional resources