通过vc 中Windows application 工程创建Windows service程序

本文介绍了如何在VC中创建Windows服务程序,包括注册服务、实现服务入口函数ServiceMain、控制服务的启动与停止。通过追加代码到_tWinMain,调用InitService和StartServiceCtrlDispatcher函数,实现服务的安装和卸载。服务状态通过ServiceStrl函数处理。提供的源代码包含头文件和实现文件,文件名为CommFile,实现了服务的安装、卸载、启动和停止功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实现步骤:

 

1. 注册service程序到系统服务管理器函数Install的实现,主要是以下两个api的调用。

    OpenSCManager

    CreateService

2. 在window application的入口函数中实现StartServiceCtrlDispatcher的调用。

   如果是利用我给的文件则只要在_tWinMain 中追加以下下内容就可以

   /***************************Start************************/

    TCHAR* lpCmdLine = GetCommandLine();

    TCHAR* pParam = _tcschr(lpCmdLine ,  ' ');

    if (pParam != NULL)

    {

pParam++;

    }
    InitService(pParam);
    return 0;
    /***************************End************************/

 

  InitService实际上就是执行以下部分内容:

   SERVICE_TABLE_ENTRY st[] =
    {
        {
            szServiceName /*你的服务名称,和CreateService中的服务名称应该一致*/,

             (LPSERVICE_MAIN_FUNCTION)ServiceMain /*ServiceMain 是你的service入口函数*/
        } , {
            NULL, NULL
        }
    };

     if (!::StartServiceCtrlDispatcher(st))
        {
           //Error
        }

 

3. 第二步用到的service入口函数ServiceMain的实现。

   ServiceMain的原型:

             void WINAPI ServiceMain(DWORD argc, LPTSTR *argv);

所有以上三步追加好以后就可以进行service程序的追加,启动了。

 

步骤1, 启动程序,执行第一步的Install,这时候就可以在service窗体中看到你追加的服务名称【应该是你设定的服务名称】

 步骤2.启动或停止你的服务。

           手动操作方法:  window键 + R 启动 运行对话框,输入 services.msc  启动服务管理,查找你的

                                  服务,选中并点右键选择 开始/停止。

 

           代码事项:执行StartService,具体看cpp文件的注释部分。

 

 其他:可以追加你要执行的相应操作,也可以添加卸载操作。查看Uninstall函数。

 

 

 *通过以上操作和以下文件的应用,执行生成的文件

   参数说明:

    exe文件   /install 加载自己的service到服务管理列表中

    exe文件   /uninstall 卸载加载的程序

 

 

以上是实现的简单说明,看实例可以更好的理解。

 

以下是头文件和实现文件的全部内容,文件名称是:CommFile

/*****************.h文件  Start*******************************/


#ifndef COMM_FILE_
#define COMM_FILE_

void Init();
BOOL IsInstalled();
BOOL Install();
BOOL Uninstall();
void LogEvent(LPCTSTR pszFormat, ...);
void WINAPI ServiceMain(DWORD argc, LPTSTR *argv);
void WINAPI ServiceStrl(DWORD dwOpcode) ;
void FormatMsg(DWORD errCode, TCHAR Msg[]);

static TCHAR szServiceName[] = _T("Temp3");
static BOOL bInstall;
static SERVICE_STATUS_HANDLE hServiceStatus;
static SERVICE_STATUS status;
static DWORD dwThreadID;
static SC_HANDLE  hScm ;
static SC_HANDLE hService ;
static  TCHAR szFilePath[MAX_PATH];


#define  MSG_LEN 1024
#define  InitService(lpCmdLine) /
 { /
    Init();  /
    dwThreadID = ::GetCurrentThreadId(); /
    SERVICE_TABLE_ENTRY st[] = /
    { /
        { /
            szServiceName, (LPSERVICE_MAIN_FUNCTION)ServiceMain /
        } , { /
            NULL, NULL /
        } /
    };  /
    if (wcsicmp(lpCmdLine, _T("/install")) == 0) { /
        if(Install()) { /
            LogEvent(_T("Install Success!")); /
        } else { /
            LogEvent(_T("Install Failed!")); /
        }; /
    } else if (wcsicmp(lpCmdLine, _T("/uninstall")) == 0) { /
        if(Uninstall()) { /
        LogEvent(_T("Uninstall Success!")); /
        } else { /
        LogEvent(_T("Uninstall Failed!")); /
        }; /
    } else { /
        LogEvent(_T("StartServiceCtrlDispatcher Start")); /
        if (!::StartServiceCtrlDispatcher(st)) /
        { /
            DWORD errCode = GetLastError();  /
            TCHAR  tchrTemp[MSG_LEN]; /
            TCHAR  errMsg[MSG_LEN]; /
            FormatMsg(errCode, tchrTemp); /
            wsprintf(errMsg, _T("Code = %d ErrorMessage = %s"), errCode, tchrTemp); /
            LogEvent(errMsg); /
        } /
    } /
 }


#endif

 

/*****************.h文件  End*******************************/

 

 

/*****************.Cpp文件  Start*******************************/

 
#include "stdafx.h"
#include "stdio.h"
#include "CommFile.h"
#include "tchar.h"
void LogEvent(LPCTSTR pszFormat, ...)
{
    SYSTEMTIME sysTem;
    //GetSystemTime(&sysTem);
    GetLocalTime(&sysTem);
    char chrMultl[MSG_LEN];
    BOOL bFlg;
    LPSTR ptcsDot = NULL;
    char logFile[MAX_PATH];
    memset(logFile, 0, MAX_PATH);

    WideCharToMultiByte(CP_ACP, NULL, pszFormat, wcslen(pszFormat) * sizeof(wchar_t) , chrMultl, MSG_LEN, "", &bFlg);
    WideCharToMultiByte(CP_ACP, NULL, szFilePath, MAX_PATH, logFile, MAX_PATH, "", &bFlg);
  
    ptcsDot = strrchr(logFile, '.');
    *ptcsDot = 0;
    strcat(logFile, ".log");
   
    FILE* hfile = fopen(logFile, "a+");
   if (hfile != NULL) {
       char chrMsg[MSG_LEN];
       memset(chrMsg, 0, MSG_LEN);
       sprintf(chrMsg, "%04d/02%02d/%02d %02d:%02d:%02d-%03d %s",
           sysTem.wYear,
           sysTem.wMonth,
           sysTem.wDay,
           sysTem.wHour,
           sysTem.wMinute,
           sysTem.wSecond,
           sysTem.wMilliseconds,
           chrMultl);
       fprintf(hfile, "%s/n", chrMsg);

       fclose(hfile);
      
   }


}

void FormatMsg(DWORD errCode, TCHAR Msg[])
{
    LPVOID lpMsgBuf;
    TCHAR  tchrTemp_utf8[256];
    memset(Msg, 0, sizeof(Msg));
    FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
        NULL, errCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL);
    lstrcat(Msg, (TCHAR*)lpMsgBuf);
}


void WINAPI ServiceStrl(DWORD dwOpcode)
{
    LogEvent(_T("ServiceStrl Start"));
  
    DWORD Opcode = dwOpcode;
    switch(Opcode)
    {
    case SERVICE_CONTROL_PAUSE:
         LogEvent(_T("SERVICE_CONTROL_PAUSE"));

        // Do whatever it takes to pause here.
        status.dwCurrentState = SERVICE_PAUSED;
      
        break;
    case SERVICE_CONTROL_CONTINUE:
         LogEvent(_T("SERVICE_CONTROL_CONTINUE"));

        // Do whatever it takes to continue here.
        status.dwCurrentState = SERVICE_RUNNING;
       
        break;
    case SERVICE_CONTROL_STOP:
        LogEvent(_T("SERVICE_CONTROL_STOP"));
        // Do whatever it takes to stop here.
        status.dwWin32ExitCode = 0;
        status.dwCurrentState = SERVICE_STOPPED;
        status.dwCheckPoint = 0;
        status.dwWaitHint = 0;
        if (!SetServiceStatus (hServiceStatus, &status))
        {
            LogEvent(_T("SetServiceStatus Error[SERVICE_CONTROL_STOP]"));
        }
    case SERVICE_CONTROL_INTERROGATE:
         LogEvent(_T("SERVICE_CONTROL_INTERROGATE"));

        // Fall through to send current status.
         return ;
        break;
    default:
       // LogEvent(_T("default"));
        return;
        break;
    }
    // Send current status.
    if (!SetServiceStatus(hServiceStatus, &status))
    {
        LogEvent(_T("SetServiceStatus Error"));
    }
    LogEvent(_T("ServiceStrl End"));
    return;
}

void Init() {
    hServiceStatus = NULL;
    status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
    status.dwCurrentState = SERVICE_START_PENDING;
    status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
    status.dwWin32ExitCode  = 0;
    status.dwServiceSpecificExitCode = 0;
    status.dwCheckPoint = 0;
    status.dwWaitHint = 0;
    memset(szFilePath, 0, sizeof(szFilePath));
    GetModuleFileName(NULL, szFilePath, sizeof(szFilePath));
   
}

BOOL Install() {
    hScm = OpenSCManager(NULL,
        NULL,
        SC_MANAGER_ALL_ACCESS);
   
    //create server
     hService = ::CreateService(
                                    hScm,
                                    szServiceName,
                                    szServiceName,
                                    SERVICE_ALL_ACCESS,
                                    SERVICE_WIN32_OWN_PROCESS,
                                    SERVICE_AUTO_START,
                                    SERVICE_ERROR_NORMAL,
                                    szFilePath,
                                    NULL,
                                    NULL,
                                    NULL,
                                    NULL,
                                    NULL);

     wchar_t szPath[1][MAX_PATH];
     lstrcpy(szPath[0], szFilePath);
    
     /*if(StartService(hService, 0, NULL) == FALSE) {
         LogEvent(_T("StartService Err"));
         TCHAR Msg[MSG_LEN];
         TCHAR errMsg[MSG_LEN];
         DWORD dwErrCode  = GetLastError();
         FormatMsg(dwErrCode, Msg);
         wsprintf(errMsg, _T("Code = %d ErrorMsg = %s"),
                            dwErrCode,
                            Msg);
         LogEvent(errMsg);

         ::CloseServiceHandle(hService);
         ::CloseServiceHandle(hScm);
         return FALSE;
     }*/
    ::CloseServiceHandle(hService);
    ::CloseServiceHandle(hScm);
return  TRUE;
}

BOOL Uninstall()
{

     hScm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    hService =  OpenService(hScm, szServiceName, SERVICE_STOP | DELETE);
    ControlService(hService, SERVICE_CONTROL_STOP, &status);
    DeleteService(hService);
    ::CloseServiceHandle(hService);
    ::CloseServiceHandle(hScm);

    return TRUE;
}

void WINAPI ServiceMain(DWORD argc, LPTSTR *argv)
{
  
    //Register the control requeset handler
    hServiceStatus = RegisterServiceCtrlHandler(szServiceName, ServiceStrl);
    if (hServiceStatus == (SERVICE_STATUS_HANDLE)0) {
        LogEvent(_T("Handler not installed"));
        return ;
    }

    status.dwServiceType = SERVICE_WIN32;
    status.dwCurrentState = SERVICE_START_PENDING;
    status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
    status.dwWin32ExitCode = 0;
    status.dwServiceSpecificExitCode = 0;
    status.dwCheckPoint = 0;
    status.dwWaitHint = 0;
    SetServiceStatus(hServiceStatus, &status);

    //LogEvent(_T("Start MySelf Server "));

    status.dwServiceType = SERVICE_WIN32;
    status.dwCurrentState = SERVICE_RUNNING;
    status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
    status.dwWin32ExitCode = 0;
    status.dwServiceSpecificExitCode = 0;
    status.dwCheckPoint = 0;
    status.dwWaitHint = 0;
    SetServiceStatus(hServiceStatus, &status);

    LogEvent(_T("ServiceMain End"));
 
}

/*****************.Cpp文件  End*******************************/

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值