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.

Installation GUI

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