Reputation: 367
Windows isn't ALWAYS starting my service on a cold boot, most of the time it does, but every now and again it fails to start with a 'Timeout was reached' error in the system log.
I added a line to dump the time at the very start of the service to see what is going on.
After about 15 shutdowns and restarts, my service finally didn't start.
Looking in the application event log, I see the Windows License Validated event at 8:18:29 and WMI started at 8:19:04 but when I look at my log file I see '08:15:21: _tmain'
Which means my service didn't even get loaded on this reboot, or at least the 'main' didn't get called.
Looking at the system event log: I see at 8:18:57 an Event 7009: A timeout was reached (30000 milliseconds) while waiting for the XXXX service to connect.
In the registry at 'HKLM\System\CurrentControlSet\Control' I have the value 'ServicesPipeTimeout' set to 90000
My service executable is C++ with /clr support based on .Net 2.0 the executable also is NOT signed and I've added
<generatePublisherEvidence enabled="false"/>
to the .config file, just to be sure.
The service is dependent on the Event Log, which is obviously working.
This is Windows 7 x64 VM with 4GB of memory and little else but does seem to thrash on start up and have trouble getting a network connection.
If I start the service manually, it starts within 5 seconds.
I don't want to make the service 'Automatic (Delayed Start) since that happens 2 minutes after Windows has started.
I have no idea what to try next or even where to look.
Any guidance would be much appreciated.
thank you.
[EDIT] Here's the entry of my code. Note that I'm writing to the log BEFORE I do anything with the service, which is all inside the MyService class.
int _tmain(int /*argc*/, TCHAR* /*argv*/[], TCHAR* /*envp*/[])
{
SaveStringToFile(L"C:\\start.txt", CTime::GetCurrentTime().Format("%H:%M:%S") + L": _tmain\n");
SetUnhandledExceptionFilter( MyCustomFilter );
OutputDebugString(_T(__FUNCTION__));
CMyService Service;
Upvotes: 1
Views: 674
Reputation: 23236
There could be a race condition during start up. If the Event Log has not started working before the system attempts to start your service, and there is a dependency on that log, this may cause your service to fail.
Perhaps you can Change the order in which your service application is started with respect to the Log.
EDIT to add information from comments
In my experience, there is a real danger failing to launch a service executable if too much is done during initialization. I put only the essentials in. In this case, write to a log: (also included snippets of main and ServiceMain() to illustrate the exception logging I referred to earlier...)
////////////////////////////////////////////////////////
//
// InitService(void) - Service initialization
//
// Caution - limit what is done from this function.
// The service start function: SVC_ServiceStart()
// is limited in how much time can be allocated
// to start this executable before it times out.
//
////////////////////////////////////////////////////////
int InitService(void)
{
char buf[200];
sprintf(buf, "Monitoring started");
if(LOG_STRTSTOP==1)WriteToLog(buf);
return SVC_SUCCESS;
}
Where my main() and ServiceMain() look like this:
void main()
{
SERVICE_TABLE_ENTRY ServiceTable[2];
ServiceTable[0].lpServiceName = "xyzMon";
ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
ServiceTable[1].lpServiceName = NULL;
ServiceTable[1].lpServiceProc = NULL;
// Start the control dispatcher thread for our service
StartServiceCtrlDispatcher(ServiceTable);
LogProgramFlow("Leaving main()");
}
void ServiceMain(int argc, char** argv)
{
int error, result;
pS = &s;
ServiceStatus.dwServiceType = SERVICE_WIN32;
ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwServiceSpecificExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 3000;
hStatus = RegisterServiceCtrlHandler( "xyzMon", (LPHANDLER_FUNCTION)ControlHandler);
if (hStatus == (SERVICE_STATUS_HANDLE)0)
{
// Registering Control Handler failed
if(LOG_ERR==1) WriteToLog("Registering Control Handler failed");
return;
}
// Initialize Service
error = InitService();
....
Upvotes: 1