您的位置:首页 > 其它

windows 服务程序学习心得

2012-11-30 10:49 399 查看
1.服务首先是一个win32的可执行程序,它受到操作系统的优待,伴随着操作系统启动而启动,关闭而关闭。

2.服务绝不需要用户界面。大多是的服务都是运行在服务器上。服务通常以控制台程序被编写,函数的入口是main(),不是winmain()。

3想要写一个服务,就必须熟悉Win NT/2000的安全机制,在上述操作系统之中,所有安全都是基于用户的。如果一个进程正在一个用户帐号下执行,那么这个进程就同时拥有这个用户所能拥有的一切访问权限,不论是在本机还是网络。系统帐号则是一个特殊的账号,它用来标识系统本身,而且运行在这个帐号下的任何进程都拥有系统上的所有访问权限,但是系统帐号不能在域上使用,无法访问网络资。当一个进程被产生的时候,它都是执行在一个用户的上下文(context)。服务也是Win32可执行程序,它也需要执行在一个context,通常服务都是在系统账号下运行,但是也可以根据情况选择让它运行在一个用户账号下,也就会因此获得相应的访问资源的权限。

4.服务程序通常编写成控制台类型的应用程序,总的来说,一个遵守服务控制管理程序接口要求的程序

包含下面三个函数:

1、服务程序主函数(main):调用系统函数 StartServiceCtrlDispatcher连接程序主线程到服务控制管理程序。

2、服务入口点函数(ServiceMain):执行服务初始化任务,同时执行多个服务的服务进程有多个服务入口函数。

3、控制服务处理程序函数(Handler):在服务程序收到控制请求时由控制分发线程引用。

5另外在系统运行此服务之前需要安装登记服务程序:installService函数。删除服务程序则需要先删除服务安装登记:removeService
函数。
服务程序主函数

int _tmain(int argc, _TCHAR* argv[])
{
if((argc==2)&&(*argv[1]=='-'))
{
if(_tcscmp(_T("install"),argv[1]+1)==0)
{
installService();
}
else if(_tcscmp(_T("remove"),argv[1]+1)==0)
{
removeService();
}
}
//如果未能和上面的如何参数匹配,则可能是服务控制管理程序来启动该程序。立即调用
//StartServiceCtrlDispatcher 函数。
printf("%s - install to install the service \n",SZAPPNAME);
printf("%s - remove to remove the service \n",SZAPPNAME);
printf("%s - debug to debug the service \n",SZAPPNAME);
printf("\n StartServiceCtrlDispatcher being called.\n");
printf("This may take several seconds.Please wait.\n");

SERVICE_TABLE_ENTRY dispatchTable[]={
{TEXT(SZSERVICENAME),(LPSERVICE_MAIN_FUNCTION)Service_Main},
{NULL,NULL}
};
bool ret=StartServiceCtrlDispatcher(dispatchTable);
if(!ret)
AddToMessageLog(TEXT("StartServiceCtrlDispatcher failed."));
else
AddToMessageLog(TEXT("StartServiceCtrlDispatcher OK."));
return 0;

}


服务入口函数

//服务入口点函数
void  WINAPI  Service_Main(DWORD dwArgc, LPTSTR *lpszArgv)
{
//初始化 SERVICE_STATUS 结构中的成员
ssStatus.dwServiceType=SERVICE_WIN32_OWN_PROCESS;
ssStatus.dwControlsAccepted=SERVICE_ACCEPT_STOP;
ssStatus.dwCurrentState= SERVICE_START_PENDING;
ssStatus.dwServiceSpecificExitCode=0;
ssStatus.dwCheckPoint=0;
ssStatus.dwWin32ExitCode=0;
ssStatus.dwWaitHint=0;
SetServiceStatus(sshStatusHandle,&ssStatus);

//注册服务控制处理函数
sshStatusHandle=RegisterServiceCtrlHandler(TEXT(SZSERVICENAME),Service_Ctrl);
//如果注册失败
if(!sshStatusHandle)
{
goto cleanup;
return;
}
//更新服务状态
if(!ReportStatusToSCMgr(
SERVICE_RUNNING,//服务状态,The service is starting.
NO_ERROR,            //退出码
3000))                   //等待时间
goto cleanup;        //更新服务状态失败则转向 cleanup
ServiceStart(dwArgc,lpszArgv);//具体的服务程序
return;
cleanup:
//把服务状态更新为 SERVICE_STOPPED,并退出。
if(sshStatusHandle)
(void)ReportStatusToSCMgr(SERVICE_STOPPED,dwErr,0);

}


控制处理函数

//控制处理程序函数

void WINAPI Service_Ctrl(DWORD dwCtrlCode)

{
//处理控制请求码
switch(dwCtrlCode)
{
//先更新服务状态为 SERVICDE_STOP_PENDING,再停止服务。
case SERVICE_CONTROL_STOP:
ReportStatusToSCMgr(SERVICE_STOP_PENDING,NO_ERROR,500);
//  ServiceStop();     //由具体的服务程序实现
ssStatus.dwCurrentState=SERVICE_STOPPED;
return;
//暂停服务
case SERVICE_CONTROL_PAUSE:
//ReportStatusToSCMgr(SERVICE_STOP_PENDING,NO_ERROR,500);
// ServicePause();    //由具体的服务程序实现
ssStatus.dwCurrentState=SERVICE_PAUSED;
return;
//继续服务
case SERVICE_CONTROL_CONTINUE:
ReportStatusToSCMgr(SERVICE_STOP_PENDING,NO_ERROR,500);
//  ServiceContinue(); //由具体的服务程序实现
ssStatus.dwCurrentState=SERVICE_RUNNING;
return;
//更新服务状态
case SERVICE_CONTROL_INTERROGATE:
break;
//无效控制码
default:
break;
}
ReportStatusToSCMgr(ssStatus.dwCurrentState,NO_ERROR,0);
}


安装函数

//安装服务程序

void installService()
{
SC_HANDLE schService;
SC_HANDLE schSCManager;
TCHAR szPath[512];
//得到程序磁盘文件的路径
if(GetModuleFileName(NULL,szPath,512)==0)
{
_tprintf(TEXT("Unable to install %s - %s /n"),
TEXT(SZAPPNAME),
GetLastError());//@1获取调用函数返回的最后错误码
return;
}
//打开服务管理数据库
schSCManager=OpenSCManager(
NULL,    //本地计算机
NULL,    //默认的数据库
SC_MANAGER_ALL_ACCESS  //要求所有的访问权
);
if(schSCManager)
{
//登记服务程序
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);
if(schService)
{
_tprintf(TEXT("%s installed. \n"),TEXT(SZAPPNAME));
CloseServiceHandle(schService);
}
else
{
_tprintf(TEXT("CreateService failed - %s \n"),GetLastError());
}
CloseServiceHandle(schSCManager);
}
else
_tprintf(TEXT("OpenSCManager failed - %s \n"),GetLastError());

}


卸载函数

/*停止和安装已安装的服务*/
void removeService()
{
SC_HANDLE	schService;
SC_HANDLE	schSCManager;
//打开服务管理数据库
schSCManager=OpenSCManager(
NULL,	//本地计算机
NULL,	//默认的数据库
SC_MANAGER_ALL_ACCESS	//要求所有的访问权
);
if(schSCManager)
{
//获取服务程序句柄
schService=OpenService(
schSCManager,			//服务管理数据库句柄
TEXT(SZSERVICENAME),	//服务名
SERVICE_ALL_ACCESS		//响应所有的访问请求
);
if(schService)
{
//试图停止服务
if(ControlService(
schService,				//服务程序句柄
SERVICE_CONTROL_STOP,	//停止服务请求码
&ssStatus				//接收最后的服务状态信息
))
{
_tprintf(TEXT("Stopping %s."),TEXT(SZAPPNAME));
Sleep(1000);

//等待服务停止
//
while(QueryServiceStatus(schService,&ssStatus))
{
if(SERVICE_STOP_PENDING==ssStatus.dwCurrentState)
{
_tprintf(TEXT("."));
Sleep(1000);
}
else
break;
}
if(SERVICE_STOPPED==ssStatus.dwCurrentState)
_tprintf(TEXT("\n %s stopped. \n"),TEXT(SZAPPNAME));
else
_tprintf(TEXT("\n %s failed to stopp. \n"),TEXT(SZAPPNAME));
}
//删除已安装的服务程序安装
if(DeleteService(schService))
_tprintf(TEXT("%s removed. \n"),TEXT(SZAPPNAME));
else
_tprintf(TEXT("DeleteService failed - %s. \n"), GetLastError());
CloseServiceHandle(schService);
}
else
_tprintf(TEXT("OpenService failed - %s \n"),GetLastError());
CloseServiceHandle(schSCManager);
}
else
_tprintf(TEXT("OpenSCManager failed - %s \n"),GetLastError());
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: