RegisterPowerSettingNotification is unnecessary.
[nssm.git] / README.txt
index 88a7290..e944340 100644 (file)
@@ -1,5 +1,5 @@
 NSSM: The Non-Sucking Service Manager\r
-Version 2.7, 2011-01-25\r
+Version 2.24, 2014-08-31\r
 \r
 NSSM is a service helper program similar to srvany and cygrunsrv.  It can \r
 start any application as an NT service and will restart the service if it \r
@@ -9,7 +9,7 @@ NSSM also has a graphical service installer and remover.
 \r
 Full documentation can be found online at\r
 \r
-                           http://iain.cx/src/nssm/\r
+                              http://nssm.cc/\r
 \r
 Since version 2.0, the GUI can be bypassed by entering all appropriate \r
 options on the command line.\r
@@ -24,14 +24,59 @@ Since version 2.3, NSSM logs to the Windows event log more elegantly.
 \r
 Since version 2.5, NSSM respects environment variables in its parameters.\r
 \r
+Since version 2.8, NSSM tries harder to shut down the managed application\r
+gracefully and throttles restart attempts if the application doesn't run\r
+for a minimum amount of time.\r
+\r
+Since version 2.11, NSSM respects srvany's AppEnvironment parameter.\r
+\r
+Since version 2.13, NSSM is translated into French.\r
+Thanks François-Régis Tardy.\r
+\r
+Since version 2.15, NSSM is translated into Italian.\r
+Thanks Riccardo Gusmeroli.\r
+\r
+Since version 2.17, NSSM can try to shut down console applications by\r
+simulating a Control-C keypress.  If they have installed a handler routine\r
+they can clean up and shut down gracefully on receipt of the event.\r
+\r
+Since version 2.17, NSSM can redirect the managed application's I/O streams\r
+to an arbitrary path.\r
+\r
+Since version 2.18, NSSM can be configured to wait a user-specified amount\r
+of time for the application to exit when shutting down.\r
+\r
+Since version 2.19, many more service options can be configured with the\r
+GUI installer as well as via the registry.\r
+\r
+Since version 2.19, NSSM can add to the service's environment by setting\r
+AppEnvironmentExtra in place of or in addition to the srvany-compatible\r
+AppEnvironment.\r
+\r
+Since version 2.22, NSSM can set the managed application's process priority\r
+and CPU affinity.\r
+\r
+Since version 2.22, NSSM can apply an unconditional delay before restarting\r
+an application which has exited.\r
+\r
+Since version 2.22, NSSM can rotate existing output files when redirecting I/O.\r
+\r
+Since version 2.22, NSSM can set service display name, description, startup\r
+type, log on details and dependencies.\r
+\r
+Since version 2.22, NSSM can manage existing services.\r
+\r
 \r
 Usage\r
 -----\r
-In the usage notes below, arguments to the program may be written in angle \r
-brackets and/or square brackets.  <string> means you must insert the \r
-appropriate string and [<string>] means the string is optional.  See the \r
+In the usage notes below, arguments to the program may be written in angle\r
+brackets and/or square brackets.  <string> means you must insert the\r
+appropriate string and [<string>] means the string is optional.  See the\r
 examples below...\r
 \r
+Note that everywhere <servicename> appears you may substitute the\r
+service's display name.\r
+\r
 \r
 Installation using the GUI\r
 --------------------------\r
@@ -58,6 +103,9 @@ with the given options (if you specified any).
 \r
 Don't forget to enclose paths in "quotes" if they contain spaces!\r
 \r
+If you want to include quotes in the options you will need to """quote""" the\r
+quotes.\r
+\r
 \r
 Managing the service\r
 --------------------\r
@@ -72,11 +120,28 @@ keep trying, pausing between each attempt, until the service is successfully
 started or you send it a stop signal.\r
 \r
 NSSM will pause an increasingly longer time between subsequent restart attempts\r
-if the service fails to start in a timely manner, up to a maximum of 60 seconds.\r
-This is so it does not consume an excessive amount of CPU time trying to start\r
-a failed application over and over again.  If you identify the cause of the\r
-failure and don't want to wait you can use the Windows service console to\r
-send a continue signal to NSSM and it will retry within a few seconds.\r
+if the service fails to start in a timely manner, up to a maximum of four\r
+minutes.  This is so it does not consume an excessive amount of CPU time trying\r
+to start a failed application over and over again.  If you identify the cause\r
+of the failure and don't want to wait you can use the Windows service console\r
+(where the service will be shown in Paused state) to send a continue signal to\r
+NSSM and it will retry within a few seconds.\r
+\r
+By default, NSSM defines "a timely manner" to be within 1500 milliseconds.\r
+You can change the threshold for the service by setting the number of\r
+milliseconds as a REG_DWORD value in the registry at\r
+HKLM\SYSTEM\CurrentControlSet\Services\<service>\Parameters\AppThrottle.\r
+\r
+Alternatively, NSSM can pause for a configurable amount of time before\r
+attempting to restart the application even if it successfully ran for the\r
+amount of time specified by AppThrottle.  NSSM will consult the REG_DWORD value\r
+at HKLM\SYSTEM\CurrentControlSet\Services\<service>\Parameters\AppRestartDelay\r
+for the number of milliseconds to wait before attempting a restart.  If\r
+AppRestartDelay is set and the application is determined to be subject to\r
+throttling, NSSM will pause the service for whichever is longer of the\r
+configured restart delay and the calculated throttle period.\r
+\r
+If AppRestartDelay is missing or invalid, only throttling will be applied.\r
 \r
 NSSM will look in the registry under\r
 HKLM\SYSTEM\CurrentControlSet\Services\<service>\Parameters\AppExit for\r
@@ -112,6 +177,420 @@ request to suicide if you explicitly configure a registry key for exit code 0.
 If only the default action is set to Suicide NSSM will instead exit gracefully.\r
 \r
 \r
+Application priority\r
+--------------------\r
+NSSM can set the priority class of the managed application.  NSSM will look in\r
+the registry under HKLM\SYSTEM\CurrentControlSet\Services\<service>\Parameters\r
+for the REG_DWORD entry AppPriority.  Valid values correspond to arguments to\r
+SetPriorityClass().  If AppPriority() is missing or invalid the\r
+application will be launched with normal priority.\r
+\r
+\r
+Processor affinity\r
+------------------\r
+NSSM can set the CPU affinity of the managed application.  NSSM will look in\r
+the registry under HKLM\SYSTEM\CurrentControlSet\Services\<service>\Parameters\r
+for the REG_SZ entry AppAffinity.   It should specify a comma-separated listed\r
+of zero-indexed processor IDs.  A range of processors may optionally be\r
+specified with a dash.  No other characters are allowed in the string.\r
+\r
+For example, to specify the first; second; third and fifth CPUs, an appropriate\r
+AppAffinity would be 0-2,4.\r
+\r
+If AppAffinity is missing or invalid, NSSM will not attempt to restrict the\r
+application to specific CPUs.\r
+\r
+Note that the 64-bit version of NSSM can configure a maximum of 64 CPUs in this\r
+way and that the 32-bit version can configure a maxium of 32 CPUs even when\r
+running on 64-bit Windows.\r
+\r
+\r
+Stopping the service\r
+--------------------\r
+When stopping a service NSSM will attempt several different methods of killing\r
+the monitored application, each of which can be disabled if necessary.\r
+\r
+First NSSM will attempt to generate a Control-C event and send it to the\r
+application's console.  Batch scripts or console applications may intercept\r
+the event and shut themselves down gracefully.  GUI applications do not have\r
+consoles and will not respond to this method.\r
+\r
+Secondly NSSM will enumerate all windows created by the application and send\r
+them a WM_CLOSE message, requesting a graceful exit.\r
+\r
+Thirdly NSSM will enumerate all threads created by the application and send\r
+them a WM_QUIT message, requesting a graceful exit.  Not all applications'\r
+threads have message queues; those which do not will not respond to this\r
+method.\r
+\r
+Finally NSSM will call TerminateProcess() to request that the operating\r
+system forcibly terminate the application.  TerminateProcess() cannot be\r
+trapped or ignored, so in most circumstances the application will be killed.\r
+However, there is no guarantee that it will have a chance to perform any\r
+tidyup operations before it exits.\r
+\r
+Any or all of the methods above may be disabled.  NSSM will look for the\r
+HKLM\SYSTEM\CurrentControlSet\Services\<service>\Parameters\AppStopMethodSkip\r
+registry value which should be of type REG_DWORD set to a bit field describing\r
+which methods should not be applied.\r
+\r
+  If AppStopMethodSkip includes 1, Control-C events will not be generated.\r
+  If AppStopMethodSkip includes 2, WM_CLOSE messages will not be posted.\r
+  If AppStopMethodSkip includes 4, WM_QUIT messages will not be posted.\r
+  If AppStopMethodSkip includes 8, TerminateProcess() will not be called.\r
+\r
+If, for example, you knew that an application did not respond to Control-C\r
+events and did not have a thread message queue, you could set AppStopMethodSkip\r
+to 5 and NSSM would not attempt to use those methods to stop the application.\r
+\r
+Take great care when including 8 in the value of AppStopMethodSkip.  If NSSM\r
+does not call TerminateProcess() it is possible that the application will not\r
+exit when the service stops.\r
+\r
+By default NSSM will allow processes 1500ms to respond to each of the methods\r
+described above before proceeding to the next one.  The timeout can be\r
+configured on a per-method basis by creating REG_DWORD entries in the\r
+registry under HKLM\SYSTEM\CurrentControlSet\Services\<service>\Parameters.\r
+\r
+  AppStopMethodConsole\r
+  AppStopMethodWindow\r
+  AppStopMethodThreads\r
+\r
+Each value should be set to the number of milliseconds to wait.  Please note\r
+that the timeout applies to each process in the application's process tree,\r
+so the actual time to shutdown may be longer than the sum of all configured\r
+timeouts if the application spawns multiple subprocesses.\r
+\r
+To skip applying the above stop methods to all processes in the application's\r
+process tree, applying them only to the original application process, set the\r
+HKLM\SYSTEM\CurrentControlSet\Services\<service>\Parameters\AppKillProcessTree\r
+registry value, which should be of type REG_DWORD, to 0.\r
+\r
+\r
+Console window\r
+--------------\r
+By default, NSSM will create a console window so that applications which\r
+are capable of reading user input can do so - subject to the service being\r
+allowed to interact with the desktop.\r
+\r
+Creation of the console can be suppressed by setting the integer (REG_DWORD)\r
+HKLM\SYSTEM\CurrentControlSet\Services\<service>\Parameters\AppNoConsole\r
+registry value to 1.\r
+\r
+\r
+I/O redirection\r
+---------------\r
+NSSM can redirect the managed application's I/O to any path capable of being\r
+opened by CreateFile().  This enables, for example, capturing the log output\r
+of an application which would otherwise only write to the console or accepting\r
+input from a serial port.\r
+\r
+NSSM will look in the registry under\r
+HKLM\SYSTEM\CurrentControlSet\Services\<service>\Parameters for the keys\r
+corresponding to arguments to CreateFile().  All are optional.  If no path is\r
+given for a particular stream it will not be redirected.  If a path is given\r
+but any of the other values are omitted they will be receive sensible defaults.\r
+\r
+  AppStdin: Path to receive input.\r
+  AppStdout: Path to receive output.\r
+  AppStderr: Path to receive error output.\r
+\r
+Parameters for CreateFile() are providing with the "AppStdinShareMode",\r
+"AppStdinCreationDisposition" and "AppStdinFlagsAndAttributes" values (and\r
+analogously for stdout and stderr).\r
+\r
+In general, if you want the service to log its output, set AppStdout and\r
+AppStderr to the same path, eg C:\Users\Public\service.log, and it should\r
+work.  Remember, however, that the path must be accessible to the user\r
+running the service.\r
+\r
+\r
+File rotation\r
+-------------\r
+When using I/O redirection, NSSM can rotate existing output files prior to\r
+opening stdout and/or stderr.  An existing file will be renamed with a\r
+suffix based on the file's last write time, to millisecond precision.  For\r
+example, the file nssm.log might be rotated to nssm-20131221T113939.457.log.\r
+\r
+NSSM will look in the registry under\r
+HKLM\SYSTEM\CurrentControlSet\Services\<service>\Parameters for REG_DWORD\r
+entries which control how rotation happens.\r
+\r
+If AppRotateFiles is missing or set to 0, rotation is disabled.  Any non-zero\r
+value enables rotation.\r
+\r
+If AppRotateSeconds is non-zero, a file will not be rotated if its last write\r
+time is less than the given number of seconds in the past.\r
+\r
+If AppRotateBytes is non-zero, a file will not be rotated if it is smaller\r
+than the given number of bytes.  64-bit file sizes can be handled by setting\r
+a non-zero value of AppRotateBytesHigh.\r
+\r
+If AppRotateDelay is non-zero, NSSM will pause for the given number of\r
+milliseconds after rotation.\r
+\r
+If AppStdoutCopyAndTruncate or AppStdErrCopyAndTruncate are non-zero, the\r
+stdout (or stderr respectively) file will be rotated by first taking a copy\r
+of the file then truncating the original file to zero size.  This allows\r
+NSSM to rotate files which are held open by other processes, preventing the\r
+usual MoveFile() from succeeding.  Note that the copy process may take some\r
+time if the file is large, and will temporarily consume twice as much disk\r
+space as the original file.  Note also that applications reading the log file\r
+may not notice that the file size changed.  Using this option in conjunction\r
+with AppRotateDelay may help in that case.\r
+\r
+Rotation is independent of the CreateFile() parameters used to open the files.\r
+They will be rotated regardless of whether NSSM would otherwise have appended\r
+or replaced them.\r
+\r
+NSSM can also rotate files which hit the configured size threshold while the\r
+service is running.  Additionally, you can trigger an on-demand rotation by\r
+running the command\r
+\r
+    nssm rotate <servicename>\r
+\r
+On-demand rotations will happen after the next line of data is read from\r
+the managed application, regardless of the value of AppRotateBytes. Be aware\r
+that if the application is not particularly verbose the rotation may not\r
+happen for some time.\r
+\r
+To enable online and on-demand rotation, set AppRotateOnline to a non-zero\r
+value.\r
+\r
+Note that online rotation requires NSSM to intercept the application's I/O\r
+and create the output files on its behalf.  This is more complex and\r
+error-prone than simply redirecting the I/O streams before launching the\r
+application.  Therefore online rotation is not enabled by default.\r
+\r
+\r
+Environment variables\r
+---------------------\r
+NSSM can replace or append to the managed application's environment.  Two\r
+multi-valued string (REG_MULTI_SZ) registry values are recognised under\r
+HKLM\SYSTEM\CurrentControlSet\Services\<service>\Parameters.\r
+\r
+AppEnvironment defines a list of environment variables which will override\r
+the service's environment.  AppEnvironmentExtra defines a list of\r
+environment variables which will be added to the service's environment.\r
+\r
+Each entry in the list should be of the form KEY=VALUE.  It is possible to\r
+omit the VALUE but the = symbol is mandatory.\r
+\r
+Environment variables listed in both AppEnvironment and AppEnvironmentExtra\r
+are subject to normal expansion, so it is possible, for example, to update the\r
+system path by setting "PATH=C:\bin;%PATH%" in AppEnvironmentExtra.  Variables\r
+are expanded in the order in which they appear, so if you want to include the\r
+value of one variable in another variable you should declare the dependency\r
+first.\r
+\r
+Because variables defined in AppEnvironment override the existing\r
+environment it is not possible to refer to any variables which were previously\r
+defined.\r
+\r
+For example, the following AppEnvironment block:\r
+\r
+      PATH=C:\Windows\System32;C:\Windows\r
+      PATH=C:\bin;%PATH%\r
+\r
+Would result in a PATH of "C:\bin;C:\Windows\System32;C:\Windows" as expected.\r
+\r
+Whereas the following AppEnvironment block:\r
+\r
+      PATH=C:\bin;%PATH%\r
+\r
+Would result in a path containing only C:\bin and probably cause the\r
+application to fail to start.\r
+\r
+Most people will want to use AppEnvironmentExtra exclusively.  srvany only\r
+supports AppEnvironment.\r
+\r
+\r
+Managing services using the GUI\r
+-------------------------------\r
+NSSM can edit the settings of existing services with the same GUI that is\r
+used to install them.  Run\r
+\r
+    nssm edit <servicename>\r
+\r
+to bring up the GUI.\r
+\r
+NSSM offers limited editing capabilities for services other than those which\r
+run NSSM itself.  When NSSM is asked to edit a service which does not have\r
+the App* registry settings described above, the GUI will allow editing only\r
+system settings such as the service display name and description.\r
+\r
+\r
+Managing services using the command line\r
+----------------------------------------\r
+NSSM can retrieve or set individual service parameters from the command line.\r
+In general the syntax is as follows, though see below for exceptions.\r
+\r
+    nssm get <servicename> <parameter>\r
+\r
+    nssm set <servicename> <parameter> <value>\r
+\r
+Parameters can also be reset to their default values.\r
+\r
+    nssm reset <servicename> <parameter>\r
+\r
+The parameter names recognised by NSSM are the same as the registry entry\r
+names described above, eg AppDirectory.\r
+\r
+NSSM offers limited editing capabilities for Services other than those which\r
+run NSSM itself.  The parameters recognised are as follows:\r
+\r
+  Description: Service description.\r
+  DisplayName: Service display name.\r
+  ImagePath: Path to the service executable.\r
+  ObjectName: User account which runs the service.\r
+  Name: Service key name.\r
+  Start: Service startup type.\r
+  Type: Service type.\r
+\r
+These correspond to the registry values under the service's key\r
+HKLM\SYSTEM\CurrentControlSet\Services\<service>.\r
+\r
+\r
+Note that NSSM will concatenate all arguments passed on the command line\r
+with spaces to form the value to set.  Thus the following two invocations\r
+would have the same effect.\r
+\r
+    nssm set <servicename> Description "NSSM managed service"\r
+\r
+    nssm set <servicename> Description NSSM managed service\r
+\r
+\r
+Non-standard parameters\r
+-----------------------\r
+The AppEnvironment and AppEnvironmentExtra parameters recognise an\r
+additional argument when querying the environment.  The following syntax\r
+will print all extra environment variables configured for a service\r
+\r
+    nssm get <servicename> AppEnvironmentExtra\r
+\r
+whereas the syntax below will print only the value of the CLASSPATH\r
+variable if it is configured in the environment block, or the empty string\r
+if it is not configured.\r
+\r
+    nssm get <servicename> AppEnvironmentExtra CLASSPATH\r
+\r
+When setting an environment block, each variable should be specified as a\r
+KEY=VALUE pair in separate command line arguments.  For example:\r
+\r
+    nssm set <servicename> AppEnvironment CLASSPATH=C:\Classes TEMP=C:\Temp\r
+\r
+\r
+The AppExit parameter requires an additional argument specifying the exit\r
+code to get or set.  The default action can be specified with the string\r
+Default.\r
+\r
+For example, to get the default exit action for a service you should run\r
+\r
+    nssm get <servicename> AppExit Default\r
+\r
+To get the exit action when the application exits with exit code 2, run\r
+\r
+    nssm get <servicename> AppExit 2\r
+\r
+Note that if no explicit action is configured for a specified exit code,\r
+NSSM will print the default exit action.\r
+\r
+To set configure the service to stop when the application exits with an\r
+exit code of 2, run\r
+\r
+    nssm set <servicename> AppExit 2 Exit\r
+\r
+\r
+The AppPriority parameter is used to set the priority class of the\r
+managed application.  Valid priorities are as follows:\r
+\r
+  REALTIME_PRIORITY_CLASS\r
+  HIGH_PRIORITY_CLASS\r
+  ABOVE_NORMAL_PRIORITY_CLASS\r
+  NORMAL_PRIORITY_CLASS\r
+  BELOW_NORMAL_PRIORITY_CLASS\r
+  IDLE_PRIORITY_CLASS\r
+\r
+\r
+The DependOnGroup and DependOnService parameters are used to query or set\r
+the dependencies for the service.  When setting dependencies, each service\r
+or service group (preceded with the + symbol) should be specified in\r
+separate command line arguments.  For example:\r
+\r
+    nssm set <servicename> DependOnService RpcSs LanmanWorkstation\r
+\r
+\r
+The Name parameter can only be queried, not set.  It returns the service's\r
+registry key name.  This may be useful to know if you take advantage of\r
+the fact that you can substitute the service's display name anywhere where\r
+the syntax calls for <servicename>.\r
+\r
+\r
+The ObjectName parameter requires an additional argument only when setting\r
+a username.  The additional argument is the password of the user.\r
+\r
+To retrieve the username, run\r
+\r
+    nssm get <servicename> ObjectName\r
+\r
+To set the username and password, run\r
+\r
+    nssm set <servicename> ObjectName <username> <password>\r
+\r
+Note that the rules of argument concatenation still apply.  The following\r
+invocation is valid and will have the expected effect.\r
+\r
+    nssm set <servicename> ObjectName <username> correct horse battery staple\r
+\r
+The following well-known usernames do not need a password.  The password\r
+parameter can be omitted when using them:\r
+\r
+  "LocalSystem" aka "System" aka "NT Authority\System"\r
+  "LocalService" aka "Local Service" aka "NT Authority\Local Service"\r
+  "NetworkService" aka "Network Service" aka "NT Authority\Network Service"\r
+\r
+\r
+The Start parameter is used to query or set the startup type of the service.\r
+Valid service startup types are as follows:\r
+\r
+  SERVICE_AUTO_START: Automatic startup at boot.\r
+  SERVICE_DELAYED_START: Delayed startup at boot.\r
+  SERVICE_DEMAND_START: Manual service startup.\r
+  SERVICE_DISABLED: The service is disabled.\r
+\r
+Note that SERVICE_DELAYED_START is not supported on versions of Windows prior\r
+to Vista.  NSSM will set the service to automatic startup if delayed start is\r
+unavailable.\r
+\r
+\r
+The Type parameter is used to query or set the service type.  NSSM recognises\r
+all currently documented service types but will only allow setting one of two\r
+types:\r
+\r
+  SERVICE_WIN32_OWN_PROCESS: A standalone service.  This is the default.\r
+  SERVICE_INTERACTIVE_PROCESS: A service which can interact with the desktop.\r
+\r
+Note that a service may only be configured as interactive if it runs under\r
+the LocalSystem account.  The safe way to configure an interactive service\r
+is in two stages as follows.\r
+\r
+    nssm reset <servicename> ObjectName\r
+    nssm set <servicename> Type SERVICE_INTERACTIVE_PROCESS\r
+\r
+\r
+Controlling services using the command line\r
+-------------------------------------------\r
+NSSM offers rudimentary service control features.\r
+\r
+    nssm start <servicename>\r
+\r
+    nssm restart <servicename>\r
+\r
+    nssm stop <servicename>\r
+\r
+    nssm status <servicename>\r
+\r
+\r
 Removing services using the GUI\r
 -------------------------------\r
 NSSM can also remove services.  Run\r
@@ -149,15 +628,39 @@ To install an Unreal Tournament server:
 \r
     nssm install UT2004 c:\games\ut2004\system\ucc.exe server\r
 \r
+To run the server as the "games" user:\r
+\r
+    nssm set UT2004 ObjectName games password\r
+\r
+To configure the server to log to a file:\r
+\r
+    nssm set UT2004 AppStdout c:\games\ut2004\service.log\r
+\r
+To restrict the server to a single CPU:\r
+\r
+    nssm set UT2004 AppAffinity 0\r
+\r
 To remove the server:\r
 \r
     nssm remove UT2004 confirm\r
 \r
+To find out the service name of a service with a display name:\r
+\r
+    nssm get "Background Intelligent Transfer Service" Name\r
+\r
 \r
 Building NSSM from source\r
 -------------------------\r
-NSSM is known to compile with Visual Studio 6, Visual Studio 2005 and Visual\r
-Studio 2008.\r
+NSSM is known to compile with Visual Studio 2008 and later.  Older Visual\r
+Studio releases may or may not work if you install an appropriate SDK and\r
+edit the nssm.vcproj and nssm.sln files to set a lower version number.\r
+They are known not to work with default settings.\r
+\r
+NSSM will also compile with Visual Studio 2010 but the resulting executable\r
+will not run on versions of Windows older than XP SP2.  If you require\r
+compatiblity with older Windows releases you should change the Platform\r
+Toolset to v90 in the General section of the project's Configuration\r
+Properties.\r
 \r
 \r
 Credits\r
@@ -168,7 +671,41 @@ Thanks to Joel Reingold for spotting a command line truncation bug.
 Thanks to Arve Knudsen for spotting that child processes of the monitored\r
 application could be left running on service shutdown, and that a missing\r
 registry value for AppDirectory confused NSSM.\r
-Thanks to Peter Wagemans and Laszlo Kereszt for suggesting throttling restarts.\r
+Thanks to Peter Wagemans and Laszlo Keresztfalvi for suggesting throttling\r
+restarts.\r
+Thanks to Eugene Lifshitz for finding an edge case in CreateProcess() and for\r
+advising how to build messages.mc correctly in paths containing spaces.\r
+Thanks to Rob Sharp for pointing out that NSSM did not respect the\r
+AppEnvironment registry value used by srvany.\r
+Thanks to Szymon Nowak for help with Windows 2000 compatibility.\r
+Thanks to François-Régis Tardy and Gildas le Nadan for French translation.\r
+Thanks to Emilio Frini for spotting that French was inadvertently set as\r
+the default language when the user's display language was not translated.\r
+Thanks to Riccardo Gusmeroli and Marco Certelli for Italian translation.\r
+Thanks to Eric Cheldelin for the inspiration to generate a Control-C event\r
+on shutdown.\r
+Thanks to Brian Baxter for suggesting how to escape quotes from the command\r
+prompt.\r
+Thanks to Russ Holmann for suggesting that the shutdown timeout be configurable.\r
+Thanks to Paul Spause for spotting a bug with default registry entries.\r
+Thanks to BUGHUNTER for spotting more GUI bugs.\r
+Thanks to Doug Watson for suggesting file rotation.\r
+Thanks to Арслан Сайдуганов for suggesting setting process priority.\r
+Thanks to Robert Middleton for suggestion and draft implementation of process\r
+affinity support.\r
+Thanks to Andrew RedzMax for suggesting an unconditional restart delay.\r
+Thanks to Bryan Senseman for noticing that applications with redirected stdout\r
+and/or stderr which attempt to read from stdin would fail.\r
+Thanks to Czenda Czendov for help with Visual Studio 2013 and Server 2012R2.\r
+Thanks to Alessandro Gherardi for reporting and draft fix of the bug whereby\r
+the second restart of the application would have a corrupted environment.\r
+Thanks to Hadrien Kohl for suggesting to disable the console window's menu.\r
+Thanks to Allen Vailliencourt for noticing bugs with configuring the service to\r
+run under a local user account.\r
+Thanks to Sam Townsend for noticing a regression with TerminateProcess().\r
+Thanks to Barrett Lewis for suggesting the option to skip terminating the\r
+application's child processes.\r
+Thanks to Miguel Angel Terrón for suggesting copy/truncate rotation.\r
 \r
 Licence\r
 -------\r