http://www.51zxw.net/study.asp?vip=1368926
A full Windows service source code download address
Development Environment VS 2010 (but the method applies to VS2005 and VS 2008) C + + ATL edition
After the EXE is compiled, use the batch processing under Release to load and unload the service
Start and stop operations for services in the Service Control Panel in Windows
This program is a complete Windows Service development framework, directly inside the Add business code can be
To produce a standard service program
With a log file
Http://b.qjwm.com/down.aspx?down=ok&filepath=dante300%2fwindows+service%2fwindow+service.rar
Knowledge description
Original source: http://topic.csdn.net/u/20070126/09/c1d1279a-bbac-45b9-8e88-835b8956d97e.html
1, debugging: How to Debug in VS2005.
Look at the CAtlServiceModuleT in the WinMain, check the input parameters valid call start. Start detection Service has not registered, not registered directly back to exit. So be sure to register first. A registration is detected to see if it is registered as LocalService (i.e.-service), if the _servicemain is connected to the SCM (Service Manager) for LocalService, it cannot be successfully connected in debug mode, or it must be started by SCM. Otherwise it thinks it has started. It cannot be registered as a service and can only be registered as Regsever (-regsever). After debugging, then register as a service. If there is only error in the service, you can use the CAtlServiceModuleT band logevent to write debug information to Windows events. MSDN says you can service processes to VS2005 I haven't tried, because it's all done in Regsever mode.
2, change the startup mode of the service.
The method for changing the service startup mode was not found. View the code found in CAtlServiceModuleT's install written in the dead.
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 indicates that the SCM is started manually. There is a way to rewrite the registerappid with Changeserviceconfig modified, but look at the changeserviceconfig parameters, a lot of ah, too much trouble. Plus I think that writing a service should start automatically, when processing tasks is a service, and do not want to use can be disabled in the SCM. So I did an immoral place--changed the CAtlServiceModuleT source program. Change the Service_demand_start to 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);
It's not a good way to be a man who calls him immoral. Of course you can use Changeserviceconfig, check yourself.
3, pause and continue,
I would like to use pause and continue to implement the configuration update, because I do not want to change the configuration, to stop the service, and then start, the service will be broken. There is the use of named pipes or global messaging to let configuration tools and services communicate, but too cumbersome, I just want to reconfigure.
First, the menu that pauses and continues in SMC is grayed out. Looking for a long time, find:: SetServiceStatus (M_hservicestatus, &m_status), fortunately m_status is public, with M_status. dwcontrolsaccepted=m_status.dwcontrolsaccepted| Service_accept_pause_continue, take care of.
Another problem, rewriting the onpause but not in. With LogEvent debugging, found CAtlServiceModuleT _handler did not go in (LocalService _servicemain connected to Scm,_servicemain call ServiceMain, The ServiceMain registers Handler as the SCM processing function, handles stop, pause, etc.), which is called in _handler ((t*) _patlmodule)-> Handler (Dwopcode); I don't know where _patlmodule is pointing to. I rewrite the handler and I can come in. When Pause,oncontinue is invoked in its own handler, the handler of the parent class is invoked.
Finally finished, the code is as follows, the worker thread is not written out.
Class Cnvsstoreservermodule:public CAtlServiceModuleT < Cnvsstoreservermodule, Ids_servicename >
{
Private
Cworkthread * pwork; Work class, not written out.
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::P remessageloop (nShowCmd);
if (hr = = S_FALSE) hr = S_OK; That's the only way to go down.
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 "Your service description";
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);
}