zoukankan      html  css  js  c++  java
  • windows系统服务的注册及运行服务方法

    如果不想将程序放入注册表的启动项又想让程序随windows自动运行,那么可以通过将程序注册为windows服务来达到自动运行的效果。步骤可分为两步,第一:首先将要启动的程序进行注册加入至服务中。第二:在程序中响应服务控制的请求,这一步必须要实现,否则当你在启动服务时会出现"错误10053:服务没有及时响应启动或控制请求"。

    以下代码为注册及启动服务方法:

    一、将程序注册为windows服务

    (1)注册为服务:

    BOOL CreateSampleService()
    {
     SC_HANDLE schSCManager;
     
     // Open a handle to the SC Manager database.
     schSCManager = OpenSCManager(
      NULL,                    // local machine
      NULL,                    // ServicesActive database
      SC_MANAGER_ALL_ACCESS);  // full access rights
     
     if (NULL == schSCManager)
        printf("OpenSCManager failed (%d)/n", GetLastError());

        TCHAR szPath[MAX_PATH]; 
         
        strcpy(szPath, "E://tttt//Debug//tttt.exe");
        SC_HANDLE schService = CreateService(
            schSCManager,              // SCManager database
            TEXT("MyServer"),        // name of service
            "Application Service",           // service name to display
            SERVICE_ALL_ACCESS,        // desired access
            SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, // service type
            SERVICE_AUTO_START,      // start type
            SERVICE_ERROR_NORMAL,      // error control type
            szPath,                    // path to service's binary
            NULL,                      // no load ordering group
            NULL,                      // no tag identifier
            NULL,                      // no dependencies
            NULL,                      // LocalSystem account
            NULL);                     // no password 
     
        if (schService == NULL)
        {
            printf("CreateService failed (%d)/n", GetLastError());
            return FALSE;
        }
        else
        {
              if ( !StartService(schService, NULL, NULL) )

             {

                    CloseServiceHandle(schService);

                     printf("StartService failed (%d)/n", GetLastError());

                    return FALSE;

            }

            CloseServiceHandle(schService);
            return TRUE;
        }
    }

    (2)删除服务

    BOOL DeleteSampleService()
    {
     SC_HANDLE schSCManager;
     
     // Open a handle to the SC Manager database.
     schSCManager = OpenSCManager(
      NULL,                    // local machine
      NULL,                    // ServicesActive database
      SC_MANAGER_ALL_ACCESS);  // full access rights
     
     if (NULL == schSCManager)
        printf("OpenSCManager failed (%d)/n", GetLastError());

        SC_HANDLE schService = OpenService(
            schSCManager,       // SCManager database
            TEXT("MyServer"), // name of service 
            DELETE);            // only need DELETE access
     
        if (schService == NULL)
        {
            printf("OpenService failed (%d)/n", GetLastError());
            return FALSE;
        }
     
        if (! DeleteService(schService) )
        {
            printf("DeleteService failed (%d)/n", GetLastError());
            return FALSE;
        }
        else
            printf("DeleteService succeeded/n");
     
        CloseServiceHandle(schService);
        return TRUE;
    }

    二、响应服务的程序实现

    /*
        响应系统服务的程序执行方法
    */
    #include   <stdio.h>  
    #include   <windows.h>  
    #include   <winsvc.h>  

    // 服务名称,如果服务为SERVICE_WIN32_OWN_PROCESS 类型,则服务名称被忽略
    #define  SERVICE_NAME   "MyServer"  

    // 启动服务入口函数
    void   WINAPI   MyServiceMain(DWORD argc, LPTSTR *argv); 
    // 服务控制函数
    void   WINAPI   MyServiceControl(DWORD   nControlCode);  
    // 服务所执行函数
    BOOL   MyExecuteService();  
    // 服务终止函数
    void   MyTerminateService();  
    // 服务运行后的处理线程
    DWORD   WINAPI MyServiceProc(LPVOID   lpParameter);  
    // 更新服务状态
    BOOL   MyUpdateServiceStatus(DWORD   dwCurrentState,   DWORD   dwWin32ExitCode,  
             DWORD   dwServiceSpecificExitCode,   DWORD   dwCheckPoint,DWORD   dwWaitHint);  

    // 服务状态句柄
    SERVICE_STATUS_HANDLE   hServiceStatus;    
    DWORD   ServiceCurrentStatus;  
    HANDLE   hServiceThread;  
    BOOL   bServiceRunning;  
    HANDLE   hServiceEvent;  

    // 信息输出
    VOID SvcDebugOut(LPSTR String, DWORD Status)
    {
     CHAR  Buffer[1024];
     if (strlen(String) < 1000)
     {
      sprintf(Buffer, String, Status);
      OutputDebugStringA(Buffer);
     }
    }

    void main(int argc, char* argv[])  
    {  
     // 服务入口表, ServiceMain为响应服务函数
     SERVICE_TABLE_ENTRY  ServiceTable[]   =    
     {  
      { SERVICE_NAME, MyServiceMain },  
      { NULL, NULL}  
     };  
       
     if(!StartServiceCtrlDispatcher(ServiceTable))  
     {  
      SvcDebugOut(" [MY_SERVICE] StartServiceCtrlDispatcher (%d)/n",
       GetLastError());
     }  
    }  

    void WINAPI MyServiceMain(DWORD argc, LPTSTR  *argv)  
    {  
     // 这里可获得指定的服务启动参数个数,及参数内容
     char ddd[128] = {'/0'};
     sprintf(ddd, "参数共有%d个", argc);
     
     // 注册服务控制回调
     hServiceStatus = RegisterServiceCtrlHandler(SERVERNAME,(LPHANDLER_FUNCTION)MyServiceControl);  
     if(!hServiceStatus || !MyUpdateServiceStatus(SERVICE_START_PENDING,NO_ERROR,0,1,3000))  
     {  
      return;  
     }  
       
     // 创建等待事件
     hServiceEvent = CreateEvent(0,TRUE,FALSE,0);  
     if(!hServiceEvent || !MyUpdateServiceStatus(SERVICE_START_PENDING,NO_ERROR,0,2,1000))  
     {  
      return;  
     }  
       
     // 运行服务
     if( !MyExecuteService() )  
     {
      return;  
     }  
       
     ServiceCurrentStatus = SERVICE_RUNNING;  
       
     if(!MyUpdateServiceStatus(SERVICE_RUNNING,NO_ERROR,0,0,0))  
     {  
      return;  
     }  
       
     // 等待受信
     WaitForSingleObject(hServiceEvent,INFINITE);  
     CloseHandle(hServiceEvent);  
     
    }  

    // 服务消息处理线程
    void WINAPI MyServiceControl(DWORD   dwControlCode)  
    {  
     switch(dwControlCode)  
     {  
     case SERVICE_CONTROL_SHUTDOWN:  
     case SERVICE_CONTROL_STOP:  
      ServiceCurrentStatus = SERVICE_STOP_PENDING;  
      MyUpdateServiceStatus(SERVICE_STOP_PENDING,NO_ERROR,0,1,3000);  
      MyTerminateService();  
      return;  
     default:  
      break;  
     }  
       
     MyUpdateServiceStatus(ServiceCurrentStatus,NO_ERROR,0,0,0);  
    }  

    // 执行服务内容线程
    BOOL MyExecuteService()  
    {  
     DWORD   dwThreadID;  
     // 启动服务线程
     hServiceThread = CreateThread(0,0,(LPTHREAD_START_ROUTINE)MyServiceProc,0,0,&dwThreadID);  
       
     if(hServiceThread != NULL)  
     {  
      bServiceRunning = TRUE;  
      return TRUE;  
     }  
     else  
     {  
      return FALSE;  
     }  
    }  

    // 停止服务时执行的方法
    void MyTerminateService()  
    {  
    // ::MessageBox(NULL, "hello","you kill me ?", MB_ICONWARNING | MB_TOPMOST);
     bServiceRunning   =   FALSE;  
     SetEvent(hServiceEvent);  
     MyUpdateServiceStatus(SERVICE_STOPPED,NO_ERROR,0,0,0);  
    }  

    // 所要进行的操作在此线程中处理
    DWORD WINAPI MyServiceProc(LPVOID lpParameter)
    {  
     while(bServiceRunning)  
     {  
      Beep(450,150);  
      Sleep(4000);  
     }  
       
     return   0;  
    }  

    BOOL MyUpdateServiceStatus(DWORD   dwCurrentState,   DWORD   dwWin32ExitCode,  
             DWORD   dwServiceSpecificExitCode,   DWORD   dwCheckPoint,DWORD   dwWaitHint)  
    {  
     SERVICE_STATUS ServiceStatus;  
     ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;  
     ServiceStatus.dwCurrentState = dwCurrentState;  
       
     if(dwCurrentState == SERVICE_START_PENDING)  
     {  
      ServiceStatus.dwControlsAccepted   =   0;  
     }  
     else  
     {  
      ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;  
     }  
       
     if(dwServiceSpecificExitCode == 0)  
     {  
      ServiceStatus.dwWin32ExitCode = dwWin32ExitCode;  
     }  
     else  
     {  
      ServiceStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;  
     }  
       
     ServiceStatus.dwServiceSpecificExitCode = dwServiceSpecificExitCode;  
     ServiceStatus.dwCheckPoint = dwCheckPoint;  
     ServiceStatus.dwWaitHint = dwWaitHint;  
       
     if(!SetServiceStatus(hServiceStatus,&ServiceStatus))  
     {  
      MyTerminateService();  
      return   FALSE;  
     }  
     return   TRUE;  
    }

    实现以上方法后程序即可成为windows服务运行了!

  • 相关阅读:
    备战考研算法笔记(四)快速排序
    VMware安装
    使用 Vagrant 打造跨平台开发环境
    类加载器,注解,动态代理
    IE兼容forEach/map/every/some等新方法
    不得不看的Java代码性能优化总结
    关于Oracle误操作--数据被Commit后的数据回退(闪回)
    JPA与Hibernate的关系
    Jenkins-GitHub-Gradle自动构建项目
    过滤器Filter
  • 原文地址:https://www.cnblogs.com/tyjsjl/p/2156057.html
Copyright © 2011-2022 走看看