VC系统服务程序

VC系统服务程序

                                      

// testService.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <stdio.h>
#include <afxwin.h>
#include <windows.h>
#include <winsvc.h>
#include <string.h>
#include <TLHELP32.H>
#include <shlwapi.h>

#pragma comment(lib,"ws2_32.lib")
//
//   函数原型声明
//

//服务的主函数
void ServiceMain(DWORD dwArgc,//参数个数
     LPTSTR *lpszArgv//具体的参数命令串
     );
//服务控制函数
//如控制服务的启动、暂停、停止等
void CtrlHandler(
     DWORD fdwControl//控制命令,如SERVICE_CONTROL_STOP等
     );

//向服务管理器报告服务状态
BOOL ReportStatusToSCMgr(DWORD dwCurrentState, //服务的当前状态
       DWORD dwWin32ExitCode, //服务报告的错误代码
       DWORD dwServiceSpecificExitCode, //自定义的错误代码
       DWORD dwCheckPoint, //用于报告事件进展的两个参数
       DWORD dwWaitHint);

//结束服务
void KillService();

//初始化线程,在线程中执行服务的主要处理函数
BOOL InitThread();

//服务中主要的任务处理函数(根据自己的任务需要,自己编写的)
DWORD myThreadProc(LPDWORD param);

//具体的处理任务程序,具体处理任务是
//从任务管理器的进程表中,查找是否有我们需要的进程
//如果没有,就启动我们指定的程序
//如果有,还要看该进程是否有响应
//如果有响应,则不做任何事情
//如果没有响应,表示该程序已死,需要先结束该进程,并重新启动他
void myServiceProc();


//获取服务程序所在的路径
CString GetServerPath();

//
//   全局变量声明
//
SERVICE_STATUS_HANDLE hServiceStatus; //存储调用RegisterServiceCtrlHandler返回的句柄
char *strServiceName = "testService"; 标识服务的内部名
BOOL nServiceRunning;//服务是否正在运行
HANDLE hService; //由CreateEvent或OpenEvent返回,用于KillService中
DWORD nServiceCurrentStatus; //服务的当前状态
HANDLE hServiceThread;//服务中创建的线程,用于运行主要的处理任务

DWORD dwMilliseconds;//线程唤醒时间(毫秒)

CString     strServerPath; //服务程序所在的路径

//main函数即入口点函数
//完成ServiceMain函数的初始化
int main(int argc, char* argv[])
{
strServerPath=GetServerPath();
//adServiceInit();//获得可执行程序的文件名,路径和窗口标题
SERVICE_TABLE_ENTRY service_table_entry[]={
   {"myService1",(LPSERVICE_MAIN_FUNCTION)ServiceMain},
   {"myService2",(LPSERVICE_MAIN_FUNCTION)ServiceMain},
   {NULL,NULL}//表示结束
  };
//这个数组的地址传向StartServiceCtrlDispatcher函数
BOOL bSuccess;
bSuccess=StartServiceCtrlDispatcher(service_table_entry);
if (!bSuccess)
{
  printf("创建失败!");
}
else
{
  printf("创建成功!");
}
return 0;
}

//服务的主函数(入口函数)
void ServiceMain(DWORD dwArgc,//参数个数
     LPTSTR *lpszArgv//具体的参数命令串
     )
{

hServiceStatus=RegisterServiceCtrlHandler(strServiceName,
  (LPHANDLER_FUNCTION)CtrlHandler);  //注册服务

if (!hServiceStatus)
{
  //AfxMessageBox("服务注册失败!");
  return;//如果注册不成功,直接返回
}

//注册成功后向SCM报告服务状态信息,因为服务还没初始化完成,
//所以当前服务状态为SERVICE_START_PENDING
BOOL bSuccess;
bSuccess=ReportStatusToSCMgr(SERVICE_START_PENDING,NO_ERROR,0,1,3000);//处理第一个事件大约需要3秒钟

if (!bSuccess)
{
  return;//如果报告不成功,直接返回
}
//报告成功后,创建一个事件,保持该函数的运行,直到SCM发出停止请求才返回
hService=CreateEvent(0,TRUE,FALSE,0);
//CreateEvent(
// LPSECURITY_ATTRIBUTES lpEventAttributes,   // 安全属性
// BOOL bManualReset,   // 复位方式
// BOOL bInitialState,   // 初始状态
// LPCTSTR lpName)   // 对象名称
if (hService==NULL)
{
  return;//事件创建不成功,直接返回
}
//再次向SCM报告服务状态信息
bSuccess=ReportStatusToSCMgr(SERVICE_START_PENDING,NO_ERROR,0,2,1000); //处理第二个事件大约需要2秒钟
if(!bSuccess)
{
  return; //如果不成功,直接返回
}
//InitThread()创建一个线程来运行我们的处理程序(服务中的关键处理部分)
//bSuccess=InitThread();
InitThread();
if (!bSuccess)
{
  return;//如果线程创建不成功,直接返回
}
//线程创建成功,服务开始运行我们的主要处理任务
//设置服务的当前状态为SERVICE_RUNNING
nServiceCurrentStatus=SERVICE_RUNNING;
bSuccess=ReportStatusToSCMgr(SERVICE_RUNNING,NO_ERROR,0,0,0); //再次向SCM报告服务的状态
if (!bSuccess)
{
  return;//如果报告不成功,直接返回
}
//线程中的处理函数运行结束后返回ServiceMain(),
//ServiceMain()调用WaitForSingleObject,
//因为服务被停止之前ServiceMain()不会结束
WaitForSingleObject(hService,INFINITE); //INFINITE表示无限等待,等待SCM的信号
CloseHandle(hService); //关闭句柄
return;
}
//服务控制函数

void CtrlHandler(DWORD dwControlCode)
{
BOOL success;
switch(dwControlCode)
{
case SERVICE_CONTROL_SHUTDOWN: 
case SERVICE_CONTROL_STOP:
  //先更新服务状态为 SERVICDE_STOP_PENDING,再停止服务
  nServiceCurrentStatus=SERVICE_STOP_PENDING;
  success=ReportStatusToSCMgr(SERVICE_STOP_PENDING,NO_ERROR,0,1,3000);
  KillService();
  return;
default:
  break;
}
ReportStatusToSCMgr(nServiceCurrentStatus,NO_ERROR,0,0,0);
}
//向服务管理器报告服务状态
BOOL ReportStatusToSCMgr(DWORD dwCurrentState, //服务的当前状态
       DWORD dwWin32ExitCode, //服务报告的错误代码
       DWORD dwServiceSpecificExitCode, //自定义的错误代码
       DWORD dwCheckPoint, //用于报告事件进展的两个参数
       DWORD dwWaitHint)
{
BOOL bSuccess;
SERVICE_STATUS nServiceStatus; //定义一个SERVICE_STATUS类型结构nServiceStatus 
nServiceStatus.dwServiceType=SERVICE_WIN32_OWN_PROCESS; //表示我们的服务是独占一个进程的服务
nServiceStatus.dwCurrentState=dwCurrentState; //当前服务状态
if(dwCurrentState==SERVICE_START_PENDING) 
{
  nServiceStatus.dwControlsAccepted=0; //服务的初始化没有完成
}
else
{
  //通知 SCM 服务接受哪个域。这里允许停止、关机、暂停继续
  nServiceStatus.dwControlsAccepted=
   SERVICE_ACCEPT_STOP 
   |SERVICE_ACCEPT_SHUTDOWN
   |SERVICE_ACCEPT_PAUSE_CONTINUE;
}
//dwServiceSpecificExitCode在你终止服务并报告退出细节时很有用。
//初始化服务时并不退出,因此值为 0
if(dwServiceSpecificExitCode==0)
{
  nServiceStatus.dwWin32ExitCode=dwWin32ExitCode;
}
else
{
  nServiceStatus.dwWin32ExitCode=ERROR_SERVICE_SPECIFIC_ERROR; //用户自定义错误代码
}
nServiceStatus.dwServiceSpecificExitCode=dwServiceSpecificExitCode;
//
nServiceStatus.dwCheckPoint=dwCheckPoint;
nServiceStatus.dwWaitHint=dwWaitHint;
//设置好nServiceStatus后,向SCM报告服务状态
//非0表示成功,0表示失败
bSuccess=SetServiceStatus(hServiceStatus,&nServiceStatus); 
if(!bSuccess)//如果失败
{
  KillService();
  //return bSuccess; //返回一个假
  return FALSE; 
}
else
{
  //return bSuccess; //返回真
  return TRUE;
}
}
//结束服务
void KillService()
{
nServiceRunning=false;
SetEvent(hService); //如果操作成功,则返回非零值,否则为0。设置事件的状态为有标记,释放任意等待线程。如果事件是手工的,此事件将保持有标记直到调用ResetEvent。这种情况下将释放多个线程,如果事件是自动的,此事件将保持有标记,直到一个线程被释放,系统将设置事件的状态为无标记。如果没有线程在等待,则此事件将保持有标记,直到一个线程被释放。
ReportStatusToSCMgr(SERVICE_STOPPED,NO_ERROR,0,0,0);
}

//初始化线程,在线程中执行服务的主要处理函数
BOOL InitThread()
{
DWORD id;
hServiceThread=CreateThread(
  0,
  0,
  (LPTHREAD_START_ROUTINE)myThreadProc,
  0,
  0,
  &id);
if(hServiceThread==NULL)
{
  return false; //线程创建不成功
}
else
{
  nServiceRunning=true; //设置服务为正在运行
  return true;

return true;
}

//服务中主要的任务处理函数(根据自己的任务需要,自己编写的)
DWORD myThreadProc(LPDWORD param)
{
CString strTime;
strTime=ReadInit("TimeOut","time1");
dwMilliseconds=atoi(strTime)*1000;
CString pauseOrNot;
while(nServiceRunning)//只要服务正在运行,就可以继续执行我们的处理任务
{
  pauseOrNot=ReadInit("RunningOrNot","running");
  if(!strcmp(pauseOrNot,"1"))
  {
   myServiceProc();
  }
 
  Sleep(dwMilliseconds); //唤醒线程

return 0;
}

//具体的处理任务程序void myServiceProc()
{
  ……
return;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值