I made a windows service, and I install it with:
SC_HANDLE service = CreateServiceA
(
scm,
"turboledz",
"TurboLEDz",
SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS,
SERVICE_AUTO_START,
SERVICE_ERROR_NORMAL,
servicepath,
NULL,
NULL,
NULL,
NULL,
NULL
);
This succeeds.
I can then query its state, using QueryServiceStatus(service, &servstat);
which predicably returns SERVICE_STOPPED.
So far, so good.
When I subsequently start the service, either programmatically using:
const int started = StartServiceA
(
service,
0, // num service arguments.
NULL
);
if (started)
{
LOGI("turboledz service has been started.");
}
else
{
const DWORD err = GetLastError();
LOGI("Failed to start service. Error: 0x%lx", err);
return 5;
}
...or by using the sc
command line tool:
sc start turboledz
Then I am immediately, (in a fraction of a second) prompted with the error:
[SC] StartService FAILED 1053:
The service did not respond to the start or control request in a timely fashion.
Which corresponds to ERROR_SERVICE_REQUEST_TIMEOUT.
Furthermore, since the first thing my service does is create a log file, and this log file is not present, I must conclude that SCM did not even try to launch my service.
The service has a properly set binpath, by the way, so that is not the issue.
This raises so many questions:
- How can a TIMEOUT fail in a split second?
- How come SCM does not launch the service process?
Note: I have Administrator Privileges when I create and start the service.
Note: It is not an issue of missing service executable, because if I delete that, the sc error changes into ERROR_SERVICE_DOES_NOT_EXIST
UPDATE
The event viewer shows the SCM logs, which contains a flat out lie: 30,000 miliseconds never passed between the start of the service and the timeout error.
The creation, the launch, the time-out, all occurred at 12:52:43.
UPDATE 2
The main() code:
...
SERVICE_TABLE_ENTRY servtabl[] =
{
{L"turboledz", (LPSERVICE_MAIN_FUNCTION)ServiceMain},
{NULL, NULL}
};
const int startres = StartServiceCtrlDispatcher( servtabl );
if (!startres)
{
const DWORD err = GetLastError();
if (err == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT)
LOGI("The program is being run as a console application rather than as a service.");
LOGI("StartServiceCtrlDispatcher() failed with: 0x%lx", err);
return 1;
}
...
And ServiceMain:
VOID WINAPI ServiceMain(DWORD argc, LPTSTR* argv)
{
sshandle = RegisterServiceCtrlHandlerExA
(
"turboledz",
ServiceCtrlHandler,
(LPVOID)0
);
if (sshandle == NULL)
{
const DWORD err = GetLastError();
LOGI("RegisterServiceCtrlHandlerExA() failed with error 0x%lx", err);
return;
}
else
{
LOGI("Service Control Handler for TurboLEDz has been registered.");
}
...
But according to my logging, neither of these is ever reached. The service process is simply never started.
CodePudding user response:
So, I found the root-cause: the service process never launched because a DLL dependency was not found. (My MSI installer package had not packed up a DLL that my service process depends on.)
Still, in my opinion, this is a bug in MS Windows 10. The OS claims there was a 30,000 ms time-out. There was no time-out.
The StartService()
call should have returned a different error, to indicate that the service process failed to launch.
Maybe ERROR_APP_INIT_FAILURE would be a good error code for this.
As it it now, a failed launch is not properly communicated to the caller, nor to the event log.
I'll see if I can log a bug with Microsoft for this.