编纂windows服务程序

2012-11-02 08:54 (分类:微机程序)

     
windows服务是一个运行在后台并落到实处勿需用户交互的任务的控制台程序,对于隐藏程序有很大协理。

      用了几天时间概括了编写windows服务程序的概况,上边用伪码记录一下。

      

//七个全局变量
SERVICE_STATUS_HANDLE StatusHandle
SERVICE_STATUS m_ServiceStatus

void main()

//一个程序可能带有若干个劳务。每一个服务都必须列于专门的摊派表中
SERVICE_TABLE_ENTRY ServiceTable[2]; //结构类型的数组,
ServiceTable[0].lpServiceName = “MemoryStatus”; //服务名
ServiceTable[0].lpServiceProc =
(LPSERVICE_MAIN_FUNCTION)ServiceMain; //服务主函数  
ServiceTable[1].lpServiceName = NULL;
//数组最后一个分子组默许都为NULL
ServiceTable[1].lpServiceProc = NULL;    

// 启动服务的决定分派机线程,
负责把程序主线程连接到服务控制管理程序SCM,布告服务控制程序//服务正在实践,并提供函数地址;为每一个传递到它的数组中的非空元素爆发一个新的线程,每一//个经过始起实施由数组元素中的指明的ServiceMain函数;SCM启动一个服务程序之后,它会等待该/*先后的主线程去调StartServiceCtrlDispatcher。借使不行函数在两分钟内没有被调用,SCM将会以为这些服务有难题,并调用TerminateProcess去杀死这几个历程。那就须要你的主线程要尽可能快的调用StartServiceCtrlDispatcher,开端启动服务解析*/

StartServiceCtrlDispatcher(ServiceTable); 

}

ServiceMain 函数
该函数是劳动的入口点。它运行在一个单身的线程当中,那么些线程是由控制分派器创立的。瑟维斯Main
应该尽量早早为劳动登记控制电脑

void WINAPI ServiceMain()
{
//指定服务特色和其眼前境况来起先化 ServiceStatus 结构
m_ServiceStatus.dwServiceType=SERVICE_WIN32_OWN_PROCESS;
//提醒服务类型,创造 Win32 服务。赋值 SERVICE_WIN32;
m_ServiceStatus.dwCurrentState=SERVICE_START_PENDING;
//指定服务的此时此刻场所。因为劳动的先导化在那里没有做到,所以那边
状态为SERVICE_START_PENDING;
m_ServiceStatus.dwControlsAccepted=SERVICE_ACCEPT_STOP|SERVICE_ACCEPT_SHUTDOWN
//这几个域通告 SCM 服务接受哪个域,截止,关机为止

m_瑟维斯Status.dwWin32ExitCode=0; //是同意服务报告错误的要紧
m_ServiceStatus.dwServiceSpecificExitCode=0; //一般不关怀,设为0

m_瑟维斯Status.dwCheckPoint=0;
//是一个劳动用来告诉它方今的风云进展情况的
m_ServiceStatus.dwWaitHint=0; //一般不关注,设为0

//使用API函数RegisterServiceCtrlHandler()设置服务控制管理器SCM的劳动控制处理函数
//ServiceMain
应该尽量早早为劳动注册控制电脑(尽量1秒之内)。那要通过调用
//Register瑟维斯CtrlHadler
函数来促成;调用RegisterServiceCtrlHandler函数去布告SCM
//它的CtrlHandler回调函数的地方
//SERVICE_STATUS_HANDLE StatusHandle是一个全局变量,当必要改变状态时
//SetServiceStatus()用它来标识一个服务。

SERVICE_STATUS_HANDLE StatusHandle
StatusHandle =RegisterServiceCtrlHadler(“system”,serviceCtrlHandler)
//函数名称 //控制函数CtrlHandler函数地址

//RegisterServiceCtrlHandler再次回到一个SERVICE_STATUS_HANDLE,这是一个32位的句柄。SCM用
//它来唯一确定这一个服务。当这几个服务必要把它立时的图景报告给SCM的时候,就不能不把那些句柄传//给要求它的Win32函数

//在RegisterServiceCtrlHandler函数重返后,ServiceMain线程要及时告诉SCM服务正在持续开始//化。具体的措施是透过调用SetServiceStatus函数传递SERVICE_STATUS数据结构。
//通过调用 SetServiceStatus 函数,用 hStatus 向 SCM 报告服务的气象。

//一旦服务被完全开端化,就相应再度早先化SERVICE_STATUS结构的成员,更改dwCurrentState
//为SERVICE_RUNNING,然后把dwCheckPoint和dwWaitHint都改为0,将状态及时通报给服务控制管
//理器SCM,使用一个API函数SetServiceStatus()来促成这一目的

m_ServiceStatus.dwCurrentState=SERVICE_START_RUNNING;
m_ServiceStatus.dwCheckPoint=0;
m_ServiceStatus.dwWaitHint=0;

SetServiceStatus(StatusHandle,m_ServiceStatus )
//服务的句柄 //SERVICE_STATUS结构的地点

door();启动后门程序
return;

}

void WINAPI ServiceCtrlHandler(DWORD dwControl) //服务控制函数
{
switch (dwControl)
{

case SERVICE_CONTROL_PAUSE:
servicestatus.dwCurrentState = SERVICE_PAUSE_PENDING;
// TODO: add code to set dwCheckPoint & dwWaitHint
// This value need to try a lot to confirm 
// …
SetServiceStatus(servicestatushandle, &servicestatus);
// TODO: add code to pause the service
// not called in this service
// …
servicestatus.dwCurrentState = SERVICE_PAUSED;
// TODO: add code to set dwCheckPoint & dwWaitHint to 0
break;
case SERVICE_CONTROL_CONTINUE:
servicestatus.dwCurrentState = SERVICE_CONTINUE_PENDING;
// TODO: add code to set dwCheckPoint & dwWaitHint
SetServiceStatus(servicestatushandle, &servicestatus);
// TODO: add code to unpause the service
// not called in this service
// …
servicestatus.dwCurrentState = SERVICE_RUNNING;
// TODO: add code to set dwCheckPoint & dwWaitHint to 0
break;
case SERVICE_CONTROL_STOP:
servicestatus.dwCurrentState = SERVICE_STOP_PENDING;
// TODO: add code to set dwCheckPoint & dwWaitHint
SetServiceStatus(servicestatushandle, &servicestatus);
// TODO: add code to stop the service
Stop();
servicestatus.dwCurrentState = SERVICE_STOPPED;
// TODO: add code to set dwCheckPoint & dwWaitHint to 0
break;
case SERVICE_CONTROL_SHUTDOWN:
// TODO: add code for system shutdown
// as quick as possible
break;
case SERVICE_CONTROL_INTERROGATE:
// TODO: add code to set the service status
// …
servicestatus.dwCurrentState = SERVICE_RUNNING;
break;
}
SetServiceStatus(servicestatushandle, &servicestatus);
}

//安装服务函数 

//OpenSCManager函数是在创建一个服务目的(CreateService),并且把它进入到中要调用的API
//打开服务管理数据库

SC_HANDLE schService;
SC_HANDLE schSCManager;
schSCManager=OpenSCManager(
NULL, //本地总结机
NULL, //默许的数据库
SC_MANAGER_ALL_ACCESS //要求具有的访问权
);

//成立进度

CreateService(
SC_HANDLE
hSCManager,//服务控制管理程序维护的登记数据库的句柄,由系统函数
OpenSCManager 再次回到 
LPCTSTR lp瑟维斯Name, //以NULL
结尾的服务名,用于成立登记数据库中的关键字
LPCTSTR lpDisplayName, //以NULL 结尾的劳动名,用于用户界面标识服务
DWORD dwDesiredAccess, //指定服务重回类型
DWORD dwServiceType, //指定服务类型
DWORD dwStartType, //指定曾几何时起步服务
DWORD dwErrorControl, //指定服务启动败北的不得了程度
LPCTSTR lpBinaryPathName, //指定服务程序二进制文件的不二法门
LPCTSTR lpLoadOrderGroup, //指定顺序装入的劳动组名
LPDWORD lpdwTagId, //忽略,NULL
LPCTSTR lpDependencies, //指定启动该服务前必须先启动的劳动或服务组
LPCTSTR lpServiceStartName, //以NULL
结尾的字符串,指定服务帐号。如是NULL,则表示使用 LocalSystem 帐号 
LPCTSTR lpPassword //以NULL
结尾的字符串,指定相应的口令。为NULL表示无口。
但使用LocalSystem时填NULL

schService=CreateService(
schSCManager, //服务管理数据库句柄
TEXT(SZSERVICENAME), //服务名
TEXT(SZAPPNAME), //用于呈现服务的标识
SERVICE_ALL_ACCESS, //响应所有的拜会请求
SERVICE_WIN32_OWN_PROCESS, //服务类型
SERVICE_DEMAND_START, //启动类型
SERVICE_ERROR_NORMAL, //错误决定项目
szPath, //服务程序磁盘文件的途径
NULL, //服务不属于任何组
NULL, //没有tag标识符
NULL, //启动服务所依赖的服务或服务组,那里仅仅是一个空字符串
NULL, //LocalSystem 帐号
NULL);

剔除服务时调用
DeleteService;它唯有一个参数(服务句柄)。我们可分四步成功
1)、打开SCM句柄。
2)、打开要刨除的服务。
3)、检查当前劳动的情景确保服务业已终止。
4)、删除服务并关闭所有打开的句柄。上边是一段删除服务的顺序。

SC_HANDLE Service,scm;
SERVICE_STATUS status;
BOOL success;

scm = OpenSCManager(NULL,NULL,SC_MANAGER_ENUMERATE_SERVICE);
//打开SCM句柄。

//打开要删减的劳务
Service = OpenService(scm,pszServiceName,SERVICE_ALL_ACCESS|DELETE);

//检查当前服务的情事确保服务一度告一段落
if (!Service){

cout<<“OpenService ERROR:”<<GetLastError()<<endl;
CloseServiceHandle(Service);
CloseServiceHandle(scm);
return false;
}

success = QueryServiceStatus(Service,&status);
if (!success){

cout<<“QueryServiceStatus
ERROR:”<<GetLastError()<<endl;
CloseServiceHandle(Service);
CloseServiceHandle(scm);
return false;
}

if (status.dwCurrentState!=SERVICE_STOPPED)
{
success = ControlService(Service,SERVICE_CONTROL_STOP,&status);
if (!success){
cout<<“ControlService ERROR:”<<GetLastError()<<endl;
CloseServiceHandle(Service);
CloseServiceHandle(scm);
return false;
}
}
//删除服务
success = DeleteService(Service);

if (!success){

cout<<“DeleteService ERROR:”<<GetLastError()<<endl;

CloseServiceHandle(Service);
CloseServiceHandle(scm);
return false;
}
bb//关闭所有打开的句柄
CloseServiceHandle(Service);
CloseServiceHandle(scm);
return true;

 

相关文章