我的OS是XP,我试着写了一个后台服务程序,源码如下:
#include <windows.h>
#include <stdio.h>#define SLEEP_TIME 5000
#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;
}//声明几个全局变量,以便在程序的多个函数之间共享它们值
SERVICE_STATUS ServiceStatus; 
SERVICE_STATUS_HANDLE hStatus; void ServiceMain(int argc, char** argv); 
void ControlHandler(DWORD request); 
int InitService();
void InstallService();
void UnInstallService();
void ControlHandler(DWORD request) 

   switch(request) 
   { 
      case SERVICE_CONTROL_STOP: 
         WriteToLog("后台停止!");         ServiceStatus.dwWin32ExitCode = 0; 
         ServiceStatus.dwCurrentState = SERVICE_STOPPED; 
         SetServiceStatus (hStatus, &ServiceStatus);
         return; 
 
      case SERVICE_CONTROL_SHUTDOWN: 
         WriteToLog("后台停止!");         ServiceStatus.dwWin32ExitCode = 0; 
         ServiceStatus.dwCurrentState = SERVICE_STOPPED; 
         SetServiceStatus (hStatus, &ServiceStatus);
         return; 
        
      default:
         break;
    } 
 
    // Report current status
    SetServiceStatus (hStatus, &ServiceStatus);
 
    return; 
}void ServiceMain(int argc, char** argv) 

   int error;    hStatus = RegisterServiceCtrlHandler("MLOG", (LPHANDLER_FUNCTION)ControlHandler); 
   if (hStatus == (SERVICE_STATUS_HANDLE)0) 
   { 
      // 注册控制句柄失败
      return; 
   }     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; 
   
   error = InitService(); 
   if (error) 
   {
   //初始化失败!
      ServiceStatus.dwCurrentState = SERVICE_STOPPED; 
      ServiceStatus.dwWin32ExitCode = -1; 
      SetServiceStatus(hStatus, &ServiceStatus); 
      return; 
   } 
   ServiceStatus.dwCurrentState = SERVICE_RUNNING;
   
   SetServiceStatus (hStatus, &ServiceStatus);
 
   while (ServiceStatus.dwCurrentState == SERVICE_RUNNING)
   {
      char buffer[16];
  sprintf(buffer,"%s","写日志成功!");
      int result = WriteToLog(buffer);
      if (result)
      {
         ServiceStatus.dwCurrentState =  SERVICE_STOPPED; 
         ServiceStatus.dwWin32ExitCode = -1; 
         SetServiceStatus(hStatus,&ServiceStatus);
         return;
      }
      Sleep(SLEEP_TIME);
   }
   return; 
}int InitService() 

    int result;
    result = WriteToLog("初始化成功!");
    return result; 
}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); }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("打开服务管理器失败!");
}可以安装,但就是不能启动服务,为什么?帮忙看看,谢谢

解决方案 »

  1.   

    你不是有输出log吗?看看log里是到了那里出现问题。
      

  2.   

    log里边只有"服务成功安装!"那一句,也就是好像只执行了InstallService(); 其他的都没执行,不知道为什么
      

  3.   

    CreateService是安装服务,是安装程序或者动态安装服务的应用程序调用的。服务程序用RegisterServiceCtrlHandlerEx注册服务,然后响应各种控制命令。以下是MSDN中的例子,LZ可以参考一下:
    #include <windows.h>SERVICE_STATUS          MyServiceStatus; 
    SERVICE_STATUS_HANDLE   MyServiceStatusHandle; VOID SvcDebugOut(LPSTR String, DWORD Status);void WINAPI MyServiceStart (DWORD argc, LPTSTR *argv) 

        DWORD status; 
        DWORD specificError; 
     
        MyServiceStatus.dwServiceType        = SERVICE_WIN32; 
        MyServiceStatus.dwCurrentState       = SERVICE_START_PENDING; 
        MyServiceStatus.dwControlsAccepted   = SERVICE_ACCEPT_STOP | 
            SERVICE_ACCEPT_PAUSE_CONTINUE; 
        MyServiceStatus.dwWin32ExitCode      = 0; 
        MyServiceStatus.dwServiceSpecificExitCode = 0; 
        MyServiceStatus.dwCheckPoint         = 0; 
        MyServiceStatus.dwWaitHint           = 0; 
     
        MyServiceStatusHandle = RegisterServiceCtrlHandler( 
            "MyService", 
            MyServiceCtrlHandler); 
     
        if (MyServiceStatusHandle == (SERVICE_STATUS_HANDLE)0) 
        { 
            SvcDebugOut(" [MY_SERVICE] RegisterServiceCtrlHandler 
                failed %d\n", GetLastError()); 
            return; 
        } 
     
        // Initialization code goes here. 
        status = MyServiceInitialization(argc,argv, &specificError); 
     
        // Handle error condition 
        if (status != NO_ERROR) 
        { 
            MyServiceStatus.dwCurrentState       = SERVICE_STOPPED; 
            MyServiceStatus.dwCheckPoint         = 0; 
            MyServiceStatus.dwWaitHint           = 0; 
            MyServiceStatus.dwWin32ExitCode      = status; 
            MyServiceStatus.dwServiceSpecificExitCode = specificError; 
     
            SetServiceStatus (MyServiceStatusHandle, &MyServiceStatus); 
            return; 
        } 
     
        // Initialization complete - report running status. 
        MyServiceStatus.dwCurrentState       = SERVICE_RUNNING; 
        MyServiceStatus.dwCheckPoint         = 0; 
        MyServiceStatus.dwWaitHint           = 0; 
     
        if (!SetServiceStatus (MyServiceStatusHandle, &MyServiceStatus)) 
        { 
            status = GetLastError(); 
            SvcDebugOut(" [MY_SERVICE] SetServiceStatus error
                %ld\n",status); 
        } 
     
        // This is where the service does its work. 
        SvcDebugOut(" [MY_SERVICE] Returning the Main Thread \n",0); 
     
        return; 

     
    // Stub initialization function. 
    DWORD MyServiceInitialization(DWORD   argc, LPTSTR  *argv, 
        DWORD *specificError) 

        argv; 
        argc; 
        specificError; 
        return(0); 
    }
      

  4.   

    建议你使用参数控制,让程序在Service状态不执行安装的代码:
    int main( int argc , char *argv[] )
    {
       if(argc == 2 && char *argv[1]=="install" )
       {
        InstallService();
       }
       else
       {
        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); 
       }
    }
      

  5.   

    晕,犯了个低级错误,上面比较字符串应该用strcmpi
    if(argc == 2 && char *argv[1]=="install" )
    改成:
    if(argc == 2 && strcmpi(argv[1],"install")==0 )