The final option for an ATL server is a COM-based Windows NT service. The main difference between a regular EXE server and a Windows NT service is that the AppWizard generates a class named CServiceModule derived from CComModule to manage the COM and Windows NT service aspects of the server. CServiceModule includes four critical member functions necessary for the EXE to run as a service: Start, ServiceMain, Run, and Handler.
The server's WinMain calls CServiceModule::Start to kick off the server. Start calls StartServiceCtrlDispatcher to connect the main thread of the service to the SCM. Start passes CServiceModule::ServiceMain as one of the parameters to StartServiceCtrlDispatcher.
CServiceModule::ServiceMain is called whenever the service is started through Control Panel. ServiceMain calls back to the SCM using RegisterServiceCtrlHandler to pass CServiceModule::Handler to the SCM. The SCM then calls CServiceModule::Handler. By default, ATL handles the stop instruction (and posts a WM_QUIT message to itself). ServiceMain also calls the API function SetServiceStatus to tell the SCM that the service is starting. Finally, CServiceModule::Run runs the service. Run installs the main thread into the process's multithreaded apartment by calling CoInitializeEx and then starting the message pump.
Selecting COM-based service from the ATL COM AppWizard yields the following files:
Compiling the project yields three more files:
As with a DLL-based server, an EXE server generated by the AppWizard also includes IDL code. Compiling the EXE yields enough source code to create a proxy/stub DLL capable of remoting the interfaces described within the IDL file.
That does it for the options available through the ATL COM AppWizard. Let's take a look at the options available through the ATL Object Wizard.