怎样写一个 NT 服务程序

类别:VC语言 点击:0 评论:0 推荐:

先说一下NT服务的特点:
1.随系统的启动而启动
2.隐蔽性比较好,一般的手动方式不能删除
3.只适用于NT内核的OS

WIN98下的请参考RegisterServiceProcess API,这个API函数将进程注册为一个服务模式的进程.
下面是我写好的class,你只要在这个程序中用这个包含这个.h文件就可以了。

======================
service.h

// Service.h: interface for the CService class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_SERVICE_H__6ED74430_7123_484D_8CBD_A8E15381A869__INCLUDED_)
#define AFX_SERVICE_H__6ED74430_7123_484D_8CBD_A8E15381A869__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "winsvc.h"

class CService 
{
public:
 void Init_Service_Table_Entry();
 CService();
 virtual ~CService();
 void InstallService();

 static void WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv);
 static void WINAPI BeginSrv(DWORD Opcode);
 //
//static SERVICE_STATUS_HANDLE hServiceStatus;
//static SC_HANDLE scm,svc;
//static SERVICE_STATUS serviceStatus;
};

#endif // !defined(AFX_SERVICE_H__6ED74430_7123_484D_8CBD_A8E15381A869__INCLUDED_)


////////////////////////////
Service.cpp

// Service.cpp: implementation of the CService class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Service.h"


#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
SERVICE_STATUS_HANDLE hServiceStatus;
SC_HANDLE scm,svc;
SERVICE_STATUS serviceStatus;

CService::CService()
{

}

CService::~CService()
{

}

void WINAPI CService::BeginSrv(DWORD Opcode)
{
 switch(Opcode)
 {
 case SERVICE_CONTROL_STOP:
  serviceStatus.dwCurrentState =SERVICE_STOPPED;
  SetServiceStatus (hServiceStatus,&serviceStatus);
  break;
 case SERVICE_CONTROL_CONTINUE:
  serviceStatus.dwCurrentState = SERVICE_RUNNING;
  SetServiceStatus (hServiceStatus,&serviceStatus);
  break;
 case SERVICE_CONTROL_PAUSE:
  serviceStatus.dwCurrentState = SERVICE_PAUSED;
  SetServiceStatus (hServiceStatus,&serviceStatus);
  break;
  
 case SERVICE_CONTROL_INTERROGATE:
  break;
 }
 
 SetServiceStatus (hServiceStatus,&serviceStatus);
}

void CService::Init_Service_Table_Entry()
{
 SERVICE_TABLE_ENTRY ste[2];
 ste[0].lpServiceName="VirusService";//Service Name
 ste[0].lpServiceProc=ServiceMain; //service function Name
 
 // the last one must be NULL
 ste[1].lpServiceName=NULL;
 ste[1].lpServiceProc=NULL;
 StartServiceCtrlDispatcher(ste);
 InstallService();
 
}

void WINAPI CService::ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv)
{
 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;
 
 RegisterServiceCtrlHandler("VirusService",BeginSrv);
 serviceStatus.dwCurrentState = SERVICE_RUNNING;
 serviceStatus.dwCheckPoint = 0;
 serviceStatus.dwWaitHint = 0;
 SetServiceStatus(hServiceStatus,&serviceStatus);
 serviceStatus.dwCurrentState = SERVICE_RUNNING;
 serviceStatus.dwCheckPoint = 0;
 serviceStatus.dwWaitHint = 0;
 SetServiceStatus(hServiceStatus,&serviceStatus); //set service status
}

void CService::InstallService()
{
 //Get the modulefilename
 char currentPath[128];
 
 GetModuleFileName(NULL,currentPath,128);
 char* p = strrchr(currentPath,'\\');  //检测最后是否以"\\"结尾,如果是,删除。
 if (*p)        //返回当前文件的路径
  *p = 0;

 LPCTSTR lpsysfilename;
 lpsysfilename=(LPCTSTR)lstrcat(currentPath,"\\test.exe");
 
 scm=OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
 if(scm!=NULL)
  svc=CreateService(scm,"VirusService","VirusService",SERVICE_ALL_ACCESS,
  SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS,SERVICE_AUTO_START,SERVICE_ERROR_IGNORE,lpsysfilename,NULL,NULL,NULL,NULL,NULL);
 if(svc!=NULL)
  svc=OpenService(scm,"VirusService",SERVICE_START);
 if (svc!=NULL)
 {
  StartService(svc,0,NULL);
  CloseServiceHandle(svc);
 }
 CloseServiceHandle(scm);
}


好了,这个服务程序到此就结束了,写个测试程序吧,然后用
 CService ntservice;
 ntservice.Init_Service_Table_Entry();

到你的控制面板,可以看到系统的服务中是否多了一个virusservice

本程序在winxp+vc6下测通过。

本文地址:http://com.8s8s.com/it/it1615.htm