Let the dump command copy a service.
authorIain Patterson <me@iain.cx>
Thu, 28 Jul 2016 14:53:52 +0000 (15:53 +0100)
committerIain Patterson <me@iain.cx>
Thu, 28 Jul 2016 15:44:32 +0000 (16:44 +0100)
If an optional second argument is given to dump, the name of the service
in the output will be set to the argument's value.  In any case, an
"install" line will be written, replacing the Application dump line.

Thus a service can be copied by running:

    nssm dump <servicename> <newservicename> | %COMSPEC% /k

README.txt
service.cpp
settings.cpp

index d771faa..f8906d3 100644 (file)
@@ -882,6 +882,14 @@ quoted or escaped from the command prompt, NSSM tries hard to produce
 output which will work correctly when run as a script, by adding quotes\r
 and caret escapes as appropriate.\r
 \r
 output which will work correctly when run as a script, by adding quotes\r
 and caret escapes as appropriate.\r
 \r
+To facilitate copying a service, the dump command accepts a second\r
+argument which specifies the name of the service to be used in the output.\r
+\r
+    nssm dump <servicename> <newname>\r
+\r
+Lines in the dump will reference the <newname> service while showing the\r
+configuration of <servicename>.\r
+\r
 \r
 Example usage\r
 -------------\r
 \r
 Example usage\r
 -------------\r
index 8561616..f18626c 100644 (file)
@@ -906,7 +906,11 @@ int pre_edit_service(int argc, TCHAR **argv) {
     mandatory = 3;\r
     mode = MODE_RESETTING;\r
   }\r
     mandatory = 3;\r
     mode = MODE_RESETTING;\r
   }\r
-  else if (str_equiv(verb, _T("dump"))) mode = MODE_DUMPING;\r
+  else if (str_equiv(verb, _T("dump"))) {\r
+    mandatory = 1;\r
+    remainder = 2;\r
+    mode = MODE_DUMPING;\r
+  }\r
   if (argc < mandatory) return usage(1);\r
 \r
   const TCHAR *parameter = 0;\r
   if (argc < mandatory) return usage(1);\r
 \r
   const TCHAR *parameter = 0;\r
@@ -1056,17 +1060,27 @@ int pre_edit_service(int argc, TCHAR **argv) {
   int ret;\r
 \r
   if (mode == MODE_DUMPING) {\r
   int ret;\r
 \r
   if (mode == MODE_DUMPING) {\r
+    TCHAR *service_name = service->name;\r
+    if (argc > remainder) service_name = argv[remainder];\r
     if (service->native) key = 0;\r
     else {\r
       key = open_registry(service->name, KEY_READ);\r
       if (! key) return 4;\r
     }\r
 \r
     if (service->native) key = 0;\r
     else {\r
       key = open_registry(service->name, KEY_READ);\r
       if (! key) return 4;\r
     }\r
 \r
+    TCHAR quoted_service_name[SERVICE_NAME_LENGTH * 2];\r
+    TCHAR quoted_exe[EXE_LENGTH * 2];\r
+    TCHAR quoted_nssm[EXE_LENGTH * 2];\r
+    if (quote(service_name, quoted_service_name, _countof(quoted_service_name))) return 5;\r
+    if (quote(service->exe, quoted_exe, _countof(quoted_exe))) return 6;\r
+    if (quote(nssm_exe(), quoted_nssm, _countof(quoted_nssm))) return 6;\r
+    _tprintf(_T("%s install %s %s\n"), quoted_nssm, quoted_service_name, quoted_exe);\r
+\r
     ret = 0;\r
     for (i = 0; settings[i].name; i++) {\r
       setting = &settings[i];\r
       if (! setting->native && service->native) continue;\r
     ret = 0;\r
     for (i = 0; settings[i].name; i++) {\r
       setting = &settings[i];\r
       if (! setting->native && service->native) continue;\r
-      if (dump_setting(service->name, key, service->handle, setting)) ret++;\r
+      if (dump_setting(service_name, key, service->handle, setting)) ret++;\r
     }\r
 \r
     if (! service->native) RegCloseKey(key);\r
     }\r
 \r
     if (! service->native) RegCloseKey(key);\r
index f22a04d..f7346cb 100644 (file)
@@ -1386,7 +1386,7 @@ int dump_setting(const TCHAR *service_name, HKEY key, SC_HANDLE service_handle,
 }\r
 \r
 settings_t settings[] = {\r
 }\r
 \r
 settings_t settings[] = {\r
-  { NSSM_REG_EXE, REG_EXPAND_SZ, (void *) _T(""), false, 0, setting_set_string, setting_get_string, 0 },\r
+  { NSSM_REG_EXE, REG_EXPAND_SZ, (void *) _T(""), false, 0, setting_set_string, setting_get_string, setting_not_dumpable },\r
   { NSSM_REG_FLAGS, REG_EXPAND_SZ, (void *) _T(""), false, 0, setting_set_string, setting_get_string, 0 },\r
   { NSSM_REG_DIR, REG_EXPAND_SZ, (void *) _T(""), false, 0, setting_set_string, setting_get_string, 0 },\r
   { NSSM_REG_EXIT, REG_SZ, (void *) exit_action_strings[NSSM_EXIT_RESTART], false, ADDITIONAL_MANDATORY, setting_set_exit_action, setting_get_exit_action, setting_dump_exit_action },\r
   { NSSM_REG_FLAGS, REG_EXPAND_SZ, (void *) _T(""), false, 0, setting_set_string, setting_get_string, 0 },\r
   { NSSM_REG_DIR, REG_EXPAND_SZ, (void *) _T(""), false, 0, setting_set_string, setting_get_string, 0 },\r
   { NSSM_REG_EXIT, REG_SZ, (void *) exit_action_strings[NSSM_EXIT_RESTART], false, ADDITIONAL_MANDATORY, setting_set_exit_action, setting_get_exit_action, setting_dump_exit_action },\r