我制作了一個 Windows 服務,并使用以下命令安裝它:
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
);
這成功了。
然后我可以查詢它的狀態,使用QueryServiceStatus(service, &servstat);它可預測地回傳 SERVICE_STOPPED。
到現在為止還挺好。
當我隨后啟動服務時,要么以編程方式使用:
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;
}
...或使用sc命令列工具:
sc start turboledz
然后我立即(在幾分之一秒內)提示錯誤:
[SC] StartService FAILED 1053:
The service did not respond to the start or control request in a timely fashion.
這對應于ERROR_SERVICE_REQUEST_TIMEOUT。
此外,由于我的服務做的第一件事是創建一個日志檔案,而這個日志檔案不存在,我必須得出結論,SCM甚至沒有嘗試啟動我的服務。
順便說一下,該服務有一個正確設定的 binpath,所以這不是問題。
這引發了很多問題:
- 超時如何在一瞬間失敗?
- 為什么 SCM 不啟動服務行程?
注意:我在創建和啟動服務時擁有管理員權限。
注意:這不是缺少服務可執行檔案的問題,因為如果我洗掉它,sc 錯誤將更改為ERROR_SERVICE_DOES_NOT_EXIST
更新
事件查看器顯示 SCM 日志,其中包含一個完全的謊言:在服務啟動和超時錯誤之間從未經過 30,000 毫秒。
創建、啟動、超時,都發生在12:52:43。

更新 2
main() 代碼:
...
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;
}
...
和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.");
}
...
但根據我的記錄,這兩個都沒有達到。服務行程根本就沒有啟動。
uj5u.com熱心網友回復:
所以,我找到了根本原因:服務行程從未啟動,因為未找到 DLL 依賴項。(我的 MSI 安裝程式包沒有打包我的服務行程所依賴的 DLL。)
盡管如此,在我看來,這是 MS Windows 10 中的一個錯誤。作業系統聲稱有 30,000 毫秒的超時。沒有超時。
該StartService()呼叫應該回傳一個不同的錯誤,以指示服務行程未能啟動。
也許ERROR_APP_INIT_FAILURE會是一個很好的錯誤代碼。
就像現在一樣,失敗的啟動沒有正確地傳達給呼叫者,也沒有傳達給事件日志。
我會看看我是否可以為此向 Microsoft 記錄一個錯誤。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/395866.html
