开发环境 vs c++ 2010 (但方法适用于VS2005 及 VS 2008)c++ atl 版

http://www.51zxw.net/study.asp?vip=1368926

一个完整windows 服务源代码下载地址

开发环境 vs 2010 (但方法适用于VS2005 及 VS 2008)c++ atl 版

在编译出exe以后使用release下的批处理安装卸载服务
在windows里的服务控制面板进行服务的启动和停止操作
本程序是完整的windows 服务开发框架,直接在里面添加业务代码就可以
产生一个标准的服务程序

带有一个日志文件

http://b.qjwm.com/down.aspx?down=ok&filepath=dante300%2fwindows+service%2fwindow+service.rar

 

 

知识性说明

原文出处:http://topic.csdn.net/u/20070126/09/c1d1279a-bbac-45b9-8e88-835b8956d97e.html

1,调试:怎样才能在VS2005中调试。
看CatlServiceModuleT中的WinMain,检查输入参数有效就调用START。START先检测服务有没有注册过,没有注册的就直接返回退出。所以一定要先注册。检测到有注册就查看是否注册为LocalService(也就是   -Service),如果为LocalService就把_ServiceMain连接到SCM(服务管理器),但在调试模式下不能连接成功,或者必须由SCM来启动,要不它认为已启动。所以不能注册为服务,只能注册为RegSever(-RegSever)。调试完后,再注册为服务。如果只有在服务里面才出错,可用CatlServiceModuleT带的LogEvent   把调试信息写到windows事件里面。MSDN中讲可以服务进程连到VS2005我没试过,因为全在RegSever模式下解决了。
 
2,更改服务的启动模式。
没找到更改服务启动模式的方法。查看代码发现在CatlServiceModuleT的Install中写死的。
                  SC_HANDLE   hService   =   ::CreateService(
                            hSCM,   m_szServiceName,   m_szServiceName,
                            SERVICE_ALL_ACCESS,   SERVICE_WIN32_OWN_PROCESS,
                            SERVICE_DEMAND_START,   SERVICE_ERROR_NORMAL,
                  szFilePath,   NULL,   NULL,   _T( "RPCSS/0 "),   NULL,   NULL);
 
SERVICE_DEMAND_START表示手动在SCM启动。有个方法,在重写的RegisterAppId用ChangeServiceConfig修改,但看一下ChangeServiceConfig的参数,好多呀,太麻烦。加上我觉得写一个服务就应该自动启动,什么时候处理任务是服务的事,而且不想用了可以在SCM里禁用。所以我做了一个不道德的地方――把CatlServiceModuleT源程序改了。把SERVICE_DEMAND_START改为SERVICE_AUTO_START。
                  SC_HANDLE   hService   =   ::CreateService(
                            hSCM,   m_szServiceName,   m_szServiceName,
                            SERVICE_ALL_ACCESS,   SERVICE_WIN32_OWN_PROCESS,
                            SERVICE_AUTO_START,   SERVICE_ERROR_NORMAL,
                  szFilePath,   NULL,   NULL,   _T( "RPCSS/0 "),   NULL,   NULL);
谁叫他不道德没流一个好的方法。当然你可以用ChangeServiceConfig,自己查一下。
 
              3,暂停和继续,
我想用暂停和继续来实现配置的更新,因为不想改配置的时候,要停止服务,再启动,那样服务会断。还有就是用命名管道或全局消息让配置工具和服务通讯,但太麻烦,我只是想重新应有配置。
              第一个问题,在SMC中暂停和继续的菜单是灰的。找了很久,找到::SetServiceStatus(m_hServiceStatus,   &m_status)   ,还好m_status是Public   ,用m_status.   dwControlsAccepted=m_status.dwControlsAccepted|   SERVICE_ACCEPT_PAUSE_CONTINUE;搞定。
              另一个问题,重写了OnPause但更本没进去。用LogEvent调试,发现CatlServiceModuleT的_Handler都没进去(LocalService就把_ServiceMain连接到SCM,_ServiceMain调用ServiceMain,ServiceMain中注册Handler为SCM处理函数,处理STOP、PAUSE等),_Handler   中是这样调用的((T*)_pAtlModule)-> Handler(dwOpcode);   不知到_pAtlModule是指向谁的实例。我重写了Handler,就可以进来了。在自己的Handler中调用PAUSE,OnContinue后,就调用父类的Handler。
 
 
终于完成了,代码如下,工作线程没写出来。
 
class   CNVSStoreServerModule   :   public   CAtlServiceModuleT <   CNVSStoreServerModule,   IDS_SERVICENAME   >
{
private:
          CWorkThread   *   pWork;   //工作类,没写出来。
public   :
          DECLARE_LIBID(LIBID_NVSStoreServerLib)
          DECLARE_REGISTRY_APPID_RESOURCEID(IDR_NVSSTORESERVER,   "{CF40AF29-C742-4D52-906C-5915A611F2D6} ")
          HRESULT   InitializeSecurity()   throw()
          {
                  return   S_OK;
          }
          void   OnPauze()   throw()
          {
                  SetEvent(pWork-> mServerStopEvent);
                  SetServiceStatus(SERVICE_PAUSED);
                  __super::OnPause();
          }
          void   OnStop()   throw()
          {
                  SetEvent(pWork-> mServerStopEvent);
                  WaitForSingleObject(pWork-> mCanStopEvent,INFINITE);
                  __super::OnStop();
          }
          void   Handler(DWORD   dwOpcode)   throw()
          {
                  switch   (dwOpcode)
                  {
                  case   SERVICE_CONTROL_PAUSE:
                            OnPauze();
                            break;
                  case   SERVICE_CONTROL_CONTINUE:
                            OnContinue();
                            break;
                  }
                  __super::Handler(dwOpcode);
          }
          CServiceStatus   GetServiceStatus()   throw()
          {
                  return   this-> m_ServiceStatus;
          }
          void   OnContinue(   )   throw(   )
          {
                  SetServiceStatus(SERVICE_RUNNING);
                  __super::OnContinue();
          }
          HRESULT   PreMessageLoop(int   nShowCmd)   throw()
          {
                  m_status.dwControlsAccepted   =m_status.dwControlsAccepted   |   SERVICE_ACCEPT_PAUSE_CONTINUE;
                  HRESULT   hr   =   __super::PreMessageLoop(nShowCmd);
                  if   (hr   ==   S_FALSE)   hr   =   S_OK;   //要这句才能走下去
                  pWork=new   CWorkThread();
                  return   hr;
          }
          HRESULT   RegisterAppId(bool   bService   =   false)   throw()
          {                      
                  HRESULT   hr   =   S_OK;
                  BOOL   res   =   __super::RegisterAppId(bService);  
                  if   (bService)
                  {
                            if   (IsInstalled())
                            {                
                                      SC_HANDLE   hSCM   =   ::OpenSCManagerW(NULL,   NULL,   SERVICE_CHANGE_CONFIG);
                                      SC_HANDLE   hService   =   NULL;
                                      if   (hSCM   ==   NULL)
                                              hr   =   AtlHresultFromLastError();
                                      else
                                      {
                                              hService   =   ::OpenServiceW(hSCM,   m_szServiceName,   SERVICE_CHANGE_CONFIG);
                                              if   (hService   !=   NULL)
                                              {
                                                        const   int   m_szServiceNameLen   =   4096;
                                                        const   int   m_szServiceDescriptionLen   =   2000;
                                                        WCHAR   m_szServiceDescription[m_szServiceDescriptionLen]=L "你的服务描述 ";
                                                        SERVICE_DESCRIPTION   sdBuf   =   {m_szServiceDescription};
                                                        res   =   ChangeServiceConfig2W(hService,   SERVICE_CONFIG_DESCRIPTION,   &sdBuf);
                                                        ::CloseServiceHandle(hService);
                                              }
                                              else
                                                        hr   =   AtlHresultFromLastError();
                                              ::CloseServiceHandle(hSCM);
                                      }
 
                            }
                  }
                  return   hr;
          }
};
 
CNVSStoreServerModule   _AtlModule;
 
extern   "C "   int   WINAPI   _tWinMain(HINSTANCE   /*hInstance*/,   HINSTANCE   /*hPrevInstance*/,  
                                                                          LPTSTR   /*lpCmdLine*/,   int   nShowCmd)
{
          return   _AtlModule.WinMain(nShowCmd);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值