erlsrv(1)
okay bestie, gather round π this right here is the erlsrv(1) page β it lives in the Erlang Module Definition corner of the manual, and it's the one you need when you want Erlang running as a Windows service. it's a long one, and nothing is getting skipped, so grab a snack π
π NAME π
erlsrv β run the Erlang emulator as a service on Windows β¨
π¦ DESCRIPTION π¦
okay so first thing's first: this utility is specific to Windows NT/2000/XP (and later versions of Windows). what it does is let Erlang emulators run as services on the Windows system, which means embedded systems can start up without any user needing to log on. and once an emulator is running this way, you can poke at it through the Windows services applet just like any other service. slay π
and just so we're clear β erlsrv is not a general service utility for Windows. it's designed specifically for embedded Erlang systems, periodt.
erlsrv also gives you a command-line interface for registering, changing, starting, and stopping services. iconic.
β οΈ heads up bestie: to manipulate services, the logged-on user needs administrator privileges on the machine. the Erlang machine itself is (by default) run as the local administrator β you can change that with the Services applet in Windows.
one kinda wild detail: the processes created by the service can, unlike normal services, be "killed" with the task manager. and killing an emulator that was started by a service triggers the OnFail action specified for that service β which can be a reboot π anyway.
The following parameters can be specified for each Erlang service:
πΈ StopAction
tells erlsrv how to stop the Erlang emulator. the default is to just kill it (Win32 TerminateProcess), but this can be set to any Erlang shell command that gets executed inside the emulator to make it stop. the emulator is expected to stop within 30 seconds after the command is issued in the shell. if it doesn't stop, it reports a running state to the service manager π
πΈ OnFail
can be one of the following:
rebootβ the Windows system gets rebooted whenever the emulator stops (a more simple form of watchdog). handy for less critical systems; otherwise use the heart functionality to accomplish this.restartβ makes the Erlang emulator be restarted (with whatever parameters are registered for the service at the occasion) when it stops. if the emulator stops again within 10 seconds, it is not restarted, to avoid an infinite loop that could hang the Windows system.restart_alwaysβ similar torestart, but it does not try to detect cyclic restarts; it's expected that some other mechanism is present to avoid that problem.ignore(the default) β reports the service as stopped to the service manager whenever it fails; it must be manually restarted.
π«Ά on a system where release handling is used, this is always to be set to ignore. use heart to restart the service on failure instead.
πΈ Machine
the location of the Erlang emulator. the default is the erl.exe located in the same directory as erlsrv.exe.
if the system uses release handling, this is to be set to a program similar to start_erl.exe.
πΈ Env
specifies an extra environment for the emulator. the environment variables specified here get added to the system-wide environment block that is normally present when a service starts up. variables present in both the system-wide environment and in the service environment specification will be set to the value specified in the service. no cap.
πΈ WorkDir
the working directory for the Erlang emulator. it must be on a local drive (no network drives are mounted when a service starts, bestie). the default working directory for services is %SystemDrive%%SystemPath%. debug log files will be placed in this directory.
πΈ Priority
the process priority of the emulator. can be one of the following:
realtimeβ not recommended, as the machine will possibly be inaccessible to interactive users π¬highβ can be used if two Erlang nodes are to reside on one dedicated system and one is to have precedence over the other.lowβ can be used if interactive performance is not to be affected by the emulator process.defaultβ the default priority.
πΈ SName or Name
specifies the short or long node name of the Erlang emulator. the Erlang services are always distributed. default is to use the service name as the (short) nodename.
πΈ DebugType
specifies that output from the Erlang shell is to be sent to a "debug log". the log file is named <servicename>.debug or <servicename>.debug.<N>, where <N> is an integer from 1 through 99. the log file is placed in the working directory of the service (as specified in WorkDir).
can be one of the following:
newβ uses a separate log file for every invocation of the service (<servicename>.debug.<N>).reuseβ reuses the same log file (<servicename>.debug).consoleβ opens an interactive Windows console window for the Erlang shell of the service. automatically disables theStopAction. a service started with an interactive console window does not survive logouts.OnFailactions do not work with debug consoles either.none(the default) β the output of the Erlang shell is discarded.
π NOTE: theconsoleoption is not intended for production. it's only a convenient way to debug Erlang services during development. thenewandreuseoptions might seem convenient in a production system, but consider that the logs grow indefinitely during the system lifetime and cannot be truncated, except if the service is restarted. in short, theDebugTypeis intended for debugging only. logs during production are better produced with the standard Erlang logging facilities. periodt.
πΈ Args
passes extra arguments to the emulator startup program erl.exe (or start_erl.exe). arguments that cannot be specified here are -noinput (StopActions would not work), -name, and -sname (they are specified in any way). the most common use is for specifying cookies and flags to be passed to init (-s).
πΈ InternalServiceName
specifies the Windows-internal service name (not the display name, which is the one erlsrv uses to identify the service).
this internal name cannot be changed β it is fixed even if the service is renamed. erlsrv generates a unique internal name when a service is created. it is recommended to keep to the default if release handling is to be used for the application.
the internal service name can be seen in the Windows service manager if viewing Properties for an Erlang service.
πΈ Comment
a textual comment describing the service. not mandatory, but it shows up as the service description in the Windows service manager. cute β¨
the naming of the service in a system that uses release handling must follow the convention NodeName_Release, where NodeName is the first part of the Erlang node name (up to, but not including the "@") and Release is the current release of the application. iykyk π
π οΈ erlsrv {set | add} <service-name> [<service options>]
the set and add commands modify or add an Erlang service, respectively. the simplest form of an add command is without any options, in which case all the default values (described above) apply. the service name is mandatory.
every option can be specified without parameters, and the default value is then applied. values to the options are supplied only when the default is not to be used. for example, erlsrv set myservice -prio -arg sets the default priority and removes all arguments. chef's kiss π
service options:
-st[opaction] [<erlang shell command>]β defines theStopAction, the command given to the Erlang shell when the service is stopped. default is none.-on[fail] [{reboot | restart | restart_always}]β the action to take when the Erlang emulator stops unexpectedly. default is toignore.-m[achine] [<erl-command>]β the complete path to the Erlang emulator. never use thewerlprogram for this. defaults to theerl.exein the same directory aserlsrv.exe. when release handling is used, this is to be set to a program similar tostart_erl.exe.-e[nv] [<variable>[=<value>]] ...β edits the environment block for the service. every environment variable specified is added to the system environment block. if a variable specified here has the same name as a system-wide environment variable, the specified value overrides the system-wide one. environment variables are added to this list by specifying<variable>=<value>and deleted from the list by specifying<variable>alone. the environment block is automatically sorted. any number of-envoptions can be specified in one command. default is to use the system environment block unmodified (except for two additions, see section Environment below).-w[orkdir] [<directory>]β the initial working directory of the Erlang emulator. defaults to the system directory.-p[riority] [{low|high|realtime}]β the priority of the Erlang emulator. default to the Windows default priority.{-sn[ame] | -n[ame]} [<node-name>]β the node name of the Erlang machine. distribution is mandatory. defaults to-sname <service name>.-d[ebugtype] [{new|reuse|console}]β specifies where shell output is to be sent. default is that shell output is discarded. to be used only for debugging π-ar[gs] [<limited erl arguments>]β extra arguments to the Erlang emulator. avoid-noinput,-noshell, and-sname/-name. default is no extra arguments. remember that the services cookie file is not necessarily the same as the interactive users'. the service runs as the local administrator. specify all arguments together in one string, use double quotes (") to specify an argument string containing spaces, and use quoted quotes (\") to specify a quote within the argument string if necessary.-i[nternalservicename] [<internal name>]β only allowed foradd. specifies a Windows-internal service name for the service, which by default is set to something unique (prefixed with the original service name) byerlsrvwhen adding a new service. specifying this is a purely "cosmethic" action (the page really spells it like that π) and is not recommended if release handling is to be performed. the internal service name cannot be changed once the service is created. the internal name is not to be confused with the ordinary service name, which is the name used to identify a service toerlsrv.-c[omment] [<short description>]β specifies a textual comment describing the service. this comment shows up as the service description in the Windows service manager.
π οΈ erlsrv {start | start_disabled | stop | disable | enable} <service-name>
these commands are only added for convenience β the normal way to manipulate the state of a service is through the control panels services applet. fr fr π
Okay so bestie, listen up: start and stop are literally the middlemen between you and the service managerβthey ask it to start or stop a service, and they wait until that's actually done. No ghosting, they stay until it's finished. π When you disable a service, though, it does not get stoppedβthe disabled vibe doesn't kick in until the service is stopped. Enabling a service? That sets it to automatic mode, which means it starts at boot. But heads up: this command can't set the service to manual. Sorry, not sorry. π
Now start_disabled? It's the chaotic-good command that don't care about your service's current statusβenabled, disabled, started, stopped, whatever. It just does its thing: first it enables the service (even if it's already enabled, no biggie), then it starts it (if it wasn't already started), and finally it disables it again. So you end up with a service that's disabled but started, no matter what it was before. This is super handy for starting services temporarily during a release upgrade. π The glow-up here versus just doing enable, start, disable manually? All other erlsrv commands get locked out during the start_disable sequence, so from an erlsrv user's perspective, the whole thing is atomic. Slay. β¨
erlsrv remove <service-name> π
This one? It removes the service completelyβlike, all its registered options too, gone. But first, it stops the service before removing it. So it's a clean break, no messy leftovers. π
erlsrv list [<service-name>] πΈ
No service name? You get a cute little brief listing of every Erlang service out there. If you do give a service name, then it spills all the options for that specific service. It's giving 'tell me everything' energy. π
erlsrv help π
Just shows you a brief help text. A little snack of wisdom. π
Environment π
When an Erlang machine gets started as a service, its environment has two special variables that are literally so important:
ERLSRV_SERVICE_NAMEβ the name of the service that started the machine, bestie. πERLSRV_EXECUTABLEβ the full path toerlsrv.exe, which you can use to manipulate the service. This one comes in super handy when you're defining a heart command for your service. π«Ά
A command file for restarting a service looks like this:
@echo off
%ERLSRV_EXECUTABLE% stop %ERLSRV_SERVICE_NAME%
%ERLSRV_EXECUTABLE% start %ERLSRV_SERVICE_NAME%
You then set this command file as the heart command. Iconic. β¨
Oh and also? Those environment variables can be used to detect that we're running as a service, and make port programs react correctly to the control events generated on logout (see the next section). No cap.
Port Programs π¦
So when a program runs in the service context, it has to handle the control events that get sent to every program in the system when the interactive user logs off. How? Depends on whether it's a console subsystem program or a window application. If it's a console subsystem app (which is normal for port programs), it uses the win32 function SetConsoleCtrlHandler to register a control handler that returns true for the CTRL_LOGOFF_EVENT and CTRL_SHUTDOWN_EVENT events. Other apps? They just forward WM_ENDSESSION and WM_QUERYENDSESSION to the default window procedure. Simple as that. π
A brief example in C of how to set the console control handler:
#include <windows.h>
/*
** A Console control handler that ignores the log off events,
** and lets the default handler take care of other events.
*/
BOOL WINAPI service_aware_handler(DWORD ctrl){
if(ctrl == CTRL_LOGOFF_EVENT)
return TRUE;
if(ctrl == CTRL_SHUTDOWN_EVENT)
return TRUE;
return FALSE;
}
void initialize_handler(void){
char buffer[2];
/*
* We assume we are running as a service if this
* environment variable is defined.
*/
if(GetEnvironmentVariable("ERLSRV_SERVICE_NAME",buffer,
(DWORD) 2)){
/*
** Actually set the control handler
*/
SetConsoleCtrlHandler(&service_aware_handler, TRUE);
}
}
Notes π
Okay so even though these options are described in a Unix-like format, the case of the options or commands? Doesn't matter. And you can use both / and - for options. It's giving flexible. π
Also, note that the program lives in the emulator's bin directory, not in the bin directory directly under the Erlang root. Why? Because upgrading the emulator on a running system is a subtle problemβa new version of the runtime system shouldn't have to overwrite existing (and probably in-use) executables. So yeah, it's a whole thing. π
To make manipulating Erlang services easy-peasy, put the <erlang_root>\erts-<version>\bin directory in your path instead of <erlang_root>\bin. Also, you can find the erlsrv program from inside Erlang by using the os:find_executable/1 Erlang function. iykyk. π
And for release handling to actually work? Use start_erl as the Erlang machine. Like I said earlier, the service name is significant. Don't forget it. β¨
See Also π
start_erl(1), release_handler β go check 'em out if you want the full lore. π
Brought to you by Ericsson AB, erts 17.0.6, and the one and only erlsrv(1). That's the tea, bestie. Stay slaying. βπ β¨
π¦ where this page comes from
- ubuntu stonking: erlang-doc 1:29.0.6+dfsg-1 Β· Apache-2.0
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms