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

©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值