I am writing a service. Before exiting the ServiceMain(), I want to call
SetServiceStatus(hServiceHandle, SERVICE_STOPPED) to set the service status
to SERVICE_STOPPED, but the SetServiceStatus() function crash immediately.
For example:
ServiceMain(...)
{
SERVICE_STATUS MyServiceStatus;
SERVICE_STATUS_HANDLE MyServiceStatusHandle;
...
MyServiceStatus.dwCurrentState = SERVICE_STOPPED;
MyServiceStatus. ... (other values)
SetServiceStatus(MyServiceStatusHandle, &MyServiceStatus); // this line
crash
MyLog("ServiceMain Existed"); // this line never reach.
}
Any idea? or I don't need to call SetServiceStatus(hServiceHandle,
SERVICE_STOPPED) to set the service status to SERVICE_STOPPED in the
ServiceMina()?
Thanks in advance,
lauch2.
Egbert Nierop (MVP for IIS) - 28 Sep 2005 09:18 GMT
>I am writing a service. Before exiting the ServiceMain(), I want to call
> SetServiceStatus(hServiceHandle, SERVICE_STOPPED) to set the service
[quoted text clipped - 15 lines]
> MyLog("ServiceMain Existed"); // this line never reach.
> }
This might help.
//
// FUNCTION: ReportStatusToSCMgr()
//
// PURPOSE: Sets the current status of the service and
// reports it to the Service Control Manager
//
// PARAMETERS:
// dwCurrentState - the state of the service
// dwWin32ExitCode - error code to report
// dwWaitHint - worst case estimate to next checkpoint
//
// RETURN VALUE:
// TRUE - success
// FALSE - failure
//
// COMMENTS:
//
BOOL ReportStatusToSCMgr(DWORD dwCurrentState,
DWORD dwWin32ExitCode,
DWORD dwWaitHint)
{
static DWORD dwCheckPoint = 1;
BOOL fResult = TRUE;
if ( !bDebug ) // when debugging we don't report to the SCM
{
if (dwCurrentState == SERVICE_START_PENDING)
ssStatus.dwControlsAccepted = 0;
else
ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
ssStatus.dwCurrentState = dwCurrentState;
ssStatus.dwWin32ExitCode = dwWin32ExitCode;
ssStatus.dwWaitHint = dwWaitHint;
if ( ( dwCurrentState == SERVICE_RUNNING ) ||
( dwCurrentState == SERVICE_STOPPED ) )
ssStatus.dwCheckPoint = 0;
else
ssStatus.dwCheckPoint = dwCheckPoint++;
// Report the status of the service to the service control manager.
//
if (!(fResult = SetServiceStatus( sshStatusHandle, &ssStatus)))
{
AddToMessageLog(L"SetServiceStatus");
}
}
return fResult;
}
void WINAPI service_main(DWORD dwArgc, PWSTR *lpszArgv)
{
// register our service control handler:
//
sshStatusHandle = RegisterServiceCtrlHandler( SZSERVICENAME,
service_ctrl);
if (sshStatusHandle != NULL)
{
// SERVICE_STATUS members that don't change in example
//
ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
ssStatus.dwServiceSpecificExitCode = 0;
// report the status to the service control manager.
//
if (ReportStatusToSCMgr(
SERVICE_START_PENDING, // service state
NO_ERROR, // exit code
3000)) // wait hint
ServiceStart( dwArgc, lpszArgv );
// try to report the stopped status to the service control manager.
//
ReportStatusToSCMgr(SERVICE_STOPPED, dwErr,0);
}
return;
}