Преглед изворни кода

Command to exit with state code.

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.
Iain Patterson пре 7 година
родитељ
комит
a2f02c89be
5 измењених фајлова са 36 додато и 2 уклоњено
  1. 16 0
      README.txt
  2. BIN
      messages.mc
  3. 1 0
      nssm.cpp
  4. 18 2
      service.cpp
  5. 1 0
      service.h

+ 16 - 0
README.txt

@@ -848,6 +848,20 @@ NSSM offers rudimentary service control features.
 
 
     nssm status <servicename>
     nssm status <servicename>
 
 
+    nssm statuscode <servicename>
+
+The output of "nssm status" and "nssm statuscode" is a string
+representing the service state, eg SERVICE_RUNNING.
+
+The exit code of "nssm status" will be 0 if the status was
+succesfully retrieved.  If the exit code is not zero there was
+an error.
+
+The exit code of "nssm statuscode" will be the numeric value
+of the service state, eg 4 for SERVICE_RUNNING.  Zero is not a
+valid service state code.  If the exit code is zero there was
+an error.
+
 
 
 Removing services using the GUI
 Removing services using the GUI
 -------------------------------
 -------------------------------
@@ -1022,6 +1036,8 @@ Thanks to Bader Aldurai for suggesting the process tree.
 Thanks to Christian Long for suggesting virtual accounts.
 Thanks to Christian Long for suggesting virtual accounts.
 Thanks to Marcin Lewandowski for spotting a bug appending to large files.
 Thanks to Marcin Lewandowski for spotting a bug appending to large files.
 Thanks to Nicolas Ducrocq for suggesting timestamping redirected output.
 Thanks to Nicolas Ducrocq for suggesting timestamping redirected output.
+Thanks to Meang Akira Tanaka for suggestion and initial implementation of
+the statuscode command.
 
 
 Licence
 Licence
 -------
 -------


+ 1 - 0
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));
     if (str_equiv(argv[1], _T("pause"))) nssm_exit(control_service(SERVICE_CONTROL_PAUSE, argc - 2, argv + 2));
     if (str_equiv(argv[1], _T("continue"))) nssm_exit(control_service(SERVICE_CONTROL_CONTINUE, argc - 2, argv + 2));
     if (str_equiv(argv[1], _T("continue"))) nssm_exit(control_service(SERVICE_CONTROL_CONTINUE, argc - 2, argv + 2));
     if (str_equiv(argv[1], _T("status"))) nssm_exit(control_service(SERVICE_CONTROL_INTERROGATE, argc - 2, argv + 2));
     if (str_equiv(argv[1], _T("status"))) nssm_exit(control_service(SERVICE_CONTROL_INTERROGATE, argc - 2, argv + 2));
+    if (str_equiv(argv[1], _T("statuscode"))) nssm_exit(control_service(SERVICE_CONTROL_INTERROGATE, argc - 2, argv + 2, true));
     if (str_equiv(argv[1], _T("rotate"))) nssm_exit(control_service(NSSM_SERVICE_CONTROL_ROTATE, argc - 2, argv + 2));
     if (str_equiv(argv[1], _T("rotate"))) nssm_exit(control_service(NSSM_SERVICE_CONTROL_ROTATE, argc - 2, argv + 2));
     if (str_equiv(argv[1], _T("install"))) {
     if (str_equiv(argv[1], _T("install"))) {
       if (! is_admin) nssm_exit(elevate(argc, argv, NSSM_MESSAGE_NOT_ADMINISTRATOR_CANNOT_INSTALL));
       if (! is_admin) nssm_exit(elevate(argc, argv, NSSM_MESSAGE_NOT_ADMINISTRATOR_CANNOT_INSTALL));

+ 18 - 2
service.cpp

@@ -1360,7 +1360,7 @@ int edit_service(nssm_service_t *service, bool editing) {
 }
 }
 
 
 /* Control a service. */
 /* Control a service. */
-int control_service(unsigned long control, int argc, TCHAR **argv) {
+int control_service(unsigned long control, int argc, TCHAR **argv, bool return_status) {
   if (argc < 1) return usage(1);
   if (argc < 1) return usage(1);
   TCHAR *service_name = argv[0];
   TCHAR *service_name = argv[0];
   TCHAR canonical_name[SERVICE_NAME_LENGTH];
   TCHAR canonical_name[SERVICE_NAME_LENGTH];
@@ -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);
   SC_HANDLE services = open_service_manager(SC_MANAGER_CONNECT | SC_MANAGER_ENUMERATE_SERVICE);
   if (! services) {
   if (! services) {
     print_message(stderr, NSSM_MESSAGE_OPEN_SERVICE_MANAGER_FAILED);
     print_message(stderr, NSSM_MESSAGE_OPEN_SERVICE_MANAGER_FAILED);
+    if (return_status) return 0;
     return 2;
     return 2;
   }
   }
 
 
@@ -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));
   SC_HANDLE service_handle = open_service(services, service_name, access, canonical_name, _countof(canonical_name));
   if (! service_handle) {
   if (! service_handle) {
     CloseServiceHandle(services);
     CloseServiceHandle(services);
+    if (return_status) return 0;
     return 3;
     return 3;
   }
   }
 
 
@@ -1431,6 +1433,7 @@ int control_service(unsigned long control, int argc, TCHAR **argv) {
 
 
       if (response) {
       if (response) {
         print_message(stderr, NSSM_MESSAGE_BAD_CONTROL_RESPONSE, canonical_name, service_status_text(service_status.dwCurrentState), service_control_text(control));
         print_message(stderr, NSSM_MESSAGE_BAD_CONTROL_RESPONSE, canonical_name, service_status_text(service_status.dwCurrentState), service_control_text(control));
+        if (return_status) return 0;
         return 1;
         return 1;
       }
       }
       else _tprintf(_T("%s: %s: %s"), canonical_name, service_control_text(control), error_string(error));
       else _tprintf(_T("%s: %s: %s"), canonical_name, service_control_text(control), error_string(error));
@@ -1439,6 +1442,7 @@ int control_service(unsigned long control, int argc, TCHAR **argv) {
     else {
     else {
       CloseServiceHandle(service_handle);
       CloseServiceHandle(service_handle);
       _ftprintf(stderr, _T("%s: %s: %s"), canonical_name, service_control_text(control), error_string(error));
       _ftprintf(stderr, _T("%s: %s: %s"), canonical_name, service_control_text(control), error_string(error));
+      if (return_status) return 0;
       return 1;
       return 1;
     }
     }
   }
   }
@@ -1453,10 +1457,12 @@ int control_service(unsigned long control, int argc, TCHAR **argv) {
 
 
     if (ret) {
     if (ret) {
       _tprintf(_T("%s\n"), service_status_text(service_status.dwCurrentState));
       _tprintf(_T("%s\n"), service_status_text(service_status.dwCurrentState));
+      if (return_status) return service_status.dwCurrentState;
       return 0;
       return 0;
     }
     }
     else {
     else {
       _ftprintf(stderr, _T("%s: %s\n"), canonical_name, error_string(error));
       _ftprintf(stderr, _T("%s: %s\n"), canonical_name, error_string(error));
+      if (return_status) return 0;
       return 1;
       return 1;
     }
     }
   }
   }
@@ -1477,22 +1483,32 @@ int control_service(unsigned long control, int argc, TCHAR **argv) {
 
 
       if (response) {
       if (response) {
         print_message(stderr, NSSM_MESSAGE_BAD_CONTROL_RESPONSE, canonical_name, service_status_text(service_status.dwCurrentState), service_control_text(control));
         print_message(stderr, NSSM_MESSAGE_BAD_CONTROL_RESPONSE, canonical_name, service_status_text(service_status.dwCurrentState), service_control_text(control));
+        if (return_status) return 0;
         return 1;
         return 1;
       }
       }
       else _tprintf(_T("%s: %s: %s"), canonical_name, service_control_text(control), error_string(error));
       else _tprintf(_T("%s: %s: %s"), canonical_name, service_control_text(control), error_string(error));
+      if (return_status) return service_status.dwCurrentState;
       return 0;
       return 0;
     }
     }
     else {
     else {
       CloseServiceHandle(service_handle);
       CloseServiceHandle(service_handle);
       _ftprintf(stderr, _T("%s: %s: %s"), canonical_name, service_control_text(control), error_string(error));
       _ftprintf(stderr, _T("%s: %s: %s"), canonical_name, service_control_text(control), error_string(error));
       if (error == ERROR_SERVICE_NOT_ACTIVE) {
       if (error == ERROR_SERVICE_NOT_ACTIVE) {
-        if (control == SERVICE_CONTROL_SHUTDOWN || control == SERVICE_CONTROL_STOP) return 0;
+        if (control == SERVICE_CONTROL_SHUTDOWN || control == SERVICE_CONTROL_STOP) {
+          if (return_status) return SERVICE_STOPPED;
+          return 0;
+        }
       }
       }
+      if (return_status) return 0;
       return 1;
       return 1;
     }
     }
   }
   }
 }
 }
 
 
+int control_service(unsigned long control, int argc, TCHAR **argv) {
+  return control_service(control, argc, argv, false);
+}
+
 /* Remove the service */
 /* Remove the service */
 int remove_service(nssm_service_t *service) {
 int remove_service(nssm_service_t *service) {
   if (! service) return 1;
   if (! service) return 1;

+ 1 - 0
service.h

@@ -156,6 +156,7 @@ int pre_edit_service(int, TCHAR **);
 int install_service(nssm_service_t *);
 int install_service(nssm_service_t *);
 int remove_service(nssm_service_t *);
 int remove_service(nssm_service_t *);
 int edit_service(nssm_service_t *, bool);
 int edit_service(nssm_service_t *, bool);
+int control_service(unsigned long, int, TCHAR **, bool);
 int control_service(unsigned long, int, TCHAR **);
 int control_service(unsigned long, int, TCHAR **);
 void set_service_recovery(nssm_service_t *);
 void set_service_recovery(nssm_service_t *);
 int monitor_service(nssm_service_t *);
 int monitor_service(nssm_service_t *);