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
函数。
服务程序主函数
服务入口函数
控制处理函数
安装函数
卸载函数
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()); }
相关文章推荐
- C编写Windows服务程序学习
- 一个windows服务程序的编写过程及心得(更新中)
- Windows学习心得【程序中的击中测试】
- WCF学习之旅—WCF服务的Windows 服务程序寄宿(十一)
- 将Java程序变成Windows系统服务-Java基础-Java-编程开发
- 从零开始,学习windows编程(7)--不使用CRT库的程序
- Hadoop学习笔记(九):如何在windows上使用eclipse远程连接hadoop进行程序开发
- c#开发的程序安装时动态指定windows服务名称
- WCF学习心得------(三)配置服务
- 《VC++深入详解》学习笔记[1]——第1章 Windows程序内部运行机制
- C#编写Windows服务程序图文教程
- Perl学习日志(1) — Windows下怎么运行Perl程序显示输出"hello,world"语句
- C++学习笔记1(Windows程序运行原理及程序编写流程)
- .Net Windows服务程序中获取安装程序所在目录
- C#Windows 服务制作安装删除. 用户注销后,程序继续运行
- windows服务程序中创建用户进程
- JAVA学习中的心得和小程序
- C#判断程序是由Windows服务启动还是用户启动
- Oracle学习.Windows 命令行 启动ORACLE服务与实例
- C# 自动程序 windows 无法启动 XXXX 服务 错误5 拒绝访问