您的位置:首页 > 编程语言 > C语言/C++

用C/C++编写的Window服务一例

2011-11-03 17:17 351 查看
用C/C++编写的Window服务一例

//NTServiceC.cpp
//用C/C++编写的Window服务一例
//安装与反安装批处理.bat
//方法一:
//echo sc delete NTServiceC
//echo sc create NTServiceC binpath= E:\Debug\NTServiceC.exe
//方法二:
//NTServiceC.exe uninstall
//NTServiceC.exe install
//NTServiceC.exe exec
#pragma once
#include <windows.h>
#include <stdio.h>
#include <iostream>
//#include <comdef.h>
#include <tchar.h>
#include <comutil.h>

#define SLEEP_TIME 5000
#define LOGFILE "c:\\NTServiceC.txt"

using namespace std;
char* ServiceName="NTServiceC";

enum EnumRunState
{
None=0,
Running=1,
Stoped=2,
Pause=3,
};

EnumRunState RunState;

WCHAR* CharPtr2ACharPtr(const char* src)
{
// Convert to a wchar_t*
size_t srcsize = strlen(src) + 1;
size_t newsize = srcsize;
size_t convertedChars = 0;
wchar_t *wcstring;
wcstring=new wchar_t[newsize];
mbstowcs_s(&convertedChars, wcstring, srcsize, src, _TRUNCATE);
//wcscat_s(wcstring, L" (wchar_t *)");
//wcout << wcstring << endl;
return wcstring;
};

int WriteToLog(char* str)
{
FILE* log;
log=fopen(LOGFILE,"a+");
if(log==NULL)  return 0;
fprintf(log,"%s\n",str);
fclose(log);
return 1;
}

//定义变量和方法
SERVICE_STATUS ServiceStatus;
SERVICE_STATUS_HANDLE hStatus;
HANDLE terminateEvent; //事件
HANDLE threadHandle;   //线程
VOID terminate(DWORD error);
void ServiceMain(int argc,char** argv);
void ControlHandler(DWORD request);
int InitService();
//
BOOL RunService(WCHAR* sSvcName);
VOID ResumeService();
VOID PauseService();
VOID StopService();
//
BOOL SendStatusToSCM (DWORD dwCurrentState,
DWORD dwWin32ExitCode,
DWORD dwServiceSpecificExitCode,
DWORD dwCheckPoint,
DWORD dwWaitHint);
//
void InstallService();
void UninstallService();
//
DWORD WINAPI ServiceThread(LPDWORD param);
//安装入口点
void main(int argc, char* argv[])
{
WCHAR* TServiceName=CharPtr2ACharPtr(ServiceName);
//方法一
SERVICE_TABLE_ENTRY ServiceTable[2];
//设置服务名称和服务入口函数
ServiceTable[0].lpServiceName=TServiceName;
ServiceTable[0].lpServiceProc=(LPSERVICE_MAIN_FUNCTION)ServiceMain;
ServiceTable[1].lpServiceName=NULL;
ServiceTable[1].lpServiceProc=NULL;

//方法二
/*SERVICE_TABLE_ENTRY  ServiceTable[]=
{
{TEXT(ServiceName),(LPSERVICE_MAIN_FUNCTION)ServiceMain},
{ NULL,NULL}
};*/
//注册为服务和反注册
//-------------------------------------------------
//引数
if(argc<=1)
{
//usage(使用方法)表示
cout<<"使用方法:"<<endl;
//cout<<"zxz\"zxz"<<ENDL;
//"install"
cout<<"\"install\"";
//"or"
cout<<"or";
//"uninstall"
cout<<"\"uninstall\"";
//"exec"
cout<<"\"exec \"";
cout<<" parameter required in the command line"<<endl;
}
if(argc>1)
{
if(_stricmp("install",argv[1])==0)
{   //install(InstallService)
InstallService();
cout<<"installService Succed!"<<endl;
}
else if(_stricmp("uninstall",argv[1])==0)
{   //uninstall(UninstallService)
UninstallService();
cout<<"UninstallService Succed!"<<endl;
}
else if(_stricmp("exec",argv[1])==0)
{   //exec(ServiceMain)
RunService(TServiceName);
}
else
{    //usage(使用方法)表示
cout<<"使用方法 :"<<endl;
//"install"
cout<<"\"install\"";
//"or"
cout<<"or";
//"uninstall"
cout<<"\"uninstall\"";
//"exec"
cout<<"\"exec \"";
//"or"
cout<<"or";
cout<<" parameter required in the command line"<<endl;
}
}
//-------------------------------------------------
//启动服务的控制分派机线程(启动并执行一个新线程)
StartServiceCtrlDispatcher(ServiceTable);
}

//服务入口点(主线程)
void ServiceMain(int argc,char** argv)
{
WCHAR* TServiceName=CharPtr2ACharPtr(ServiceName);
int success;
//success=InitService();
//if(!success)
//{
//       //初始化失败,终止服务
//	WriteToLog("ServiceMain::InitService初始化失败,终止服务");
//	ServiceStatus.dwCurrentState=SERVICE_STOPPED;
//	ServiceStatus.dwWin32ExitCode=-1;
//	SetServiceStatus(hStatus,&ServiceStatus);
//	//退出ServiceMain
//	return;
//}
//开始服务
RunService(TServiceName);

//注册服务控制处理函数
hStatus = RegisterServiceCtrlHandler(TServiceName,(LPHANDLER_FUNCTION)ControlHandler);
if(!hStatus)
{
WriteToLog("ServiceMain函数中注册服务控制处理函数失败!\n");
return;
}
//向SCM报告工作状态
RunState=EnumRunState::Running;
ServiceStatus.dwCurrentState=SERVICE_RUNNING;
ServiceStatus.dwServiceType=SERVICE_WIN32;
ServiceStatus.dwControlsAccepted =
SERVICE_ACCEPT_STOP |
SERVICE_ACCEPT_PAUSE_CONTINUE |
SERVICE_ACCEPT_SHUTDOWN;
/*SetServiceStatus(hStatus,&ServiceStatus);*/

////启动工作循环(这个模块在另外一个线程中执行)
//while(RunState==EnumRunState::Running)
//{
//  WriteToLog("ServiceMain函数写日志\n");
//     Sleep(500);
//}
//创建一个终结事件
terminateEvent = CreateEvent (0,TRUE,FALSE,0);
if (!terminateEvent)
{
terminate(GetLastError());
return;
}
//
success =  SendStatusToSCM(SERVICE_START_PENDING,NO_ERROR,0,2,1000);
if (!success)
{
terminate(GetLastError());
return;
}
//初始化
success =  InitService();
if (!success)
{
terminate(GetLastError());
return;
}
success = SendStatusToSCM(SERVICE_RUNNING,NO_ERROR,0,0,0);
if (!success)
{
terminate(GetLastError());
return;
}
//等待停止
WaitForSingleObject ( terminateEvent, INFINITE);

terminate(0);
WriteToLog("ServiceMain函数执行完毕!");
}
//服务控制台命令处理函数
void ControlHandler(DWORD request)
{
DWORD  currentState = 0;
BOOL success;
WriteToLog("ControlHandler:"+request);
switch(request)
{
case SERVICE_CONTROL_STOP:
RunState=EnumRunState::Stoped;
currentState = SERVICE_STOP_PENDING;
ServiceStatus.dwCurrentState=currentState;
SetServiceStatus(hStatus,&ServiceStatus);
StopService();
return;
case SERVICE_CONTROL_PAUSE:
RunState=EnumRunState::Pause;
currentState = SERVICE_PAUSED;
ServiceStatus.dwCurrentState=currentState;
SetServiceStatus(hStatus,&ServiceStatus);
PauseService();
break;
case SERVICE_CONTROL_CONTINUE:
RunState=EnumRunState::Running;
currentState = SERVICE_RUNNING;
ServiceStatus.dwCurrentState=currentState;
SetServiceStatus(hStatus,&ServiceStatus);
ResumeService();
break;
case SERVICE_CONTROL_INTERROGATE:
// it will fall to bottom and send status
break;

// Do nothing in a shutdown. Could do cleanup
// here but it must be very quick.
case SERVICE_CONTROL_SHUTDOWN:
// Do nothing on shutdown
return;
default:
break;
}
//ServiceStatus.dwCurrentState=currentState;
//SetServiceStatus(hStatus,&ServiceStatus);
}
//初始化服务(开始服务时执行)
int InitService()
{
int result;
WCHAR* TServiceName=CharPtr2ACharPtr(ServiceName);
//写日志信息
result=WriteToLog("Monitoring started.");
//开始一个线程 Start the service's thread
DWORD id;
threadHandle = CreateThread(0, 0,(LPTHREAD_START_ROUTINE)ServiceThread,0, 0, &id);
if (threadHandle==0)
{
result=0;
}
else
{
result=1;
}
//
WriteToLog("InitService一个线程开始了!");
return result;
}
DWORD WINAPI ServiceThread(LPDWORD param)
{
//线程操作
while(RunState==EnumRunState::Running)
{
WriteToLog("线程中写日志\n");
Sleep(500);
}
WriteToLog("线程操作ServiceThread完成!");
return 0;
}

//

BOOL RunService(WCHAR* sSvcName)
{
SC_HANDLE schSCManager;
SC_HANDLE scHandle;
BOOL boolRet;

// open to SCM
schSCManager = OpenSCManager(
0,
0,
SC_MANAGER_ALL_ACCESS
);

//Open
scHandle = OpenService(
schSCManager,
sSvcName,
SERVICE_ALL_ACCESS
);

//start
boolRet = StartService(
scHandle,
0,
NULL);

return boolRet;
}

VOID ResumeService()
{
//pauseService=FALSE;
//ResumeThread(threadHandle);
return;
}
VOID PauseService()
{
//pauseService = TRUE;
//SuspendThread(threadHandle);
return;
}
VOID StopService()
{
RunState=EnumRunState::Stoped;//=FALSE;
// Set the event that is holding ServiceMain
// so that ServiceMain can return
SetEvent(terminateEvent);
}
//安装/反安装函数
void InstallService()
{
SC_HANDLE schService;
SC_HANDLE schSCManager;
TCHAR szPath[512];

WCHAR* TServiceName=CharPtr2ACharPtr(ServiceName);

//Install Starting...
//获取模块文件路径名称
if(!GetModuleFileName(NULL,szPath,512))
{
return;
}

// open to SCM 
schSCManager = OpenSCManager(
0,  // pointer to machine name string
0,  // pointer to database name string
SC_MANAGER_CREATE_SERVICE // type of access
);
if (!schSCManager)
{
WriteToLog("OpenScManagerErrorID:"+GetLastError());
return;
}
// Install 新服务
schService = CreateService(
schSCManager, // handle to service control manager database
TServiceName, // pointer to name of service to start
TServiceName, // pointer to display name
SERVICE_ALL_ACCESS,// type of access to service
SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS ,// type of service
SERVICE_DEMAND_START,// when to start service
SERVICE_ERROR_NORMAL,// severity if service fails to start
szPath,       // pointer to name of binary file
NULL,         // pointer to name of load ordering group
NULL,         // pointer to variable to get tag identifier
NULL,         // pointer to array of dependency names
NULL,         // pointer to account name of service
NULL          // pointer to password for service account
);
if (!schService)
{
WriteToLog("CreateServiceErrorID:"+GetLastError());
return;
}
else
{
WriteToLog("Service installed\n");
}
// clean up
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
WriteToLog("Install Ending...\n");
}

void UninstallService()
{
SC_HANDLE schService;
SC_HANDLE schSCManager;
BOOL success;
SERVICE_STATUS svcStatus;

WCHAR* TServiceName=CharPtr2ACharPtr(ServiceName);

WriteToLog("Uninstall Starting...");

// open to SCM 
schSCManager = OpenSCManager(
0,// pointer to machine name string
0,// pointer to database name string
SC_MANAGER_CREATE_SERVICE // type of access
);
if (!schSCManager)
{
WriteToLog("OpenScManagerErrorID:"+GetLastError());
return;
}

//打开一个服务
schService = OpenService(
schSCManager,              // handle to service control manager database
TServiceName,              // pointer to name of service to start
SERVICE_ALL_ACCESS | DELETE// type of access to service
);
if (!schService)
{
WriteToLog("OpenServiceErrorID:"+GetLastError());
return;
}
//(if necessary)
success = QueryServiceStatus(schService, &svcStatus);
if (!success)
{
WriteToLog("In QueryServiceStatus ErrorID:"+GetLastError());
return;
}
if (svcStatus.dwCurrentState != SERVICE_STOPPED)
{
WriteToLog("Stopping service...");
success = ControlService(
schService,           // handle to service
SERVICE_CONTROL_STOP, // control code
&svcStatus            // pointer to service status structure
);
if (!success)
{
WriteToLog("In ControlServiceErrorID:"+GetLastError());
return;
}
}
//等待
do
{
QueryServiceStatus(schService,&svcStatus);
Sleep(500);

}while(SERVICE_STOP_PENDING==svcStatus.dwCurrentState);

if(SERVICE_STOPPED!=svcStatus.dwCurrentState)
{
WriteToLog("Failed to Stop Service ErrorID:"+GetLastError());
return;
}

//删除服务
success = DeleteService(schService);
if (success)
{
WriteToLog("Service removed\n");
}
else
{
WriteToLog("In DeleteService ErrorID:"+GetLastError());
return;
}
//Clean up
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
WriteToLog("Uninstal Ending...");
}

//
BOOL SendStatusToSCM (DWORD dwCurrentState,
DWORD dwWin32ExitCode,
DWORD dwServiceSpecificExitCode,
DWORD dwCheckPoint,
DWORD dwWaitHint)
{
BOOL success;
SERVICE_STATUS serviceStatus;

// Fill in all of the SERVICE_STATUS fields
serviceStatus.dwServiceType =SERVICE_WIN32_OWN_PROCESS;
serviceStatus.dwCurrentState = dwCurrentState;

// If in the process of something, then accept
// no control events, else accept anything
if (dwCurrentState == SERVICE_START_PENDING)
serviceStatus.dwControlsAccepted = 0;
else
serviceStatus.dwControlsAccepted =
SERVICE_ACCEPT_STOP |
SERVICE_ACCEPT_PAUSE_CONTINUE |
SERVICE_ACCEPT_SHUTDOWN;

// if a specific exit code is defines, set up
// the win32 exit code properly
if (dwServiceSpecificExitCode == 0)
serviceStatus.dwWin32ExitCode =dwWin32ExitCode;
else
serviceStatus.dwWin32ExitCode =	ERROR_SERVICE_SPECIFIC_ERROR;
serviceStatus.dwServiceSpecificExitCode =dwServiceSpecificExitCode;

serviceStatus.dwCheckPoint = dwCheckPoint;
serviceStatus.dwWaitHint = dwWaitHint;

// Pass the status record to the SCM
//SERVICE_STATUS_HANDLE serviceStatusHandle;
success = SetServiceStatus (hStatus,&serviceStatus);
if (!success)
{
StopService();
}
return success;
}
//
VOID terminate(DWORD error)
{
// if terminateEvent has been created, close it.
if (terminateEvent)
CloseHandle(terminateEvent);

// Send a message to the scm to tell about
// stop age
if (hStatus)
SendStatusToSCM(SERVICE_STOPPED, error,
0, 0, 0);

// If the thread has started kill it off
if (threadHandle)
CloseHandle(threadHandle);

// Do not need to close serviceStatusHandle
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: