C語言Windows服務程序編寫-ServiceMain

      C語言編寫的Windows服務程序,可以類比Linux/Unix環境下的daemon進程。

      一下是VS2010環境下的demo:

// windows_service.cpp : 定義控制檯應用程序的入口點。
//

#include "stdafx.h"
#include <Windows.h>
#include <stdio.h>  
  
#define SLEEP_TIME 5000                          /*間隔時間*/
#define LOGFILE "D:\\log.txt"              /*信息輸出文件*/

SERVICE_STATUS ServiceStatus;  /*服務狀態*/
SERVICE_STATUS_HANDLE hStatus; /*服務狀態句柄*/
  
void  ServiceMain(int argc, char** argv);
void  CtrlHandler(DWORD request);  
int   InitService();

int _tmain(int argc, _TCHAR* argv[])
{
	SERVICE_TABLE_ENTRY ServiceTable[2];  
    ServiceTable[0].lpServiceName="Monitor";  
    ServiceTable[0].lpServiceProc=(LPSERVICE_MAIN_FUNCTION)ServiceMain;  
    ServiceTable[1].lpServiceName=NULL;  
    ServiceTable[1].lpServiceProc=NULL;  
    StartServiceCtrlDispatcher(ServiceTable);  

	return 0;
}

int WriteToLog(char* str)  
{  
    FILE* pfile;  
    fopen_s(&pfile,LOGFILE,"a+");  
    if (pfile==NULL)  
    {  
        return -1;  
    }  
    fprintf_s(pfile,"%s\n",str);  
    fclose(pfile);

    return 0;  
}  
  
/*Service initialization*/
int InitService()   
{   
    OutputDebugString("Monitoring started.");  
    int result;  
    result = WriteToLog("Monitoring started.");

    return(result);   
}

/*Control Handler*/
void CtrlHandler(DWORD request)  
{  
    switch (request)  
    {  
    case SERVICE_CONTROL_STOP:  
        OutputDebugString("Monitoring stopped.");  
        WriteToLog("Monitoring stopped.");  
  
        ServiceStatus.dwWin32ExitCode = 0;   
        ServiceStatus.dwCurrentState = SERVICE_STOPPED;   
        SetServiceStatus (hStatus, &ServiceStatus);  
        return;  
    case SERVICE_CONTROL_SHUTDOWN:  
        OutputDebugString("Monitoring stopped.");  
        WriteToLog("Monitoring stopped.");  
  
        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;  
    ServiceStatus.dwServiceType =   
        SERVICE_WIN32;  
    ServiceStatus.dwCurrentState =   
        SERVICE_START_PENDING;  
	/*在本例中只接受系統關機和停止服務兩種控制命令*/
    ServiceStatus.dwControlsAccepted =   
        SERVICE_ACCEPT_SHUTDOWN |   
        SERVICE_ACCEPT_STOP;				
    ServiceStatus.dwWin32ExitCode = 0;  
    ServiceStatus.dwServiceSpecificExitCode = 0;  
    ServiceStatus.dwCheckPoint = 0;  
    ServiceStatus.dwWaitHint = 0;  
    hStatus = ::RegisterServiceCtrlHandler(  
        "Monitor",   
        (LPHANDLER_FUNCTION)CtrlHandler);  
    if (hStatus == (SERVICE_STATUS_HANDLE)0)  
    {  
        WriteToLog("RegisterServiceCtrlHandler failed");  
        return;  
    }  
    WriteToLog("RegisterServiceCtrlHandler success");  
    /* Initialize Service   */
    error = InitService();  
    if (error)   
    {  
        /* Initialization failed  */
        ServiceStatus.dwCurrentState =   
            SERVICE_STOPPED;   
        ServiceStatus.dwWin32ExitCode = -1;   
        SetServiceStatus(hStatus, &ServiceStatus);   
        return;   
    }   
    /*向SCM 報告運行狀態*/
    ServiceStatus.dwCurrentState =   
        SERVICE_RUNNING;  
    SetServiceStatus (hStatus, &ServiceStatus);  
      
    /*do something you want to do in this while loop*/
    MEMORYSTATUS memstatus;  
    while (ServiceStatus.dwCurrentState ==   
        SERVICE_RUNNING)  
    {  
        char buffer[16];  
        GlobalMemoryStatus(&memstatus);  
        int availmb = memstatus.dwAvailPhys/1024/1024;  
        sprintf_s(buffer,100,"available memory is %dMB",availmb);  
        OutputDebugString(buffer);  
        int result = WriteToLog(buffer);  
        if (result)  
        {  
            ServiceStatus.dwCurrentState =   
                SERVICE_STOPPED;   
            ServiceStatus.dwWin32ExitCode = -1;   
            SetServiceStatus(hStatus,   
                &ServiceStatus);  
            return;  
        }  
        Sleep(SLEEP_TIME);  
    }  
    WriteToLog("service stopped");

	return;
}
註冊&啓動服務的bat腳本:

sc create Monitor binpath= D:\test\windows_service.exe
sc start Monitor
請注意binpath= 後面的空格符,空格符缺失則無法創建服務。


停止和刪除服務的命令如下:

sc stop Monitor
sc delete Monitor



如有轉載,請註明出處:http://blog.csdn.net/embedded_sky/article/details/45073193

作者:super_bert@csdn

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章