我的OS是XP,我试着写了一个后台服务程序,main()为 void main() 

InstallService(); SERVICE_TABLE_ENTRY ServiceTable[2]; ServiceTable[0].lpServiceName = "MLOG"; 
ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain; ServiceTable[1].lpServiceName = NULL; 
ServiceTable[1].lpServiceProc = NULL; StartServiceCtrlDispatcher(ServiceTable); } 
整个程序可以安装成功,但启动服务时老是失败,ServiceMain()好像不执行,为什么?

解决方案 »

  1.   

    服务要先安装再启动,不能在一个进程中安装自己然后执行StartServiceCtrlDispatcher。
      

  2.   

    那应该怎么解决这个题?是在安装完成之后再创建一个新进程,由新进程去执行StartServiceCtrlDispatcher呢还是怎么办?
      

  3.   

    我InstallService()这个函数的最后有这两句:
    CloseServiceHandle(schService);
    CloseServiceHandle(schSCManager);
    这两句对程序流程应该没有影响吧?
      

  4.   

    至少要有两个进程,这两个进程可以是同一个exe文件。一个是以应用程序方式启动,启动后执行安装服务(CreateService,安装一次即可)和启动服务(StartService,如果需要);另一个是服务进程,是由服务管理器启动的,如果服务设置为自动启动,则每次系统启动后服务管理器会自动启动它,也可以由另一应用程序通过StartService让服务管理器启动服务。在服务进程中执行StartServiceCtrlDispatcher。
      

  5.   

    如果我使用同一个EXE文件,先安装,安装完成之后再通过createprocess()创建另外一个进程来执行StartServiceCtrlDispatcher,这个createprocess()该怎么写?
      

  6.   

    看来你还是没明白我4楼的回复。服务进程应该是SCManager创建的,创建方式有两种:一种是服务设置为自动启动类型,在每次系统启动后,SCManager会自动启动这种类型的服务;另一种是手动启动,由另外一个应用程序打开服务,执行StartService,这是同样是SCManager来创建服务进程。CreateService时要指定服务的程序文件路径和启动类型等信息,这些信息会记录到注册表中。SCManager根据这些信息来创建服务进程。如果你是在做一个工具程序,想要在执行过程中创建并加载服务,大致做法是:
    做两个程序,一个应用程序和一个服务程序。
    应用程序先执行CreateService,再执行StartService,然后服务程序就已经启动了。
    服务程序中先执行StartServiceCtrlDispatcher,然后退出。SCManager会自动调ServiceMain函数,在ServiceMain函数中需要执行RegisterServiceCtrlHandler函数,然后可以返回也可以执行其它程序。
      

  7.   

    我现在单独做了一个应用程序,用来安装和启动服务,代码如下:
    #include <windows.h>
    #include <stdio.h>#define LOGFILE "C:\\Documents and Settings\\Administrator\\桌面\\log.txt"int WriteToLog(char* str)
    {
        FILE* log;
    log = fopen(LOGFILE, "a+");
        if (log == NULL)
    {
    log = fopen(LOGFILE, "w+");
    fprintf(log, "%s\n", str);
    fclose(log);
    }
        fprintf(log, "%s\n", str);
        fclose(log);
    return 0;
    }void InstallService();void main() 

        InstallService();
    }void InstallService()
    {
    SC_HANDLE schService;
    SC_HANDLE schSCManager;
    TCHAR szPath[512];
    //得到程序磁盘文件的路径
    if(GetModuleFileName(NULL,szPath,512)==0)
    {
    WriteToLog("得到程序磁盘文件的路径失败!");
    return;
    }
    //打开服务管理数据库
    schSCManager=OpenSCManager(
    NULL, //本地计算机
    NULL, //默认的数据库
    SC_MANAGER_ALL_ACCESS //要求所有的访问权
    );
    if(schSCManager)
    {
    //登记服务程序
    schService=CreateService(
    schSCManager,
    TEXT("MLOG"),
    TEXT("M LOG"),
    SERVICE_ALL_ACCESS,
    SERVICE_WIN32_OWN_PROCESS,
    SERVICE_AUTO_START,
    SERVICE_ERROR_NORMAL,
    szPath,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL);
    if(schService)
    {
    WriteToLog("服务成功安装!");
    if(StartService(schService, 0, NULL) == FALSE)
    {
    printf("StartService failed: %dn", GetLastError());
    return;
    }
    CloseServiceHandle(schService);
    }
    else
    {
    WriteToLog("创建服务失败!");
    }
    CloseServiceHandle(schSCManager);
    }
    else
    WriteToLog("打开服务管理器失败!");
    }可运行后总提示:StartService failed:1053, 服务启动不了,这是为什么啊?
      

  8.   

    ServiceMain中应该调用RegisterServiceCtrlHandler注册一个回调函数,并且要调SetServiceStatus设置服务状态。在回调函数函数中响应各种控制,也要调SetServiceStatus。另外当服务程序长时间执行一段代码而不能及时返回时,也要调SetServiceStatus。
      

  9.   

    我做了两个程序,做两个程序,一个应用程序和一个服务程序,在应用程序中使用了CreateService()函数,
    我想再问一下在CreateService()函数中,它第八个参数要的是这个应用程序的路径呢还是服务程序的路径?