2012-01-23 40 views
0

對不起,關於樣品的長度,但爲了獲得所有必需的服務組件,它必須這麼長。如何正確使用SetServiceStatus來告訴Windows我的服務正在停止?

在這裏使用他人的幫助,我設法得到一個乾淨地開始的服務,但現在它不會停止乾淨。

在第一次嘗試,很快停住它給出了錯誤

Could not stop the My service service on local computer 
The service did not return an error. This could be an internal Windows error or an internal service error 
If the problem persists, contact your system administrator 

和服務繼續運行,即使是睡眠循環取5分鐘後。

在第二次企圖阻止,任務管理器顯示進程立即停止,但服務管理需要很長的時間給錯誤

Could not stop the My service service on local computer 
Error 1053: The service did not respond to the start or control request in a timely fashion. 

這裏是源代碼

#include <stdio.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <string.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <windows.h> 
#include <winsvc.h> 
#include <time.h> 

#define MY_SVC_NAME "My service" 
#define THE_PROG "\"C:\\Program Files\\My software\\bin\\The Prog.exe\"" 
#define SLEEP_TIME 300000 

SERVICE_STATUS ServiceStatus; 
SERVICE_STATUS_HANDLE hStatus; 

void WINAPI ServiceMain(DWORD argc, LPSTR argv); 
void WINAPI ControlHandler(DWORD request); 
void InitService(); 


int cont_running = 1; 

DWORD WINAPI ServiceHandlerProc(DWORD ControlCode, DWORD a, void *b, void *c) 
{ 
    switch (ControlCode) { 
    case SERVICE_CONTROL_STOP : 
    cont_running = 0; 
    ServiceStatus.dwCheckPoint=0; 
    ServiceStatus.dwWin32ExitCode = 0; 
    ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING; 
    ServiceStatus.dwWaitHint =2000; 
    SetServiceStatus (hStatus, &ServiceStatus); 
    Sleep(1000); 
    ServiceStatus.dwCurrentState = SERVICE_STOPPED; 
    SetServiceStatus (hStatus, &ServiceStatus); 
    break; 
    case SERVICE_CONTROL_SHUTDOWN : 
    cont_running = 0; 
    ServiceStatus.dwCheckPoint=0; 
    ServiceStatus.dwWin32ExitCode = 0; 
    ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING; 
    ServiceStatus.dwWaitHint =2000; 
    SetServiceStatus (hStatus, &ServiceStatus); 
    Sleep(1000); 
    ServiceStatus.dwCurrentState = SERVICE_STOPPED; 
    SetServiceStatus (hStatus, &ServiceStatus); 
    break; 
    } 

    return 0; 

} 

void WINAPI ServiceMain(DWORD argc, LPSTR argv) 
{ 
    int hServiceStatus; 

    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   = 0; 

    hServiceStatus = RegisterServiceCtrlHandlerEx(MY_SVC_NAME, ServiceHandlerProc,0); 
    /* 
    if (hStatus == (SERVICE_STATUS_HANDLE)0) { 
    return; 
    } 
    */ 

    Sleep(1000); 

    ServiceStatus.dwCheckPoint=0; 
    ServiceStatus.dwWaitHint=0; 
    ServiceStatus.dwCurrentState=SERVICE_RUNNING; 
    SetServiceStatus(hServiceStatus, &ServiceStatus); 

    InitService(); 

    return; 
} 

void InitService() 
{ 
    cont_running=1; 
    do { 
    system(THE_PROG); 
    Sleep(SLEEP_TIME); 
    } while (cont_running); 
} 

int main(int argc, char *argv[], char *envp[]) 
{ 
    SERVICE_TABLE_ENTRY ServiceStartTable[2]; 
    ServiceStartTable[0].lpServiceName = MY_SVC_NAME; 
    ServiceStartTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain; 
    ServiceStartTable[1].lpServiceName = NULL; 
    ServiceStartTable[1].lpServiceProc = NULL; 


    if (!StartServiceCtrlDispatcher(ServiceStartTable)) 
    { 
    DWORD err = GetLastError(); 
    if (err == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT) 
     return 1; 
    } 

    return 0; 
} 

我已經提到下列文件沒有成功 http://msdn.microsoft.com/en-us/library/ms809975.aspx LUA服務參考手冊

+0

檢查'SetServiceStatus()'的返回值,並檢查'GetLastError()'是否失敗。我還認爲你需要將'cont_running'聲明爲'volatile',否則對'cont_running'所做的任何更改都不會對'InitService()'可見。 – hmjd

+0

我想我將不得不經歷創建日誌文件的麻煩,只是爲了調試printf,因爲服務上沒有標準輸出。除非有另一種方式? – banjo67xxx

+0

您可以寫入事件查看器,但不會比日誌文件困難。 – hmjd

回答

2

這個問題似乎與你的SERVICE_STATUS_HANDLE hStatus全局變量有關:它在程序中的任何地方都沒有分配,但它被使用了很多次。

此外,局部變量int hServiceStatus根本沒有意義。

解決方案:刪除hServiceStatus局部變量,並將hServiceStatus的每個用法替換爲正確的hStatus變量。

提示:也許您已經意識到這一點,但您應該在您收到控制命令時設置STOP_PENDING狀態,並且只有在確實停止了工作線程時才設置STOPPED。

+0

這就是複製和粘貼其他人的代碼時沒有完全理解它是如何工作的問題。我現在終於明白了。謝謝。 – banjo67xxx

+0

並忽略編譯器警告:''int'與'SERVICE_STATUS_HANDLE''的間接級別不同:-P – rodrigo

相關問題