Command to exit with state code.
authorIain Patterson <me@iain.cx>
Tue, 6 Sep 2016 12:22:06 +0000 (13:22 +0100)
committerIain Patterson <me@iain.cx>
Tue, 6 Sep 2016 12:23:55 +0000 (13:23 +0100)
Use "nssm statuscode <servicename>" to set the exit code to the value of
dwCurrentState, eg 4 for running.  An exit code of 0 implies an error.

Thanks Meang Akira Tanaka.

README.txt
messages.mc
nssm.cpp
service.cpp
service.h

index fc5121e..2efc968 100644 (file)
@@ -848,6 +848,20 @@ NSSM offers rudimentary service control features.
 \r
     nssm status <servicename>\r
 \r
+    nssm statuscode <servicename>\r
+\r
+The output of "nssm status" and "nssm statuscode" is a string\r
+representing the service state, eg SERVICE_RUNNING.\r
+\r
+The exit code of "nssm status" will be 0 if the status was\r
+succesfully retrieved.  If the exit code is not zero there was\r
+an error.\r
+\r
+The exit code of "nssm statuscode" will be the numeric value\r
+of the service state, eg 4 for SERVICE_RUNNING.  Zero is not a\r
+valid service state code.  If the exit code is zero there was\r
+an error.\r
+\r
 \r
 Removing services using the GUI\r
 -------------------------------\r
@@ -1022,6 +1036,8 @@ Thanks to Bader Aldurai for suggesting the process tree.
 Thanks to Christian Long for suggesting virtual accounts.\r
 Thanks to Marcin Lewandowski for spotting a bug appending to large files.\r
 Thanks to Nicolas Ducrocq for suggesting timestamping redirected output.\r
+Thanks to Meang Akira Tanaka for suggestion and initial implementation of\r
+the statuscode command.\r
 \r
 Licence\r
 -------\r
index 14ce8df..745f466 100644 (file)
Binary files a/messages.mc and b/messages.mc differ
index d70c6b4..1f9e0ed 100644 (file)
--- a/nssm.cpp
+++ b/nssm.cpp
@@ -256,6 +256,7 @@ int _tmain(int argc, TCHAR **argv) {
     if (str_equiv(argv[1], _T("pause"))) nssm_exit(control_service(SERVICE_CONTROL_PAUSE, argc - 2, argv + 2));\r
     if (str_equiv(argv[1], _T("continue"))) nssm_exit(control_service(SERVICE_CONTROL_CONTINUE, argc - 2, argv + 2));\r
     if (str_equiv(argv[1], _T("status"))) nssm_exit(control_service(SERVICE_CONTROL_INTERROGATE, argc - 2, argv + 2));\r
+    if (str_equiv(argv[1], _T("statuscode"))) nssm_exit(control_service(SERVICE_CONTROL_INTERROGATE, argc - 2, argv + 2, true));\r
     if (str_equiv(argv[1], _T("rotate"))) nssm_exit(control_service(NSSM_SERVICE_CONTROL_ROTATE, argc - 2, argv + 2));\r
     if (str_equiv(argv[1], _T("install"))) {\r
       if (! is_admin) nssm_exit(elevate(argc, argv, NSSM_MESSAGE_NOT_ADMINISTRATOR_CANNOT_INSTALL));\r
index 937a2ec..dbac12b 100644 (file)
@@ -1360,7 +1360,7 @@ int edit_service(nssm_service_t *service, bool editing) {
 }\r
 \r
 /* Control a service. */\r
-int control_service(unsigned long control, int argc, TCHAR **argv) {\r
+int control_service(unsigned long control, int argc, TCHAR **argv, bool return_status) {\r
   if (argc < 1) return usage(1);\r
   TCHAR *service_name = argv[0];\r
   TCHAR canonical_name[SERVICE_NAME_LENGTH];\r
@@ -1368,6 +1368,7 @@ int control_service(unsigned long control, int argc, TCHAR **argv) {
   SC_HANDLE services = open_service_manager(SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE);\r
   if (! services) {\r
     print_message(stderr, NSSM_MESSAGE_OPEN_SERVICE_MANAGER_FAILED);\r
+    if (return_status) return 0;\r
     return 2;\r
   }\r
 \r
@@ -1394,6 +1395,7 @@ int control_service(unsigned long control, int argc, TCHAR **argv) {
   SC_HANDLE service_handle = open_service(services, service_name, access, canonical_name, _countof(canonical_name));\r
   if (! service_handle) {\r
     CloseServiceHandle(services);\r
+    if (return_status) return 0;\r
     return 3;\r
   }\r
 \r
@@ -1431,6 +1433,7 @@ int control_service(unsigned long control, int argc, TCHAR **argv) {
 \r
       if (response) {\r
         print_message(stderr, NSSM_MESSAGE_BAD_CONTROL_RESPONSE, canonical_name, service_status_text(service_status.dwCurrentState), service_control_text(control));\r
+        if (return_status) return 0;\r
         return 1;\r
       }\r
       else _tprintf(_T("%s: %s: %s"), canonical_name, service_control_text(control), error_string(error));\r
@@ -1439,6 +1442,7 @@ int control_service(unsigned long control, int argc, TCHAR **argv) {
     else {\r
       CloseServiceHandle(service_handle);\r
       _ftprintf(stderr, _T("%s: %s: %s"), canonical_name, service_control_text(control), error_string(error));\r
+      if (return_status) return 0;\r
       return 1;\r
     }\r
   }\r
@@ -1453,10 +1457,12 @@ int control_service(unsigned long control, int argc, TCHAR **argv) {
 \r
     if (ret) {\r
       _tprintf(_T("%s\n"), service_status_text(service_status.dwCurrentState));\r
+      if (return_status) return service_status.dwCurrentState;\r
       return 0;\r
     }\r
     else {\r
       _ftprintf(stderr, _T("%s: %s\n"), canonical_name, error_string(error));\r
+      if (return_status) return 0;\r
       return 1;\r
     }\r
   }\r
@@ -1477,22 +1483,32 @@ int control_service(unsigned long control, int argc, TCHAR **argv) {
 \r
       if (response) {\r
         print_message(stderr, NSSM_MESSAGE_BAD_CONTROL_RESPONSE, canonical_name, service_status_text(service_status.dwCurrentState), service_control_text(control));\r
+        if (return_status) return 0;\r
         return 1;\r
       }\r
       else _tprintf(_T("%s: %s: %s"), canonical_name, service_control_text(control), error_string(error));\r
+      if (return_status) return service_status.dwCurrentState;\r
       return 0;\r
     }\r
     else {\r
       CloseServiceHandle(service_handle);\r
       _ftprintf(stderr, _T("%s: %s: %s"), canonical_name, service_control_text(control), error_string(error));\r
       if (error == ERROR_SERVICE_NOT_ACTIVE) {\r
-        if (control == SERVICE_CONTROL_SHUTDOWN || control == SERVICE_CONTROL_STOP) return 0;\r
+        if (control == SERVICE_CONTROL_SHUTDOWN || control == SERVICE_CONTROL_STOP) {\r
+          if (return_status) return SERVICE_STOPPED;\r
+          return 0;\r
+        }\r
       }\r
+      if (return_status) return 0;\r
       return 1;\r
     }\r
   }\r
 }\r
 \r
+int control_service(unsigned long control, int argc, TCHAR **argv) {\r
+  return control_service(control, argc, argv, false);\r
+}\r
+\r
 /* Remove the service */\r
 int remove_service(nssm_service_t *service) {\r
   if (! service) return 1;\r
index fb8a160..46664de 100644 (file)
--- a/service.h
+++ b/service.h
@@ -156,6 +156,7 @@ int pre_edit_service(int, TCHAR **);
 int install_service(nssm_service_t *);\r
 int remove_service(nssm_service_t *);\r
 int edit_service(nssm_service_t *, bool);\r
+int control_service(unsigned long, int, TCHAR **, bool);\r
 int control_service(unsigned long, int, TCHAR **);\r
 void set_service_recovery(nssm_service_t *);\r
 int monitor_service(nssm_service_t *);\r