WINDOWS后台服務程序編寫


 

 

 
 
在2000/XP等基於NT 的操作系統中,有一個服務管理器,它管理的后台進程被稱為 service。
服務是一種應用程序類型,它在后台運行,與 UNIX 后台應用程序類似。服務應用程序通常可以
在本地和通過網絡為用戶提供一些功能,例如客戶端/服務器應用程序、Web 服務器、數據庫服
務器以及其他基於服務器的應用程序。
    后台服務 程序是在后台悄悄運行的。我們通過將自己的程序登記為服務,可以使自己的程序不出現
在任務管理器中,並且隨系統啟動而最先運行,隨系統關閉而最后停止。
    
     服務控制管理器是一個RPC 服務器,它顯露了一組應用編程接口,程序員可以方便的編寫程序來配置
服務和控制遠程服務器中服務程序。
     服務程序通常編寫成控制台類型的應用程序,總的來說,一個遵守服務控制管理程序接口要求的程序
包含下面三個函數:
1。服務程序主函數(main):調用系統函數 StartServiceCtrlDispatcher 連接程序主線程到服務控制管理程序。
2。服務入口點函數(ServiceMain):執行服務初始化任務,同時執行多個服務的服務進程有多個服務入口函數。
3。控制服務處理程序函數(Handler):在服務程序收到控制請求時由控制分發線程引用。(此處是Service_Ctrl)。
 另外在系統運行此服務之前需要安裝登記服務程序:installService 函數。刪除服務程序則需要先刪除服務安裝登記:removeService 函數。
 
服務類型:
類型
說明
SERVICE_FILE_SYSTEM_DRIVER=2
文件系統驅動服務。
SERVICE_KERNEL_DRIVER=1
驅動服務。
SERVICE_WIN32_OWN_PROCESS=16
獨占一個進程的服務。
SERVICE_WIN32_SHARE_PROCESS=32
與其他服務共享一個進程的服務。
新建WIN32控制台程序, 其源文件名為service.cpp 。我用的開發工具是VC++.NET。
 
1.服務程序主函數
    服務控制管理程序啟動服務程序后,等待服務程序主函數調用系統函StartServiceCtrlDispatcher。一個SERVICE_WIN32_OWN_PROCESS 類型的服務應該立即調用 StartServiceCtrlDispatcher 函數,可以在服務啟動后讓服務入口點函數完成初始化工作。對於 SERVICE_WIN32_OWN_PROCESS 類型的服務和程序中所有服務共同的初始化工作可以在主函數中完成,但不要超過30秒。否則必須建立另外的線程完成這些共同的初始化工作,從而保證服務程序主函數能及時地調用 StartServiceCtrlDispatcher 函數。
 
 
主函數處理了三中命令行參數:- install,- remove,- debug,分別用於安裝,刪除和調試服務程序。如果不帶參數運行,則認為是服務控制管理出現啟動該服務程序。參數不正確則給出提示信息。
 
StartServiceCtrlDispatcher 函數負責把程序主線程連接到服務控制管理程序。具體描述如下:
BOOL StartServiceCtrlDispatcher(
 const LPSERVICE_TABLE_ENTRY lpServiceTable);
lpServiceStartTable 指向 SERVICE_TABLE_ENTRY 結構類型的數組,他包含了調用進程所提供的每個服務的入口函數和字符串名。表中的最后一個元素必須為 NULL,指明入口表結束。SERVICE_TABLE_ENTRY 結構具體描述如下:
 
typedef struct _SERVICE_TABLE_ENTRY { LPTSTR lpServiceName; LPSERVICE_MAIN_FUNCTION lpServiceProc;
} SERVICE_TABLE_ENTRY, *LPSERVICE_TABLE_ENTRY;
 
lpServiceName 是一個以 NULL 結尾的字符串,標識服務名。如果是 SERVICE_WIN32_OWN_PROCESS 類型的服務,這個字符串會被忽略。
lpServiceProc 指向服務入口點函數。
 
 
//服務程序主函數。
#include "stdafx.h"
#include "Windows.h"
#define SZAPPNAME      "serverSample"     //服務程序名
#define SZSERVICENAME "serviceSample"    //標識服務的內部名
 
//內部變量
bool                   bDebugServer=false;
SERVICE_STATUS              ssStatus;
SERVICE_STATUS_HANDLE sshStatusHandle;
DWORD                       dwErr=0;
TCHAR                       szErr[256];
 
//下面的函數由程序實現
void WINAPI Service_Main(DWORD dwArgc, LPTSTR *lpszArgv);
void WINAPI Service_Ctrl(DWORD dwCtrlCode);
void installService();
void removeService();
void debugService(int argc,char** argv);
bool ReportStatusToSCMgr(DWORD dwCurrentState,DWORD dwWin32ExitCode,DWORD dwWaitHint);
void AddToMessageLog(LPTSTR lpszMsg);
 
int _tmain(int argc, _TCHAR* argv[])
{   
     SERVICE_TABLE_ENTRY dispatchTable[]=
     {
         {TEXT(SZSERVICENAME),(LPSERVICE_MAIN_FUNCTION)Service_Main},
         { NULL,NULL}
     };
     if((argc>1)&&((*argv[1]=='-')||(argv[1]=="/")))
     {
         if(_stricmp("install",argv[1]+1)==0)
         {
              installService();
         }
         else if(_stricmp("remove",argv[1]+1)==0)
         {
              removeService();
         }
         else if(_stricmp("debug",argv[1]+1)==0)
         {
              bDebugServer=true;
              debugService(argc,argv);
         }
         else
         {        //如果未能和上面的如何參數匹配,則可能是服務控制管理程序來啟動該程序。立即調用
                   //StartServiceCtrlDispatcher 函數。
              printf("%s - install to install the service /n",SZAPPNAME);
              printf("%s - remove to remove the service /n",SZAPPNAME);
              printf("%s - debug to debug the service /n",SZAPPNAME);
              printf("/n StartServiceCtrlDispatcher being called./n");
              printf("This may take several seconds.Please wait./n");
              if(!StartServiceCtrlDispatcher(dispatchTable))
                   AddToMessageLog(TEXT("StartServiceCtrlDispatcher failed."));
              else
                   AddToMessageLog(TEXT("StartServiceCtrlDispatcher OK."));
         }
         exit(0);
     }
     return 0;
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2.服務入口點函數
 
服務入口點函數 service_main 首先調用系統函數 RegisterServiceCtrlHandler 注冊服務控制處理函數 service_ctrl,然后調用 ReportStatusToSCMgr 函數,它通過系統函數 SetServiceStatus 更新服務的狀態,然后調用特定的服務初始化入口函數 ServiceStart 完成具體的初始化工作。
 
 

 

//服務入口點函數
void ServiceStart(DWORD dwArgc,LPTSTR* lpszArgv);//具體服務的初始化入口函數
 void WINAPI Service_Main(DWORD dwArgc, LPTSTR *lpszArgv)
{
     //注冊服務控制處理函數
     sshStatusHandle=RegisterServiceCtrlHandler(TEXT(SZSERVICENAME),Service_Ctrl);
     //如果注冊失敗
     if(!sshStatusHandle)
     {
         goto cleanup;
         return;
     }
     //初始化 SERVICE_STATUS 結構中的成員
     ssStatus.dwServiceType=SERVICE_WIN32_OWN_PROCESS;
     ssStatus.dwServiceSpecificExitCode=0;
     //更新服務狀態
     if(!ReportStatusToSCMgr(
         SERVICE_START_PENDING,//服務狀態,The service is starting.
         NO_ERROR,           //退出碼        
         3000))                  //等待時間
         goto cleanup;       //更新服務狀態失敗則轉向 cleanup
     ServiceStart(dwArgc,lpszArgv);
     return;
cleanup:
     //把服務狀態更新為 SERVICE_STOPPED,並退出。
     if(sshStatusHandle)
         (void)ReportStatusToSCMgr(SERVICE_STOPPED,dwErr,0);
}

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3.控制處理程序函數
 
 
3.控制處理程序函數

 

函數 Service_Ctrl 是服務的控制處理程序函數,由主函數線程的控制分發程序引用。在處理控制請求碼時,應該在確定的時間間隔內更新服務狀態檢查點,避免發生服務不能響應的錯誤。
 
 

 

//控制處理程序函數
void WINAPI Service_Ctrl(DWORD dwCtrlCode)
{
     //處理控制請求碼
     switch(dwCtrlCode)
     {
         //先更新服務狀態為 SERVICDE_STOP_PENDING,再停止服務。
     case SERVICE_CONTROL_STOP:
         ReportStatusToSCMgr(SERVICE_STOP_PENDING,NO_ERROR,500);
         ServiceStop();     //由具體的服務程序實現
         return;
         //暫停服務
     case SERVICE_CONTROL_PAUSE:
         ReportStatusToSCMgr(SERVICE_STOP_PENDING,NO_ERROR,500);
         ServicePause();    //由具體的服務程序實現
         ssStatus.dwCurrentState=SERVICE_PAUSED;
         return;
         //繼續服務
     case SERVICE_CONTROL_CONTINUE:
         ReportStatusToSCMgr(SERVICE_STOP_PENDING,NO_ERROR,500);
         ServiceContinue(); //由具體的服務程序實現
         ssStatus.dwCurrentState=SERVICE_RUNNING;
         return;
         //更新服務狀態
     case SERVICE_CONTROL_INTERROGATE:
         break;
         //無效控制碼
     default:
         break;
     }
     ReportStatusToSCMgr(ssStatus.dwCurrentState,NO_ERROR,0);
}

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
除了系統定義的五種控制碼外(還有一種是:SERVICE_CONTROL_SHUTDOWN),用戶還可自定義控制碼,其取值范圍是128-255。用戶可以通過控制面板中的服務項向特定服務程序的控制處理函數發送控制碼,程序員可以調用系統函數 ControlService 直接向服務程序的控制處理函數發送控制碼。其函數原型如下:
 
BOOL ControlService(
 SC_HANDLE hService,
 DWORD dwControl,
 LPSERVICE_STATUS lpServiceStatus
);
hService :函數 OpenService or CreateService 返回的服務程序句柄。
dwControl :控制碼,不能是SERVICE_CONTROL_SHUTDOWN。
lpServiceStatus:返回最后收到的服務狀態信息。
 
4.安裝服務程序
 
    每個已安裝服務程序在 HKEY_LOCAL_MACHINE/SYSTE/CurrentControlSet/Services 下都有一個服務名的關鍵字,程序員可以調用系統函數 CreateService 安裝服務程序,並指定服務類型,服務名等。這個函數創建一個服務對象,並將其增加到相關的服務控制管理器數據庫中。
下面是函數原型:
 
SC_HANDLE CreateService(
 SC_HANDLE hSCManager, //服務控制管理程序維護的登記數據庫的句柄,由系統函數OpenSCManager 返回
 LPCTSTR lpServiceName, //以NULL 結尾的服務名,用於創建登記數據庫中的關鍵字
 LPCTSTR lpDisplayName, //以NULL 結尾的服務名,用於用戶界面標識服務
 DWORD dwDesiredAccess, //指定服務返回類型
 DWORD dwServiceType, //指定服務類型
 DWORD dwStartType, //指定何時啟動服務
 DWORD dwErrorControl, //指定服務啟動失敗的嚴重程度
 LPCTSTR lpBinaryPathName, //指定服務程序二進制文件的路徑
 LPCTSTR lpLoadOrderGroup, //指定順序裝入的服務組名
 LPDWORD lpdwTagId, //忽略,NULL
 LPCTSTR lpDependencies, //指定啟動該服務前必須先啟動的服務或服務組
 LPCTSTR lpServiceStartName, //以NULL 結尾的字符串,指定服務帳號。如是NULL,則表示使用LocalSystem 帳號
 LPCTSTR lpPassword //以NULL 結尾的字符串,指定對應的口令。為NULL表示無口令。但使用LocalSystem時填NULL
);
 
     對於一個已安裝的服務程序,可以調用系統函數 OpenService 來獲取服務程序的句柄
下面是其函數原型:
SC_HANDLE OpenService(
 SC_HANDLE hSCManager,
 LPCTSTR lpServiceName,
 DWORD dwDesiredAccess
);
 
hSCManager :服務控制管理程序微服的登記數據庫的句柄。由函數 OpenSCManager function 返回 這個句柄。
lpServiceName :將要打開的以NULL 結尾的服務程序的名字,和 CreateService 中的 lpServiceName 相對應。
dwDesiredAccess :指定服務的訪問類型。服務響應請求時,首先檢查訪問類型。
用CreateService 或OpenService 打開的服務程序句柄使用完畢后必須用CloseServiceHandle 關閉。
OpenSCManager打開的服務管理數據庫句柄也必須用它來關閉。
 
 
//安裝服務程序
void installService()
{
     SC_HANDLE schService;
     SC_HANDLE schSCManager;
     TCHAR szPath[512];
     //得到程序磁盤文件的路徑
     if(GetModuleFileName(NULL,szPath,512)==0)
     {
         _tprintf(TEXT("Unable to install %s - %s /n"),
              TEXT(SZAPPNAME),
         GetLastError());//@1獲取調用函數返回的最后錯誤碼
         return;
     }
     //打開服務管理數據庫
     schSCManager=OpenSCManager(
                            NULL,    //本地計算機
                            NULL,    //默認的數據庫
                            SC_MANAGER_ALL_ACCESS //要求所有的訪問權
                            );
if(schSCManager)
     {
         //登記服務程序
         schService=CreateService(
              schSCManager,                    //服務管理數據庫句柄
              TEXT(SZSERVICENAME),             //服務名
              TEXT(SZAPPNAME),       //用於顯示服務的標識
              SERVICE_ALL_ACCESS,              //響應所有的訪問請求
              SERVICE_WIN32_OWN_PROCESS,       //服務類型
              SERVICE_DEMAND_START,            //啟動類型
              SERVICE_ERROR_NORMAL,            //錯誤控制類型
              szPath,                              //服務程序磁盤文件的路徑
              NULL,                                //服務不屬於任何組
              NULL,                                //沒有tag標識符
              NULL,              //啟動服務所依賴的服務或服務組,這里僅僅是一個空字符串
              NULL,                                //LocalSystem 帳號
              NULL);
         if(schService)
         {
              _tprintf(TEXT("%s installed. /n"),TEXT(SZAPPNAME));
              CloseServiceHandle(schService);
         }
         else
         {
              _tprintf(TEXT("CreateService failed - %s /n"),GetLastError());
         }
         CloseServiceHandle(schSCManager);
     }
     else
         _tprintf(TEXT("OpenSCManager failed - %s /n"),GetLastError());
}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5.停止和刪除已安裝的服務程序
 
//停止和刪除已安裝的服務程序
void removeService()
{
     SC_HANDLE schService;
     SC_HANDLE schSCManager;
     //打開服務管理數據庫
     schSCManager=OpenSCManager(
                       NULL,    //本地計算機
                       NULL,    //默認的數據庫
                       SC_MANAGER_ALL_ACCESS //要求所有的訪問權
                       );
     if(schSCManager)
     {
         //獲取服務程序句柄
         schService=OpenService(
              schSCManager,          //服務管理數據庫句柄
              TEXT(SZSERVICENAME),   //服務名
              SERVICE_ALL_ACCESS     //響應所有的訪問請求
              );
         if(schService)
         {
              //試圖停止服務
              if(ControlService(
                   schService,                 //服務程序句柄
                   SERVICE_CONTROL_STOP, //停止服務請求碼
                   &ssStatus              //接收最后的服務狀態信息
                   ))
              {
                   _tprintf(TEXT("Stopping %s."),TEXT(SZAPPNAME));
                   Sleep(1000);
 
                   //等待服務停止
                   //
                   while(QueryServiceStatus(schService,&ssStatus))
                   {
                       if(SERVICE_STOP_PENDING==ssStatus.dwCurrentState)
                       {
                            _tprintf(TEXT("."));
                            Sleep(1000);
                       }
                       else
                            break;
                   }
                   if(SERVICE_STOPPED==ssStatus.dwCurrentState)
                       _tprintf(TEXT("/n %s stopped. /n"),TEXT(SZAPPNAME));
                   else
                       _tprintf(TEXT("/n %s failed to stopp. /n"),TEXT(SZAPPNAME));
              }
              //刪除已安裝的服務程序安裝
              if(DeleteService(schService))
                   _tprintf(TEXT("%s removed. /n"),TEXT(SZAPPNAME));
              else
_tprintf(TEXT("DeleteService failed - %s. /n"), GetLastError());
              CloseServiceHandle(schService);
         }
         else
              _tprintf(TEXT("OpenService failed - %s /n"),GetLastError());
         CloseServiceHandle(schSCManager);
     }
     else
         _tprintf(TEXT("OpenSCManager failed - %s /n"),GetLastError());
}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
      在編譯程序的時候,我們會發覺ServiceStop();ServicePause();ServiceContinue();等三個函數沒有具體實現,這對於理解此文的人來說應該不難編寫,在此我可以給點文檔內的參考:聲明     SetTheServiceStatus()函數,
// 
   //  SetTheServiceStatus -   This just wraps up SetServiceStatus.
   // 
   void SetTheServiceStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode,
                            DWORD dwCheckPoint,   DWORD dwWaitHint)
   {
      SERVICE_STATUS ss;  // Current status of the service.

      // 
      // Disable control requests until the service is started.
      // 
      if (dwCurrentState == SERVICE_START_PENDING)
         ss.dwControlsAccepted = 0;
      else
         ss.dwControlsAccepted =
                       SERVICE_ACCEPT_STOP|SERVICE_ACCEPT_SHUTDOWN;
                       // Other flags include SERVICE_ACCEPT_PAUSE_CONTINUE
                       // and SERVICE_ACCEPT_SHUTDOWN.

      // Initialize ss structure.
      ss.dwServiceType             = SERVICE_WIN32_OWN_PROCESS;
      ss.dwServiceSpecificExitCode = 0;
      ss.dwCurrentState            = dwCurrentState;
      ss.dwWin32ExitCode           = dwWin32ExitCode;
      ss.dwCheckPoint              = dwCheckPoint;
      ss.dwWaitHint                = dwWaitHint;

      // Send status of the service to the Service Controller.
      if (!SetServiceStatus(ssh, &ss))
         ErrorStopService(TEXT("SetServiceStatus"));
   }
    然后用如下的方式來調用函數來實現源程序中缺少的功能 : 
    SetTheServiceStatus(SERVICE_STOPPED, GetLastError(), 0, 0);// Stop the service.
 
 
--------------------------------------------------------------------------------
這是在學習windows的服務安裝機制時的筆記,主要是一些函數的說明,還有我自己的代碼,沒有整理過比較亂
OpenSCManager
    The OpenSCManager function establishes a connection to the service control manager on the specified computer and opens the specified service control manager database.
 
     SC_HANDLE OpenSCManager(
        LPCTSTR lpMachineName,
        LPCTSTR lpDatabaseName,
        DWORD dwDesiredAccess   如果以administrators的權限創建服務的話,該字段的值為SC_MANAGER_ALL_ACCESS
    );
 
CreateService
    The CreateService function creates a service object and adds it to the specified service control manager database
 
    SC_HANDLE  CreateService(
         SC_HANDLE hSCManager,
         LPCTSTR lpServiceName,    //服務的名稱
         LPCTSTR lpDisplayName,   
         DWORD dwDesiredAccess,    //SERVICE_ALL_ACCESS
         DWORD dwServiceType,      //SERVICE_WIN32_OWN_PROCESS
         DWORD dwStartType,        //SERVICE_AUTO_START
         DWORD dwErrorControl,     //SERVICE_ERROR_IGNORE
         LPCTSTR lpBinaryPathName,     //指向二進制文件的路徑
         LPCTSTR lpLoadOrderGroup,
         LPDWORD lpdwTagId,
         LPCTSTR lpDependencies,
         LPCTSTR lpServiceStartName,
         LPCTSTR lpPassword
        );
 
Type                     Meaning
SERVICE_FILE_SYSTEM_DRIVER      File system driver service.
SERVICE_KERNEL_DRIVER      Driver service.
SERVICE_WIN32_OWN_PROCESS       Service that runs in its own process.
SERVICE_WIN32_SHARE_PROCESS     Service that shares a process with other services.
 
StartService :  啟動一個服務
 
        BOOL StartService(
             SC_HANDLE hService,
             DWORD dwNumServiceArgs,
             LPCTSTR* lpServiceArgVectors
            );
 
QueryServiceStatus
 
    BOOL QueryServiceStatus(
         SC_HANDLE hService,
         LPSERVICE_STATUS lpServiceStatus
        );
 
Return:
 
    If the function succeeds, the return value is nonzero.
    If the function fails, the return value is zero. To get extended error information, call GetLastError.
 
RegisterServiceCtrlHandler:      注冊一個服務
 
    SERVICE_STATUS_HANDLE RegisterServiceCtrlHandler(
         LPCTSTR lpServiceName,        //服務的名字
         LPHANDLER_FUNCTION lpHandlerProc      //服務的控制函數的名字
        ); 
創建服務線程 服務完成的功能在這里調用
 
CreateThread
 
    HANDLE CreateThread(
         LPSECURITY_ATTRIBUTES lpThreadAttributes,
         SIZE_T dwStackSize,
         LPTHREAD_START_ROUTINE lpStartAddress,    //線程函數的名字
         LPVOID lpParameter,
         DWORD dwCreationFlags,
         LPDWORD lpThreadId
        );
 
附上我的代碼:
 
#include "windows.h"
#include "stdio.h"
 
//全局變量
     SERVICE_STATUS      ServiceStatus;
     SERVICE_STATUS_HANDLEServiceStatusHandle;
 
 
//函數聲明
voidInstallService(char *szServicePath);
voidWINAPIServiceStart(DWORDdwArgc,LPTSTR *lpArgv);
voidWINAPIServiceControl(DWORDdwCode);
DWORDWINAPIService(LPVOIDlpvThread);      //服務功能函數
 
 
intmain(intargc, char* argv[])
{     
     //定義SERVICE_TABLE_ENTRY DispatchTable[] 結構
     SERVICE_TABLE_ENTRYDispatchTable[2] =
     {
           {"mixu_yy", ServiceStart},                 
           {NULL, NULL}
     };
 
     //安裝或者打開服務
     StartServiceCtrlDispatcher(DispatchTable);
     InstallService(argv[0]);
    
     return 0;
}
//函數定義
voidInstallService(char *szServicePath)
{
     SC_HANDLE        schSCManager;
     SC_HANDLE        schService;     
     SERVICE_STATUS      InstallServiceStatus;
     DWORD      dwErrorCode;
    
     //打開服務管理數據庫
     schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
     if(schSCManager == NULL)
     {
               //Open Service Control Manager Database Failed!;
         return;
     }
     //創建服務
     schService = CreateService(     
                                                  schSCManager,
                             "mixu_yy",
                             "mixu_yy",
                             SERVICE_ALL_ACCESS,
                             SERVICE_WIN32_OWN_PROCESS,
                             SERVICE_AUTO_START,
                             SERVICE_ERROR_IGNORE,
                             szServicePath,
                             NULL,
                             NULL,
                             NULL,
                             NULL,
                             NULL);
     if(schService == NULL)
     {
           dwErrorCode = GetLastError();
           if(dwErrorCode != ERROR_SERVICE_EXISTS)
           {
                 //創建服務失敗
                 CloseServiceHandle(schSCManager);
                 return;
           }
           else
           {
                 //要創建的服務已經存在
                 schService = OpenService(schSCManager, "mixu_yy", SERVICE_START);
                 if(schService == NULL)
                 {
                       //Open Service Failed!;
                       CloseServiceHandle(schSCManager);
                       return;
                 }
           }
     }
     else
     {
           //Create Service Success!;
     }
     //啟動服務
     if(StartService(schService, 0, NULL)==0 )
     {
           //啟動失敗
           dwErrorCode = GetLastError();
           if(dwErrorCode == ERROR_SERVICE_ALREADY_RUNNING)
           {
                 //Service already run!;
                 CloseServiceHandle(schSCManager);
                 CloseServiceHandle(schService);
                 return ;
           }
     }
     else
     {
           //Service pending
     }
 
     while(QueryServiceStatus(schService, &InstallServiceStatus) != 0)
     {
           if(InstallServiceStatus.dwCurrentState == SERVICE_START_PENDING)
           {
                 //Sleep(100);
           }
           else
           {
                 break;
           }
     }
     if(InstallServiceStatus.dwCurrentState != SERVICE_RUNNING)
     {
           //Failure!
     }
     else
     {
           //Sucess!
     }
 
     //擦屁股
     CloseServiceHandle(schSCManager);
     CloseServiceHandle(schService);
     return;
}
 
voidWINAPIServiceStart(DWORDdwArgc,LPTSTR *lpArgv)
{
     HANDLEhThread;
 
     ServiceStatus.dwServiceType      = SERVICE_WIN32;
     ServiceStatus.dwCurrentState      = SERVICE_START_PENDING;
     ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP      |SERVICE_ACCEPT_PAUSE_CONTINUE;
    
     ServiceStatus.dwServiceSpecificExitCode      = 0;
     ServiceStatus.dwWin32ExitCode            = 0;
     ServiceStatus.dwCheckPoint            = 0;
     ServiceStatus.dwWaitHint            = 0;
 
     ServiceStatusHandle = RegisterServiceCtrlHandler("mixu_yy", ServiceControl);
     if(ServiceStatusHandle == 0)
     {
           //error
           return;
     }
 
     ServiceStatus.dwCurrentState      = SERVICE_RUNNING;
     ServiceStatus.dwCheckPoint      = 0;
     ServiceStatus.dwWaitHint      = 0;
 
     if(SetServiceStatus(ServiceStatusHandle, &ServiceStatus) == 0)
     {
           //SetServiceStatus error!
           return;
     }
    
     //創建服務線程   服務完成的功能在這里調用
     hThread = CreateThread(NULL,
                       0,
                       Service,
                       NULL,
                       0,
                       NULL);
     if(hThread == NULL)
     {
           //CreateThread error!
           return;
     }
     CloseHandle(hThread);
     return;
}
 
//服務控制模塊
 
voidWINAPIServiceControl(DWORDdwCode)
{
     switch(dwCode) {
     caseSERVICE_CONTROL_PAUSE:
           ServiceStatus.dwCurrentState      = SERVICE_PAUSED;
           break;
 
     caseSERVICE_CONTROL_CONTINUE:
           ServiceStatus.dwCurrentState      = SERVICE_RUNNING;
           break;
 
     caseSERVICE_CONTROL_STOP:
           ServiceStatus.dwCurrentState      = SERVICE_STOPPED;
           ServiceStatus.dwWin32ExitCode      = 0;
           ServiceStatus.dwCheckPoint      = 0;
           ServiceStatus.dwWaitHint      = 0;
           if(SetServiceStatus(ServiceStatusHandle, &ServiceStatus) == 0)
           {
                 //SetServiceStatus error!
           }
           return;
     caseSERVICE_CONTROL_INTERROGATE:
           break;
     default:
           break;
     }
 
     if(SetServiceStatus(ServiceStatusHandle, &ServiceStatus) == 0)
     {
           //SetServiceStatus error!
     }
 
     return ;
}
 
//服務線程函數
DWORDWINAPIService(LPVOIDlpvThread)
{
           //實現函數功能的地方。
       return 1;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM