当前位置:   article > 正文

WINDOWS服务开发_startservicectrldispatcher失败

startservicectrldispatcher失败

1.查看系统日志:控制面板\所有控制面板项\管理工具\计算机管理

2.windows服务的实现:

资料:msdn->system service->services. http://msdn.microsoft.com/en-us/library/windows/desktop/ms685141(v=vs.85).aspx

demo:http://msdn.microsoft.com/en-us/library/windows/desktop/bb540476(v=vs.85).aspx

/
删除Windows服务  

  现在的流氓软件,越来越多把自己注册为一个服务。一般会把非Windows系统的服务以023的方式列出来,如下面这段:   

  O23 - 未知 - Service: BKMARKS [提供传输协议的数据安全保护机制,有效维护数据传输中的安全及完整。] - C:WINDOWSSYSTEM32RUNDLL.EXE   

  O23 - 未知 - Service: ewido anti-spyware 4.0 guard [ewido anti-spyware 4.0 guard] - D:Program Filesewido anti-spyware 4.0guard.exe   

  O23 - 未知 - Service: KSD2Service [KSD2Service] - C:WINDOWSsystem32SVCH0ST.exe

  对于这些流氓软件,需要删除相关的.exe文件,使它不能再运行,或者直接清除这个服务本身,使计算机重启的时候,它不会再启动。   

  删除的办法有两个:   

  办法一: 用sc.exe这个Windows命令   

  点击开始菜单 -》 所有程序 -》 附件 -》 命令行程序,右键菜单中选择“以管理员方式运行”。


  

  这样,就用管理员身份打开了一个命令行程序,输入 sc 加上参数就可以了,使用办法很简单:

  sc delete "服务名"(如果服务名中间有空格,就需要前后加引号)   

  如针对上面的: sc delete KSD2Service  

  sc 命令的详解,参看本文下方,Windows7之家/Vista之家已经帮您整理。  

  方法二:直接进行注册表编辑(不推荐)   

  打开注册表编辑器,找到下面的键值:   

  HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services一般服务会以相同的名字在这里显示一个主健,直接删除相关的键值便可。

特殊情况    
  1、如果服务显示的是rundll32.exe,并且这个文件是位于system32目录下,那么就不能删除这个rundll32.exe文件,它是Windows系统的文件。这时只要清除相关的服务就可以了。   
  2、如果一个服务删除了马上又自动建立了,说明后台有进程在监视、保护。需要先在进程管理器中杀掉相应的进程,或者启动后按F8,到Win7/Vista安全模式下删除。   
  // 附录:SC 命令行程序 参数详解 ///   
  描述: 
   SC 是用于与服务控制管理器和服务进行通信的命令行程序。 
  用法: 
   sc [command] [service name] ...   
   选项 的格式为 "\\ServerName"
   键入 "sc [command]" 可以获得有关命令的进一步帮助 
   命令: 
   query-----------查询服务的状态, 
   或枚举服务类型的状态。 
   queryex---------查询服务的扩展状态, 
   或枚举服务类型的状态。 
   start-----------启动服务。 
   pause-----------向服务发送 PAUSE 控制请求。 
   interrogate-----向服务发送 INTERROGATE 控制请求。 
   continue--------向服务发送 CONTINUE 控制请求。 
   stop------------向服务发送 STOP 请求。 
   config----------更改服务的配置(永久)。 
   description-----更改服务的描述。 
   failure---------更改服务失败时执行的操作。 
   failureflag-----更改服务的失败操作标志。 
   sidtype---------更改服务的服务 SID 类型。 
   privs-----------更改服务的所需权限。 
   qc--------------查询服务的配置信息。 
   qdescription----查询服务的描述。 
   qfailure--------查询失败时服务执行的操作。 
   qfailureflag----查询服务的失败操作标志。 
   qsidtype--------查询服务的服务 SID 类型。 
   qprivs----------查询服务的所需权限。 
   qtriggerinfo----查询服务的触发器参数。 
   qpreferrednode--查询首选的服务 NUMA 节点。 
   delete----------(从注册表)删除服务。 
   create----------创建服务(将其添加到注册表)。 
   control---------向服务发送控制。 
   sdshow----------显示服务的安全描述符。 
   sdset-----------设置服务的安全描述符。 
   showsid---------显示相应于假定名称的 SID 字符串。 
   triggerinfo-----配置服务的触发器参数。 
   preferrednode---设置首选的服务 NUMA 节点。 
   GetDisplayName--获取服务的 DisplayName 
   GetKeyName------获取服务的 ServiceKeyName。 
   EnumDepend------枚举服务的依存关系。   
   下列命令不要求服务名称: 
   sc 
   boot------------(ok   bad) 指示是否将上一次启动保存为 
   最近一次已知的正确启动配置 
   Lock------------锁定服务数据库 
   QueryLock-------查询 SCManager 数据库的 LockStatus 
  示例: 
   sc start MyService   
  QUERY 和 QUERYEX 选项: 
   如果查询命令带服务名称,将返回 
   该服务的状态。其他选项不适合这种 
   情况。如果查询命令不带参数或 
   带下列选项之一,将枚举此服务。 
   type= 要枚举的服务的类型(driver, service, all) 
   默认 = service) 
   state= 要枚举的服务的状态 (inactive, all) 
   (默认 = active) 
   bufsize= 枚举缓冲区的大小(以字节计) 
   (默认 = 4096) 
   ri= 开始枚举的恢复索引号 
   (默认 = 0) 
   group= 要枚举的服务组 
   (默认 = all groups)   
  语法示例 
  sc query - 枚举活动服务和驱动程序的状态 
  sc query eventlog - 显示 eventlog 服务的状态 
  sc queryex eventlog - 显示 eventlog 服务的扩展状态 
  sc query type= driver - 仅枚举活动驱动程序 
  sc query type= service - 仅枚举 Win32 服务 
  sc query state= all - 枚举所有服务和驱动程序 
  sc query bufsize= 50 - 枚举缓冲区为 50 字节 
  sc query ri= 14 - 枚举时恢复索引 = 14 
  sc queryex group= "" - 枚举不在组内的活动服务 
  sc query type= interact - 枚举所有不活动服务 
  sc query type= driver group= NDIS - 枚举所有 NDIS 驱动程序

创建windows服务
在2000/XP等基于NT 的操作系统中,有一个服务管理器,它管理的后台进程被称为 service。
服务是一种应用程序类型,它在后台运行,与 UNIX 后台应用程序类似。服务应用程序通常可以
在本地和通过网络为用户提供一些功能,例如客户端/服务器应用程序、Web 服务器、数据库服
务器以及其他基于服务器的应用程序。
    后台服务 程序是在后台悄悄运行的。我们通过将自己的程序登记为服务,可以使自己的程序不出现
在任务管理器中,并且随系统启动而最先运行,随系统关闭而最后停止。
    
     服务控制管理器是一个RPC 服务器,它显露了一组应用编程接口,程序员可以方便的编写程序来配置
服务和控制远程服务器中服务程序。
     服务程序通常编写成控制台类型的应用程序,总的来说,一个遵守服务控制管理程序接口要求的程序
包含下面三个函数:
1。服务程序主函数(main):调用系统函数 StartServiceCtrlDispatcher 连接程序主线程到服务控制管理程序。
2。服务入口点函数(ServiceMain):执行服务初始化任务,同时执行多个服务的服务进程有多个服务入口函数。
3。控制服务处理程序函数(Handler):在服务程序收到控制请求时由控制分发线程引用。(此处是Service_Ctrl)。
 另外在系统运行此服务之前需要安装登记服务程序:installService 函数。删除服务程序则需要先删除服务安装登记:removeService 函数。
 
服务类型:
类型
说明
SERVICE_FILE_SYSTEM_DRIVER=2
文件系统驱动服务。
SERVICE_KERNEL_DRIVER=1
驱动服务。
SERVICE_WIN32_OWN_PROCESS=16
独占一个进程的服务。
SERVICE_WIN32_SHARE_PROCESS=32
与其他服务共享一个进程的服务。
新建WIN32控制台程序, 其源文件名为service.cpp 。我用的开发工具是VC++.NET。
 
1.服务程序主函数
    服务控制管理程序启动服务程序后,等待服务程序主函数调用系统函StartServiceCtrlDispatcher。一个SERVICE_WIN32_OWN_PROCESS 类型的服务应该立即调用 StartServiceCtrlDispatcher 函数,可以在服务启动后让服务入口点函数完成初始化工作。对于 SERVICE_WIN32_OWN_PROCESS 类型的服务和程序中所有服务共同的初始化工作可以在主函数中完成,但不要超过30秒。否则必须建立另外的线程完成这些共同的初始化工作,从而保证服务程序主函数能及时地调用 StartServiceCtrlDispatcher 函数。
 
 
主函数处理了三中命令行参数:- install,- remove,- debug,分别用于安装,删除和调试服务程序。如果不带参数运行,则认为是服务控制管理出现启动该服务程序。参数不正确则给出提示信息。
 
StartServiceCtrlDispatcher 函数负责把程序主线程连接到服务控制管理程序。具体描述如下:
BOOL StartServiceCtrlDispatcher(
 const LPSERVICE_TABLE_ENTRY lpServiceTable);
lpServiceStartTable 指向 SERVICE_TABLE_ENTRY 结构类型的数组,他包含了调用进程所提供的每个服务的入口函数和字符串名。表中的最后一个元素必须为 NULL,指明入口表结束。SERVICE_TABLE_ENTRY 结构具体描述如下:
 
typedef struct _SERVICE_TABLE_ENTRY { LPTSTR lpServiceName; LPSERVICE_MAIN_FUNCTION lpServiceProc;
} SERVICE_TABLE_ENTRY, *LPSERVICE_TABLE_ENTRY;
 
lpServiceName 是一个以 NULL 结尾的字符串,标识服务名。如果是 SERVICE_WIN32_OWN_PROCESS 类型的服务,这个字符串会被忽略。
lpServiceProc 指向服务入口点函数。
 
 
//服务程序主函数。
#include  "stdafx.h"
#include  "Windows.h"
#define  SZAPPNAME      "serverSample"    //服务程序名
#define  SZSERVICENAME "serviceSample"   //标识服务的内部名
 
//内部变量
bool                    bDebugServer=false;
SERVICE_STATUS              ssStatus;
SERVICE_STATUS_HANDLE sshStatusHandle;
DWORD                       dwErr=0;
TCHAR                       szErr[256];
 
//下面的函数由程序实现
void  WINAPI Service_Main(DWORD dwArgc, LPTSTR *lpszArgv);
void  WINAPI Service_Ctrl(DWORD dwCtrlCode);
void  installService();
void  removeService();
void  debugService(int argc,char** argv);
bool  ReportStatusToSCMgr(DWORD dwCurrentState,DWORD dwWin32ExitCode,DWORD dwWaitHint);
void  AddToMessageLog(LPTSTR lpszMsg);
 
int  _tmain(int argc, _TCHAR* argv[])
{   
     SERVICE_TABLE_ENTRY dispatchTable[]=
     {
         {TEXT(SZSERVICENAME),(LPSERVICE_MAIN_FUNCTION)Service_Main},
         { NULL,NULL}
     };
     if((argc>1)&&((*argv[1]=='-')||(argv[1]=="/")))
     {
         if(_stricmp("install",argv[1]+1)==0)
         {
              installService();
         }
         elseif(_stricmp("remove",argv[1]+1)==0)
         {
              removeService();
         }
         elseif(_stricmp("debug",argv[1]+1)==0)
         {
              bDebugServer=true;
              debugService(argc,argv);
         }
         else
         {        //如果未能和上面的如何参数匹配,则可能是服务控制管理程序来启动该程序。立即调用
                   //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");
              if(!StartServiceCtrlDispatcher(dispatchTable))
                   AddToMessageLog(TEXT("StartServiceCtrlDispatcher failed."));
              else
                   AddToMessageLog(TEXT("StartServiceCtrlDispatcher OK."));
         }
         exit(0);
     }
     return 0;
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

2.服务入口点函数
 
服务入口点函数 service_main 首先调用系统函数 RegisterServiceCtrlHandler 注册服务控制处理函数 service_ctrl, 然后调用 ReportStatusToSCMgr 函数,它通过系统函数 SetServiceStatus 更新服务的状态,然后调用特定的服务初始化 入口函数 ServiceStart 完成具体的初始化工作。
 
 

//服务入口点函数
void  ServiceStart(DWORD dwArgc,LPTSTR* lpszArgv);//具体服务的初始化入口函数
  void  WINAPI Service_Main(DWORD dwArgc, LPTSTR *lpszArgv)
{
     //注册服务控制处理函数
     sshStatusHandle=RegisterServiceCtrlHandler(TEXT(SZSERVICENAME),Service_Ctrl);
     //如果注册失败
     if(!sshStatusHandle)
     {
         goto cleanup;
         return;
     }
     //初始化 SERVICE_STATUS 结构中的成员
     ssStatus.dwServiceType=SERVICE_WIN32_OWN_PROCESS;
     ssStatus.dwServiceSpecificExitCode=0;
     //更新服务状态
     if(!ReportStatusToSCMgr(
         SERVICE_START_PENDING,//服务状态,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);
}

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3.控制处理程序函数
 
 
3.控制处理程序函数

 

函数 Service_Ctrl 是服务的控制处理程序函数,由主函数线程的控制分发程序引用。在处理控制请求码时,应该在确定的时间间隔内更新服务状态检查点,避免发生服务不能响应的错误。
 
 

//控制处理程序函数
void  WINAPI Service_Ctrl(DWORD dwCtrlCode)
{
     //处理控制请求码
     switch(dwCtrlCode)
     {
         //先更新服务状态为 SERVICDE_STOP_PENDING,再停止服务。
     case SERVICE_CONTROL_STOP:
         ReportStatusToSCMgr(SERVICE_STOP_PENDING,NO_ERROR,500);
         ServiceStop();     //由具体的服务程序实现
         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);
}

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
除了系统定义的五种控制码外(还有一种是:SERVICE_CONTROL_SHUTDOWN),用户还可自定义控制码,其取值范围是128-255。用户可以通过控制面板中的服务项向特定服务程序的控制处理函数发送控制码,程序员可以调用系统函数 ControlService 直接向服务程序的控制处理函数发送控制码。其函数原型如下:
 
BOOL ControlService(
 SC_HANDLE hService,
 DWORD dwControl,
 LPSERVICE_STATUS lpServiceStatus
);
hService :函数 OpenService or CreateService 返回的服务程序句柄。
dwControl :控制码,不能是SERVICE_CONTROL_SHUTDOWN。
lpServiceStatus:返回最后收到的服务状态信息。
4.安装服务程序
 
    每个已安装服务程序在 HKEY_LOCAL_MACHINE/SYSTE/CurrentControlSet/Services 下都有一个服务名的关键字,程序员可以调用系统函数 CreateService 安装服务程序,并指定服务类型,服务名等。这个函数创建一个服务对象,并将其增加到相关的服务控制管理器数据库中。
下面是函数原型:
 
SC_HANDLE CreateService(
 SC_HANDLE hSCManager, //服务控制管理程序维护的登记数据库的句柄,由系统函数OpenSCManager 返回
 LPCTSTR lpServiceName, //以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
);
 
     对于一个已安装的服务程序,可以调用系统函数 OpenService 来获取服务程序的句柄
下面是其函数原型:
SC_HANDLE OpenService(
 SC_HANDLE hSCManager,
 LPCTSTR lpServiceName,
 DWORD dwDesiredAccess
);
 
hSCManager :服务控制管理程序微服的登记数据库的句柄。由函数 OpenSCManager function 返回 这个句柄。
lpServiceName :将要打开的以NULL 结尾的服务程序的名字,和 CreateService 中的 lpServiceName 相对应。
dwDesiredAccess :指定服务的访问类型。服务响应请求时,首先检查访问类型。
用CreateService 或OpenService 打开的服务程序句柄使用完毕后必须用CloseServiceHandle 关闭。
OpenSCManager打开的服务管理数据库句柄也必须用它来关闭。
 
 
//安装服务程序
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());
}
5.停止和删除已安装的服务程序
 
//停止和删除已安装的服务程序
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());
}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
      在编译程序的时候,我们会发觉ServiceStop();ServicePause();ServiceContinue();等三个函数没有具体实现,这对于理解此文的人来说应该不难编写,在此我可以给点文档内的参考:声明     SetTheServiceStatus()函数,
//
   //  SetTheServiceStatus -   This just wraps up SetServiceStatus.
   // 
   void SetTheServiceStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode,
                            DWORD dwCheckPoint,   DWORD dwWaitHint)
   {
      SERVICE_STATUS ss;  // Current status of the service.

      // 
      // Disable control requests until the service is started.
      // 
      if (dwCurrentState == SERVICE_START_PENDING)
         ss.dwControlsAccepted = 0;
      else
         ss.dwControlsAccepted =
                       SERVICE_ACCEPT_STOP|SERVICE_ACCEPT_SHUTDOWN;
                       // Other flags include SERVICE_ACCEPT_PAUSE_CONTINUE
                       // and SERVICE_ACCEPT_SHUTDOWN.

      // Initialize ss structure.
      ss.dwServiceType             = SERVICE_WIN32_OWN_PROCESS;
      ss.dwServiceSpecificExitCode = 0;
      ss.dwCurrentState            = dwCurrentState;
      ss.dwWin32ExitCode           = dwWin32ExitCode;
      ss.dwCheckPoint              = dwCheckPoint;
      ss.dwWaitHint                = dwWaitHint;

      // Send status of the service to the Service Controller.
      if (!SetServiceStatus(ssh, &ss))
         ErrorStopService(TEXT("SetServiceStatus"));
   }
    然后用如下的方式来调用函数来实现源程序中缺少的功能 : 
    SetTheServiceStatus(SERVICE_STOPPED, GetLastError(), 0, 0);// Stop the service.
--------------------------------------------------------------------------------
这是在学习windows的服务安装机制时的笔记,主要是一些函数的说明,还有我自己的代码,没有整理过比较乱
OpenSCManager
     The OpenSCManager function establishes a connection to the service control manager on the specified computer and opens the specified service control manager database.
 
    SC_HANDLE OpenSCManager(
        LPCTSTR lpMachineName,
        LPCTSTR lpDatabaseName,
        DWORD dwDesiredAccess   如果以administrators的权限创建服务的话,该字段的值为SC_MANAGER_ALL_ACCESS
     );
 
CreateService
     The CreateService function creates a service object and adds it to the specified service control manager database
 
    SC_HANDLE CreateService(
         SC_HANDLE hSCManager,
         LPCTSTR lpServiceName,    // 服务的名称
          LPCTSTR lpDisplayName,   
          DWORD dwDesiredAccess,    //SERVICE_ALL_ACCESS
         DWORD dwServiceType,      //SERVICE_WIN32_OWN_PROCESS
         DWORD dwStartType,        //SERVICE_AUTO_START
         DWORD dwErrorControl,     //SERVICE_ERROR_IGNORE
         LPCTSTR lpBinaryPathName,     // 指向二进制文件的路径
          LPCTSTR lpLoadOrderGroup,
         LPDWORD lpdwTagId,
         LPCTSTR lpDependencies,
         LPCTSTR lpServiceStartName,
         LPCTSTR lpPassword
        );
 
Type                    Meaning
SERVICE_FILE_SYSTEM_DRIVER      File system driver service.
SERVICE_KERNEL_DRIVER      Driver service.
SERVICE_WIN32_OWN_PROCESS       Service that runs in its own process.
SERVICE_WIN32_SHARE_PROCESS     Service that shares a process with other services.
 
StartService: 启动一个服务
 
         BOOL StartService(
             SC_HANDLE hService,
             DWORD dwNumServiceArgs,
             LPCTSTR* lpServiceArgVectors
            );
 
QueryServiceStatus
 
     BOOL QueryServiceStatus(
         SC_HANDLE hService,
         LPSERVICE_STATUS lpServiceStatus
        );
 
Return:
 
     If the function succeeds, the return value is nonzero.
    If the function fails, the return value is zero. To get extended error information, call GetLastError.
 
RegisterServiceCtrlHandler:    注册一个服务
 
     SERVICE_STATUS_HANDLE RegisterServiceCtrlHandler(
         LPCTSTR lpServiceName,        // 服务的名字
         LPHANDLER_FUNCTION lpHandlerProc      // 服务的控制函数的名字
         ); 
创建服务线程 服务完成的功能在这里调用
 
CreateThread
 
     HANDLE CreateThread(
         LPSECURITY_ATTRIBUTES lpThreadAttributes,
         SIZE_T dwStackSize,
         LPTHREAD_START_ROUTINE lpStartAddress,    // 线程函数的名字
          LPVOID lpParameter,
         DWORD dwCreationFlags,
         LPDWORD lpThreadId
        );
 
附上我的代码
 
#include  "windows.h"
#include  "stdio.h"
 
// 全局变量
      SERVICE_STATUS       ServiceStatus ;
      SERVICE_STATUS_HANDLE ServiceStatusHandle ;
 
 
// 函数声明
void InstallService ( char  * szServicePath );
void WINAPI ServiceStart ( DWORD dwArgc , LPTSTR  * lpArgv );
void WINAPI ServiceControl ( DWORD dwCode );
DWORD WINAPI Service ( LPVOID lpvThread );      // 服务功能函数
 
 
int main ( int argc , char * argv [])
{     
      // 定义 SERVICE_TABLE_ENTRY DispatchTable[] 结构
      SERVICE_TABLE_ENTRY DispatchTable [2] =
     {
           { "mixu_yy" , ServiceStart },                 
           { NULL , NULL }
     };
 
      // 安装或者打开服务
      StartServiceCtrlDispatcher ( DispatchTable );
      InstallService ( argv [0]);
    
      return  0;
}
// 函数定义
void InstallService ( char  * szServicePath )
{
      SC_HANDLE         schSCManager ;
      SC_HANDLE         schService ;     
      SERVICE_STATUS       InstallServiceStatus ;
      DWORD       dwErrorCode ;
    
      // 打开服务管理数据库
      schSCManager  = OpenSCManager ( NULL , NULL , SC_MANAGER_ALL_ACCESS );
      if ( schSCManager  ==  NULL )
     {
                //Open Service Control Manager Database Failed!;
          return ;
     }
      // 创建服务
      schService  = CreateService (     
                                                   schSCManager ,
                             "mixu_yy" ,
                             "mixu_yy" ,
                             SERVICE_ALL_ACCESS ,
                             SERVICE_WIN32_OWN_PROCESS ,
                             SERVICE_AUTO_START ,
                             SERVICE_ERROR_IGNORE ,
                             szServicePath ,
                             NULL ,
                             NULL ,
                             NULL ,
                             NULL ,
                              NULL );
      if ( schService  ==  NULL )
     {
            dwErrorCode  = GetLastError ();
            if ( dwErrorCode  !=  ERROR_SERVICE_EXISTS )
           {
                  // 创建服务失败
                  CloseServiceHandle ( schSCManager );
                  return ;
           }
            else
           {
                  // 要创建的服务已经存在
                  schService  = OpenService ( schSCManager , "mixu_yy" , SERVICE_START );
                  if ( schService  == NULL )
                 {
                       //Open Service Failed!;
                       CloseServiceHandle ( schSCManager );
                       return ;
                 }
           }
     }
      else
     {
            //Create Service Success!;
     }
      // 启动服务
      if ( StartService ( schService , 0,  NULL )==0 )
     {
            // 启动失败
            dwErrorCode  = GetLastError ();
            if ( dwErrorCode  ==  ERROR_SERVICE_ALREADY_RUNNING )
           {
                  //Service already run!;
                  CloseServiceHandle ( schSCManager );
                  CloseServiceHandle ( schService );
                  return  ;
           }
     }
      else
     {
            //Service pending
     }
 
      while ( QueryServiceStatus ( schService , & InstallServiceStatus ) != 0)
     {
            if ( InstallServiceStatus . dwCurrentState  ==  SERVICE_START_PENDING )
           {
                  //Sleep(100);
           }
            else
           {
                  break ;
           }
     }
      if ( InstallServiceStatus . dwCurrentState  !=  SERVICE_RUNNING )
     {
            //Failure!
     }
      else
     {
            //Sucess!
     }
 
      // 擦屁股
      CloseServiceHandle ( schSCManager );
      CloseServiceHandle ( schService );
      return ;
}
 
void WINAPI ServiceStart ( DWORD dwArgc , LPTSTR  * lpArgv )
{
      HANDLE hThread ;
 
      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;
 
      ServiceStatusHandle  = RegisterServiceCtrlHandler ( "mixu_yy" , ServiceControl );
      if ( ServiceStatusHandle  == 0)
     {
            //error
            return ;
     }
 
      ServiceStatus . dwCurrentState       =  SERVICE_RUNNING ;
      ServiceStatus . dwCheckPoint       = 0;
      ServiceStatus . dwWaitHint       = 0;
 
      if ( SetServiceStatus ( ServiceStatusHandle , & ServiceStatus ) == 0)
     {
            //SetServiceStatus error!
            return ;
     }
    
      // 创建服务线程    服务完成的功能在这里调用
      hThread  = CreateThread ( NULL ,
                       0,
                       Service ,
                        NULL ,
                       0,
                       NULL );
      if ( hThread  ==  NULL )
     {
            //CreateThread error!
            return ;
     }
      CloseHandle ( hThread );
      return ;
}
 
// 服务控制模块
 
void WINAPI ServiceControl ( DWORD dwCode )
{
      switch ( dwCode ) {
      case SERVICE_CONTROL_PAUSE :
            ServiceStatus . dwCurrentState       =  SERVICE_PAUSED ;
            break ;
 
      case SERVICE_CONTROL_CONTINUE :
            ServiceStatus . dwCurrentState       =  SERVICE_RUNNING ;
            break ;
 
      case SERVICE_CONTROL_STOP :
            ServiceStatus . dwCurrentState       =  SERVICE_STOPPED ;
            ServiceStatus . dwWin32ExitCode       = 0;
            ServiceStatus . dwCheckPoint       = 0;
            ServiceStatus . dwWaitHint       = 0;
            if ( SetServiceStatus ( ServiceStatusHandle , & ServiceStatus ) == 0)
           {
                  //SetServiceStatus error!
           }
            return ;
      case SERVICE_CONTROL_INTERROGATE :
            break ;
      default :
            break ;
     }
 
      if ( SetServiceStatus ( ServiceStatusHandle , & ServiceStatus ) == 0)
     {
            //SetServiceStatus error!
     }
 
      return  ;
}
 
// 服务线程函数
DWORD WINAPI Service ( LPVOID lpvThread )
{
            // 实现函数功能的地方。
        return  1;
}
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/69264
推荐阅读
相关标签
  

闽ICP备14008679号