Controlling the Freelancer server with an NT service
Installing the service
Rather than have users download a separate program like the venerable srvany to install our service, we allow it to be run from the command line with an argument of either "install" or "remove."
Installing the service
To install the service, the user will type
flmonitor install
This will show a nice GUI to set the path to the server executable, name the service and pass any options to the server.
I'll skip discussion of the GUI and the writing of these parameters to the registry. Instead let's focus on the act of actually installing the service. This takes place in the install() function of dialogue.cpp.
The first thing to do is to get a handle to the services manager:
/* Open service manager */ SC_HANDLE services = OpenSCManager(0, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS); if (! services) /* Error */
Next we try to create the service using CreateService():
/* Get path of this program */ char path[MAX_PATH]; GetModuleFileName(0, path, MAX_PATH); /* Create the service */ /* name contains the name of the service */ SC_HANDLE service = CreateService(services, name, name, SC_MANAGER_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, path, 0, 0, 0, 0, 0); if (! service) /* Error */
We then try to write the registry parameters which govern the service's operation, using create_parameters(). If this fails, we call DeleteService(service) to delete the service we just created.
Whatever happened above, we now need to close the service manager, leaving the service successfully installed OR with no changes to the services database made.
CloseServiceHandle(service); CloseServiceHandle(services);
Removing the service
To remove the service, the user will type
flmonitor remove
After popping up a confirmation window, we call remove_service() to remove the service. You already know how to do this:
SC_HANDLE services = OpenSCManager(0, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS); if (! services) /* Error */ /* Try to open the service */ SC_HANDLE service = OpenService(services, FL_SERVICE, SC_MANAGER_ALL_ACCESS); if (! service) /* Error */ /* Try to delete the service */ if (! DeleteService(service)) /* Error */ /* Cleanup */ CloseServiceHandle(service); CloseServiceHandle(services);
We don't need to worry about removing the registry entries as they will be removed along with the other service parameters.
Conclusion
We can now install and remove an NT service which will control the Freelancer game server.
Jump to a section
intro | part 1: Creating an NT service | part 2: Installing the service