一个NT服务的框架,希望对大家有所帮助,请斑竹加精
很长一段时间以来,不断有人提问如何编写NT Service。其实,NT Service是有自己的框架的,只要按照框架编写,再进行安装,那么运行起来是很简单的。
这里是我写的一个NT系统Service的框架代码,你可以给它添加代码,实现自己的功能。
这个服务程序在自身可执行文件所在目录下建立AotoLog.log文件,记录可能发生的一切。你也可以运用WriteToLog和WriteRetLog这两个接口,往记录文件中添加自己的内容。
#include <windows.h>
#include <stdio.h>
////////////////////////////////////////////////////////////////////////////////////////////
// Declaretion
// Begin
#define SVR_NAME "AotoLogon"
#define LOG_NAME "AotoLog.log"
const DWORD MAX_LEN = 256;
char szLogFileName[MAX_LEN];
int nCount;
SERVICE_STATUS ServiceStatus;
SERVICE_STATUS_HANDLE sshStatusHandle;
BOOL CreateLogoFile();
BOOL WriteToLog(const char *Message);
BOOL WriteRetLog(const char *Msg, DWORD RetCode);
void WINAPI SvrStart(DWORD dwArgc,LPTSTR *lpArgv);
void WINAPI SvrCtrl(DWORD dwCode);
void ServiceEntry();
// End
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
// TODO: Add your own declaretion
// End
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
//
// Service control codes
//
////////////////////////////////////////////////////////////////////////////////////////////
void main(void)
{
if (!CreateLogoFile())
{
printf("Create logo file error, process terminated.\n");
return;
}
WriteToLog("[main] Logo file created, function begin.");
SERVICE_TABLE_ENTRY DispatchTable[] =
{
{SVR_NAME, SvrStart},
{NULL , NULL }
};
if (StartServiceCtrlDispatcher(DispatchTable))
{
WriteToLog("[main] StartServiceCtrlDispatcher success.");
}
else
{
WriteToLog("[main] StartServiceCtrlDispatcher failed.");
}
WriteToLog("[main] Function end.");
}
////////////////////////////////////////////////////////////////////////////////////////////
BOOL CreateLogoFile()
{
FILE *pLogFile;
char szFileName[MAX_LEN];
ZeroMemory(szFileName, MAX_LEN);
char *Tmp = NULL;
GetModuleFileName(NULL, szFileName, (DWORD)MAX_LEN);
Tmp = strrchr(szFileName, '\\');
Tmp += 1;
strcpy(Tmp, LOG_NAME);
ZeroMemory(szLogFileName, MAX_LEN);
strcpy(szLogFileName, szFileName);
pLogFile = fopen(szLogFileName, "w+");
if (NULL == pLogFile)
{
return FALSE;
}
if (fclose(pLogFile) != 0)
{
return FALSE;
}
nCount = 0;
return TRUE;
}
BOOL WriteToLog(const char *Message)
{
FILE *pLogFile;
pLogFile = fopen(szLogFileName, "a");
if (NULL == pLogFile)
{
return FALSE;
}
fprintf(pLogFile, "%d:\t %s\n\n", ++nCount, Message);
if (fclose(pLogFile) != 0)
{
return FALSE;
}
return TRUE;
}
BOOL WriteRetLog(const char *Msg, DWORD RetCode)
{
FILE *pLogFile;
pLogFile = fopen(szLogFileName, "a");
if (NULL == pLogFile)
{
return FALSE;
}
fprintf(pLogFile, "%d:\t %s\n", ++nCount, Msg);
fprintf(pLogFile, "RetCode = %d\n\n", RetCode);
if (fclose(pLogFile) != 0)
{
return FALSE;
}
return TRUE;
}
////////////////////////////////////////////////////////////////////////////////////////////
void WINAPI SvrStart(DWORD dwArgc,LPTSTR *lpArgv)
{
WriteToLog("[SvrStart] Function begin");
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;
sshStatusHandle = RegisterServiceCtrlHandler(SVR_NAME, SvrCtrl);
if (NULL == sshStatusHandle)
{
WriteToLog("[SvrStart] RegisterServiceCtrlHandler failed.");
return;
}
else
{
WriteToLog("[SvrStart] RegisterServiceCtrlHandler success.");
}
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
if(SetServiceStatus(sshStatusHandle,&ServiceStatus)==0)
{
WriteToLog("[SvrStart] SetServiceStatus failed.");
return;
}
else
{
WriteToLog("[SvrStart] SetServiceStatus success.");
}
ServiceEntry();
WriteToLog("[SvrStart] Function end");
}
void WINAPI SvrCtrl(DWORD dwCode)
{
WriteToLog("[SvrCtrl] Function begin");
switch(dwCode)
{
case SERVICE_CONTROL_PAUSE:
ServiceStatus.dwCurrentState = SERVICE_PAUSED;
WriteToLog("[SvrCtrl] SetServiceStatus: SERVICE_PAUSED");
break;
case SERVICE_CONTROL_CONTINUE:
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
WriteToLog("[SvrCtrl] SetServiceStatus: SERVICE_CONTINUE");
break;
case SERVICE_CONTROL_STOP:
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
WriteToLog("[SvrCtrl] SetServiceStatus: SERVICE_CONTROL_STOP");
if(!SetServiceStatus(sshStatusHandle,&ServiceStatus))
{
WriteToLog("[SvrCtrl] SetServiceStatus failed.");
}
else
{
WriteToLog("[SvrCtrl] SetServiceStatus sucess.");
}
return ;
case SERVICE_CONTROL_INTERROGATE:
break;
default:
break;
}
if(!SetServiceStatus(sshStatusHandle,&ServiceStatus))
{
WriteToLog("[SvrCtrl] SetServiceStatus failed.");
}
else
{
WriteToLog("[SvrCtrl] SetServiceStatus sucess.");
}
WriteToLog("[SvrCtrl] Function end");
}
////////////////////////////////////////////////////////////////////////////////////////////
//
// TODO: Fix your own service codes
//
////////////////////////////////////////////////////////////////////////////////////////////
void ServiceEntry()
{
WriteToLog("[ServiceEntry] Function begin.");
//////////////////////////////////////////////////////////////////////////////////
// TODO: add your own service codes here
// End
//////////////////////////////////////////////////////////////////////////////////
WriteToLog("[ServiceEntry] Function end.");
return;
}
////////////////////////////////////////////////////////////////////////////////////////////
//
// TODO: Adding your own function entrys
//
////////////////////////////////////////////////////////////////////////////////////////////
// End
////////////////////////////////////////////////////////////////////////////////////////////