2012-08-15 310 views
3

我試圖控制應用程序內的服務。通過StartService啓動服務(MSDN)工作正常,該服務需要大約10秒才能啓動,但在調用StartService之後,它立即將控制權返回給主應用程序。異步停止Windows服務

但是,當通過ControlService停止服務時(MSDN) - AFAIK沒有停止服務 - 它會阻塞主應用程序一段時間,直到服務停止,這大約需要10秒。

Start: StartServiceW(handle, 0, NULL) 
Stop: ControlService(handle, SERVICE_CONTROL_STOP, status) 

有沒有一種非阻塞/異步停止Windows服務的方法?

+2

你是否嘗試從線程調用它?將阻塞呼叫轉變爲非阻塞呼叫的經典方法... – 2012-08-15 16:35:21

+0

我不知道如何,但'sc'命令允許您停止服務而不會阻塞它。嘗試尋找有趣的API函數。 – wilx 2012-08-15 16:38:29

+0

有沒有一種特定的服務是以這種方式表現的,還是所有這些服務?我的猜測是有問題的服務沒有正確響應STOP請求。 – 2012-08-15 22:37:13

回答

1

我可能會考慮在新線程中停止服務。這將消除您的主線程阻塞。

1

SCM以序列化的方式處理控制請求。如果任何服務忙於處理控制請求,則ControlService()將被阻止,直到SCM可以處理新的請求。這在the documentation表述爲多:

單片機在處理業務控制的通知串行方式,它 將等待一個服務發送下一個之前完成處理業務控制 通知。因此,如果有任何服務忙於處理控制代碼,012xx將致電 ControlService將阻塞30秒。如果超時過期時,忙服務仍未從其處理函數返回 ,則ControlService 將失敗,並返回ERROR_SERVICE_REQUEST_TIMEOUT。

+0

謝謝,我已經讀過。除我以外沒有其他控制要求,所以我認爲這不適用於此,或者? – OnTheFly 2012-08-15 20:47:12

+0

「如果** ANY **服務忙於處理控制代碼,則對ControlService的調用將阻塞30秒」,而不僅僅是您的服務。 – 2012-08-16 18:46:45

1

該服務正在清理其控制處理程序例程。對於只需要幾分之一秒退出的服務而言,這是可以的,但是需要十秒鐘的服務應該確定將狀態設置爲STOP_PENDING,然後異步清理。

如果這是您自己的服務,您應該糾正該問題。我首先確保所有的清理工作都是非常必要的,例如,在停止之前不需要釋放內存(除非服務與其他服務共享進程)。如果清理速度確實不夠快,請啓動一個單獨的線程(或通知主線程)以執行服務關閉並將服務狀態設置爲STOP_PENDING。

如果這是他人的服務,唯一的解決方案是從單獨的線程或子進程發出停止請求。

+0

謝謝。我已經設置了SERVICE_STOP_PENDING,但是ControlService阻塞了,直到SERVICE_STOPPED。太糟糕了...... – OnTheFly 2012-08-17 08:53:39

+0

將狀態設置爲SERVICE_STOP_PENDING後服務控制例程是否退出?你能顯示代碼嗎? – 2012-08-18 03:26:07