Hello Gary
"Gary Chang[MSFT]" said:
Hi Peter,
In the OnStart() method I detect a service failure, but the
SCM reports that the service started successfully. How
can I tell the SCM that the service failed?
I am afraid I am not very clear about the detailed scenario, do you mean
you detected the current service started failed on its OnStrat() method, or
detected some other service failed, and how do you detect it failed when
SCM reports it started successfully?
I detect the failure in the worker thread within the service during or after
OnStart() finishes in another thread.
The reason you cannot stopped a service may be some other running services
have dependency on it or you don't have enough permission to stop it. Have
you checked the return value of the SetServiceStatus call, is there any
useful info?
Thanks, that was the problem: I didn't initialize all members of the
SERVICE_STATUS struct. I looked at the example code from
http://msdn2.microsoft.com/en-us/library/system.serviceprocess.servicebase.aspx
.. SetServiceStatus is not called from C++, so I used the C# example, where
only the dwCurrentState member is ever assigned. Perhaps in C# all struct
members are implicitly initialized by the compiler?
Anyway, here is what I did to initialize (parent_ is derived from
ServiceBase; I hope this wraps ok):
SERVICE_STATUS st;
st.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
st.dwControlsAccepted = 0
| (parent_->CanStop ? SERVICE_ACCEPT_STOP : 0)
| (parent_->CanShutdown ? SERVICE_ACCEPT_SHUTDOWN : 0)
| (parent_->CanPauseAndContinue ? SERVICE_ACCEPT_PAUSE_CONTINUE
: 0)
| (parent_->CanHandleSessionChangeEvent ? SERVICE_ACCEPT_SESSIONCHANGE :
0)
| (parent_->CanHandlePowerEvent ? SERVICE_ACCEPT_POWEREVENT : 0)
;
st.dwCheckPoint = 0;
// now fill in our specific data
st.dwCurrentState = status;
st.dwWaitHint = waitHint;
st.dwWin32ExitCode = failed_ ? ERROR_SERVICE_SPECIFIC_ERROR : NO_ERROR;
st.dwServiceSpecificExitCode = failed_ ? 42 : 0; // random error number...
SetServiceStatus(hdl, &st);
Regards, Peter