2014-11-04 223 views
1

我在C++服務上編寫,但有錯誤,不能修復它。StartServiceCtrlDispatcher不能訪問1063錯誤

我的服務功能主要

int main (int argc, TCHAR *argv[]) 
{DWORD f; 
    for(int i=0;i<113;i++) 
     f = GetLastError(); 
    servicePath = LPTSTR(argv[0]); 
    OutputDebugString(_T("My Sample Service: Main: Entry")); 
    //InstallService(); 
    SERVICE_TABLE_ENTRY ServiceTable[] = 
    { 
     {SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION) ServiceMain}, 
     {NULL, NULL} 
    }; 
// StartService(); 
    if(!StartServiceCtrlDispatcher(ServiceTable)) { 
     f = GetLastError(); 
     //addLogMessage("Error: StartServiceCtrlDispatcher"); 

    } else if(memcmp(argv[argc-1],"install",7)) { 
    InstallService(); 
    } else if(memcmp(argv[argc-1],"remove",6)) { 
    RemoveService(); 
    } else if(memcmp(argv[argc-1],"start",5)) { 
    StartService(); 
    } else if(memcmp(argv[argc-1],"stop",4)) { 
    // StopService(); 
    } 
// StopService(); 
    OutputDebugString(_TEXT("My Sample Service: Main: Exit")); 
    return 0; 
} 

當調試我PROGRAMM與StartServiceCtrlDispatcher命令行參數(service_path和行動)每次返回1063錯誤。 Visual Studio我在Administrator下運行。我寫錯碼的地方,請幫忙。

UPDATE

VOID WINAPI ServiceMain (DWORD argc, LPTSTR *argv) 
{ 
    DWORD Status = E_FAIL; 

    OutputDebugString(_T("My Sample Service: ServiceMain: Entry")); 

    g_StatusHandle = RegisterServiceCtrlHandler (SERVICE_NAME, ServiceCtrlHandler); 

    if (g_StatusHandle == NULL) 
    { 
     OutputDebugString(_T("My Sample Service: ServiceMain: RegisterServiceCtrlHandler returned error")); 
     goto EXIT; 
    } 

    // Tell the service controller we are starting 
    ZeroMemory (&g_ServiceStatus, sizeof (g_ServiceStatus)); 
    g_ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; 
    g_ServiceStatus.dwControlsAccepted = 0; 
    g_ServiceStatus.dwCurrentState = SERVICE_START_PENDING; 
    g_ServiceStatus.dwWin32ExitCode = 0; 
    g_ServiceStatus.dwServiceSpecificExitCode = 0; 
    g_ServiceStatus.dwCheckPoint = 0; 

    if (SetServiceStatus (g_StatusHandle, &g_ServiceStatus) == FALSE) 
    { 
     OutputDebugString(_T("My Sample Service: ServiceMain: SetServiceStatus returned error")); 
    } 

    /* 
    * Perform tasks neccesary to start the service here 
    */ 
    OutputDebugString(_T("My Sample Service: ServiceMain: Performing Service Start Operations")); 

    // Create stop event to wait on later. 
    g_ServiceStopEvent = CreateEvent (NULL, TRUE, FALSE, NULL); 
    if (g_ServiceStopEvent == NULL) 
    { 
     OutputDebugString(_T("My Sample Service: ServiceMain: CreateEvent(g_ServiceStopEvent) returned error")); 

     g_ServiceStatus.dwControlsAccepted = 0; 
     g_ServiceStatus.dwCurrentState = SERVICE_STOPPED; 
     g_ServiceStatus.dwWin32ExitCode = GetLastError(); 
     g_ServiceStatus.dwCheckPoint = 1; 

     if (SetServiceStatus (g_StatusHandle, &g_ServiceStatus) == FALSE) 
     { 
      OutputDebugString(_T("My Sample Service: ServiceMain: SetServiceStatus returned error")); 
     } 
     goto EXIT; 
    }  

    // Tell the service controller we are started 
    g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP; 
    g_ServiceStatus.dwCurrentState = SERVICE_RUNNING; 
    g_ServiceStatus.dwWin32ExitCode = 0; 
    g_ServiceStatus.dwCheckPoint = 0; 

    if (SetServiceStatus (g_StatusHandle, &g_ServiceStatus) == FALSE) 
    { 
     OutputDebugString(_T("My Sample Service: ServiceMain: SetServiceStatus returned error")); 
    } 

    // Start the thread that will perform the main task of the service 
    HANDLE hThread = CreateThread (NULL, 0, ServiceWorkerThread, NULL, 0, NULL); 

    OutputDebugString(_T("My Sample Service: ServiceMain: Waiting for Worker Thread to complete")); 

    // Wait until our worker thread exits effectively signaling that the service needs to stop 
    WaitForSingleObject (hThread, INFINITE); 

    OutputDebugString(_T("My Sample Service: ServiceMain: Worker Thread Stop Event signaled")); 


    /* 
    * Perform any cleanup tasks 
    */ 
    OutputDebugString(_T("My Sample Service: ServiceMain: Performing Cleanup Operations")); 

    CloseHandle (g_ServiceStopEvent); 

    g_ServiceStatus.dwControlsAccepted = 0; 
    g_ServiceStatus.dwCurrentState = SERVICE_STOPPED; 
    g_ServiceStatus.dwWin32ExitCode = 0; 
    g_ServiceStatus.dwCheckPoint = 3; 

    if (SetServiceStatus (g_StatusHandle, &g_ServiceStatus) == FALSE) 
    { 
     OutputDebugString(_T("My Sample Service: ServiceMain: SetServiceStatus returned error")); 
    } 

    EXIT: 
    OutputDebugString(_T("My Sample Service: ServiceMain: Exit")); 

    return; 
} 

VOID WINAPI ServiceCtrlHandler (DWORD CtrlCode) 
{ 
    OutputDebugString(_T("My Sample Service: ServiceCtrlHandler: Entry")); 

    switch (CtrlCode) 
    { 
    case SERVICE_CONTROL_STOP : 

     OutputDebugString(_T("My Sample Service: ServiceCtrlHandler: SERVICE_CONTROL_STOP Request")); 

     if (g_ServiceStatus.dwCurrentState != SERVICE_RUNNING) 
      break; 

     /* 
     * Perform tasks neccesary to stop the service here 
     */ 

     g_ServiceStatus.dwControlsAccepted = 0; 
     g_ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING; 
     g_ServiceStatus.dwWin32ExitCode = 0; 
     g_ServiceStatus.dwCheckPoint = 4; 

     if (SetServiceStatus (g_StatusHandle, &g_ServiceStatus) == FALSE) 
     { 
      OutputDebugString(_T("My Sample Service: ServiceCtrlHandler: SetServiceStatus returned error")); 
     } 

     // This will signal the worker thread to start shutting down 
     SetEvent (g_ServiceStopEvent); 

     break; 

    default: 
     break; 
    } 

    OutputDebugString(_T("My Sample Service: ServiceCtrlHandler: Exit")); 
} 

DWORD WINAPI ServiceWorkerThread (LPVOID lpParam) 
{ 
    OutputDebugString(_T("My Sample Service: ServiceWorkerThread: Entry")); 

    main2(); 

    OutputDebugString(_T("My Sample Service: ServiceWorkerThread: Exit")); 

    return ERROR_SUCCESS; 
} 
+0

由於我們無法看到'ServiceMain',所以我們不知道什麼是錯的。除了由於訪問未分配的內存('memcmp(argv [argc-1],「install」,7)')而導致明顯的未定義行爲外。 – IInspectable 2014-11-04 10:54:56

+0

更新添加ServiceMain函數 – 2014-11-04 11:00:51

回答

3

只能調用StartServiceCtrlDispatcher當你的過程是由服務控制管理器,即,當它實際上是作爲服務運行啓動。當從其他任何環境調用時,您將獲得ERROR_FAILED_SERVICE_CONTROLLER_CONNECT(1063)。

從代碼的外觀上來看,你應該只調用StartServiceControlDispatcher如果沒有命令行參數傳遞,例如,像

if (argc < 2) 
{ 
    if (!StartServiceCtrlDispatcher(ServiceTable)) 
    { 
    f = GetLastError(); 
    } 
} 
else if (strcmp(argv[1], "install") 
{ 
    InstallService(); 
} 

等。


也有一些其他的問題,你的main()函數,最值得注意的是:

  • 錯誤的簽名;的argv []是炭,不TCHAR

  • 鑄造的argv [0]至TCHAR

  • 環路它調用GetLastError函數沒有理由,114倍

  • 使用memcmp代替的strcmp

我沒有看ServiceMain()。

3

當服務安裝在Windows 8或更高版本的64位並調用方法StartServiceCtrlDispatcher時會發生這種情況,它將調用Main入口點。但方法StartServiceCtrlDispatcher使用8位指針。

因此,解決方案是使用函數StartServiceCtrlDispatcherW其具有16個比特指針的工作原理,例如:

之前:它使用指針LPTSTR(8個比特),即類型

SERVICE_TABLE_ENTRY DispatchTable[] = { 
      { (LPTSTR)srvName.str().c_str(), (LPSERVICE_MAIN_FUNCTION)ServiceMain }, 
      { NULL,NULL } 
     }; 
StartServiceCtrlDispatcher(DispatchTable); 

之後:需要SERVICE_TABLE_ENTRYStartServiceCtrlDispatcher數據,它採用指針LPWSTR(16位),也就是數據的需要SERVICE_TABLE_ENTRYWStartServiceCtrlDispatcherW類型:

SERVICE_TABLE_ENTRYW DispatchTable[] = { 
      { (LPWSTR)srvName.str().c_str(), (LPSERVICE_MAIN_FUNCTION)ServiceMain }, 
      { NULL,NULL } 
     }; 
StartServiceCtrlDispatcherW(DispatchTable); 

結論:

使用寬字符串(每個字符16位)和功能StartServiceCtrlDispatcherW和SERVICE_TABLE_ENTRYW類型,而不是StartServiceCtrlDispatcher和SERVICE_TABLE_ENTRY。

+0

此外,我注意到有壞的檢查,如果它使用wstring和wchar,如下所示: wstring wAux = srvName.str(); \t \t \t LPWSTR wSrv =(LPWSTR)wAux.c_str(); \t \t \t SERVICE_TABLE_ENTRYW DispatchTable [] = { \t \t \t \t {wSrv,(LPSERVICE_MAIN_FUNCTION)的ServiceMain}, \t \t \t \t {NULL,NULL} \t \t \t}; \t \t \t StartServiceCtrlDispatcherW(DispatchTable); – 2017-02-23 02:01:41

+1

'StartServiceCtrlDispatcher'是一個根據構建設置展開爲'StartServiceCtrlDispatcherA'或'StartServiceCtrlDispatcherW'的宏。除非服務名稱包含非ASCII字符,否則使用哪一個並不重要,當然,您必須提供一個正確類型的字符串。無論如何,Visual Studio默認爲寬字符,在這種情況下,您的兩個代碼片段是相同的。 – 2017-08-09 21:22:07

+0

它不完全相同,在StartServiceCtrlDispatcherW使用指向寬字符串LPWSTR的指針的同時'StartServiceCtrlDispatcherA'使用'LPSTR'。這就是存在內存異常的原因。 https://source.winehq.org/source/include/winsvc.h#0214 – 2017-08-09 23:24:08