首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >StartServiceCtrlDispatcher不能访问1063错误

StartServiceCtrlDispatcher不能访问1063错误
EN

Stack Overflow用户
提问于 2014-11-04 10:26:54
回答 2查看 10.4K关注 0票数 1

我是在c++服务上写的,但是有错误,不能修复它。

我的服务主要功能

代码语言:javascript
运行
复制
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;
}

在StartServiceCtrlDispatcher上使用命令行参数(StartServiceCtrlDispatcher和action)调试程序,每次返回1063错误。Visual我在Administrator下运行。在我写错代码的地方,请帮忙。

更新

代码语言:javascript
运行
复制
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;
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-11-05 02:04:25

只有当您的进程由服务控制管理器启动时,即当它作为服务实际运行时,才能调用StartServiceCtrlDispatcher。当从任何其他上下文调用时,您将得到ERROR_FAILED_SERVICE_CONTROLLER_CONNECT (1063)。

从代码的外观来看,只有在没有传递命令行参数的情况下,才应该调用StartServiceControlDispatcher,例如

代码语言:javascript
运行
复制
if (argc < 2)
{
  if (!StartServiceCtrlDispatcher(ServiceTable)) 
  {
    f = GetLastError();
  }
} 
else if (strcmp(argv[1], "install")
{
  InstallService();
}

诸若此类。

main()函数还有其他一些问题,最值得注意的是:

  • 错误的签名;argv[]是char,而不是TCHAR
  • 将argv铸造到TCHAR
  • 一个无缘无故地调用GetLastError的循环,114次
  • 使用memcmp代替strcmp

我没有看ServiceMain()。

票数 4
EN

Stack Overflow用户

发布于 2017-02-22 23:02:36

当服务安装在64位的windows 8或更高版本上,并调用将调用主入口点的方法StartServiceCtrlDispatcher时,就会发生这种情况。但是StartServiceCtrlDispatcher方法适用于指针为8位的指针。

因此,解决方案是使用函数StartServiceCtrlDispatcherW,它可以处理16位指针,例如:

以前:它使用指向SERVICE_TABLE_ENTRYStartServiceCtrlDispatcher的数据类型LPTSTR (8位)的指针。

代码语言:javascript
运行
复制
SERVICE_TABLE_ENTRY DispatchTable[] = {
            { (LPTSTR)srvName.str().c_str(), (LPSERVICE_MAIN_FUNCTION)ServiceMain },
            { NULL,NULL }
        };
StartServiceCtrlDispatcher(DispatchTable);

之后:它使用指向SERVICE_TABLE_ENTRYWStartServiceCtrlDispatcherWLPWSTR (16位)的指针,这是数据的类型。

代码语言:javascript
运行
复制
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。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26732815

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档