Browse Source

Localised (almost) all messages.

Use FormatMessage() to localise messages printed to the console or shown
in MessageBoxes.

The new messages are allocated IDs starting at 501 so as not to clash
with event log messages starting at 1001.

Once again French translations were provided by François-Régis Tardy.
Iain Patterson 10 years ago
parent
commit
f2ec1c0c55
6 changed files with 432 additions and 55 deletions
  1. 49 0
      event.cpp
  2. 3 0
      event.h
  3. 40 26
      gui.cpp
  4. 320 0
      messages.mc
  5. 8 17
      nssm.cpp
  6. 12 12
      service.cpp

+ 49 - 0
event.cpp

@@ -19,6 +19,16 @@ char *error_string(unsigned long error) {
   return error_message;
 }
 
+/* Convert message code to format string */
+char *message_string(unsigned long error) {
+  char *ret;
+  if (! FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE | FORMAT_MESSAGE_IGNORE_INSERTS, 0, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR) &ret, NSSM_ERROR_BUFSIZE, 0)) {
+    ret = (char *) HeapAlloc(GetProcessHeap(), 0, 32);
+    if (_snprintf(ret, NSSM_ERROR_BUFSIZE, "system error %lu", error) < 0) return 0;
+  }
+  return ret;
+}
+
 /* Log a message to the Event Log */
 void log_event(unsigned short type, unsigned long id, ...) {
   va_list arg;
@@ -40,3 +50,42 @@ void log_event(unsigned short type, unsigned long id, ...) {
   /* Close event log */
   DeregisterEventSource(handle);
 }
+
+/* Log a message to the console */
+void print_message(FILE *file, unsigned long id, ...) {
+  va_list arg;
+
+  char *format = message_string(id);
+  if (! format) return;
+
+  va_start(arg, id);
+  vfprintf(file, format, arg);
+  va_end(arg);
+
+  LocalFree(format);
+}
+
+/* Show a GUI dialogue */
+int popup_message(unsigned int type, unsigned long id, ...) {
+  va_list arg;
+
+  char *format = message_string(id);
+  if (! format) {
+    return MessageBox(0, "Message %lu was supposed to go here!", NSSM, MB_OK | MB_ICONEXCLAMATION);
+  }
+
+  char blurb[256];
+  va_start(arg, id);
+  if (vsnprintf(blurb, sizeof(blurb), format, arg) < 0) {
+    va_end(arg);
+    LocalFree(format);
+    return MessageBox(0, "Message %lu was supposed to go here!", NSSM, MB_OK | MB_ICONEXCLAMATION);
+  }
+  va_end(arg);
+
+  int ret = MessageBox(0, blurb, NSSM, type);
+
+  LocalFree(format);
+
+  return ret;
+}

+ 3 - 0
event.h

@@ -2,6 +2,9 @@
 #define EVENT_H
 
 char *error_string(unsigned long);
+char *message_string(unsigned long);
 void log_event(unsigned short, unsigned long, ...);
+void print_message(FILE *, unsigned long, ...);
+int popup_message(unsigned int, unsigned long, ...);
 
 #endif

+ 40 - 26
gui.cpp

@@ -1,13 +1,10 @@
 #include "nssm.h"
 
 int nssm_gui(int resource, char *name) {
-  char blurb[256];
-
   /* Create window */
   HWND dlg = CreateDialog(0, MAKEINTRESOURCE(resource), 0, install_dlg);
   if (! dlg) {
-    _snprintf(blurb, sizeof(blurb), "CreateDialog() failed with error code %d", GetLastError());
-    MessageBox(0, blurb, NSSM, MB_OK);
+    popup_message(MB_OK, NSSM_GUI_CREATEDIALOG_FAILED, error_string(GetLastError()));
     return 1;
   }
 
@@ -72,20 +69,20 @@ int install(HWND window) {
 
   /* Get service name */
   if (! GetDlgItemText(window, IDC_NAME, name, sizeof(name))) {
-    MessageBox(0, "No valid service name was specified!", NSSM, MB_OK);
+    popup_message(MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_SERVICE_NAME);
     return 2;
   }
 
   /* Get executable name */
   if (! GetDlgItemText(window, IDC_PATH, exe, sizeof(exe))) {
-    MessageBox(0, "No valid executable path was specified!", NSSM, MB_OK);
+    popup_message(MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_PATH);
     return 3;
   }
 
   /* Get flags */
   if (SendMessage(GetDlgItem(window, IDC_FLAGS), WM_GETTEXTLENGTH, 0, 0)) {
     if (! GetDlgItemText(window, IDC_FLAGS, flags, sizeof(flags))) {
-      MessageBox(0, "No valid options were specified!", NSSM, MB_OK);
+      popup_message(MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INVALID_OPTIONS);
       return 4;
     }
   }
@@ -94,27 +91,27 @@ int install(HWND window) {
   /* See if it works */
   switch (install_service(name, exe, flags)) {
     case 2:
-      MessageBox(0, "Can't open service manager!\nPerhaps you need to be an administrator...", NSSM, MB_OK);
+      popup_message(MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_OPEN_SERVICE_MANAGER_FAILED);
       return 2;
 
     case 3:
-      MessageBox(0, "Path too long!\nThe full path to " NSSM " is too long.\nPlease install " NSSM " somewhere else...\n", NSSM, MB_OK);
+      popup_message(MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_PATH_TOO_LONG, NSSM);
       return 3;
 
     case 4:
-      MessageBox(0, "Error constructing ImagePath!\nThis really shouldn't happen.  You could be out of memory\nor the world may be about to end or something equally bad.", NSSM, MB_OK);
+      popup_message(MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_OUT_OF_MEMORY_FOR_IMAGEPATH);
       return 4;
 
     case 5:
-      MessageBox(0, "Couldn't create service!\nPerhaps it is already installed...", NSSM, MB_OK);
+      popup_message(MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_INSTALL_SERVICE_FAILED);
       return 5;
 
     case 6:
-      MessageBox(0, "Couldn't set startup parameters for the service!\nDeleting the service...", NSSM, MB_OK);
+      popup_message(MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_CREATE_PARAMETERS_FAILED);
       return 6;
   }
 
-  MessageBox(0, "Service successfully installed!", NSSM, MB_OK);
+  popup_message(MB_OK, NSSM_MESSAGE_SERVICE_INSTALLED, name);
   return 0;
 }
 
@@ -127,53 +124,70 @@ int remove(HWND window) {
 
   /* Get service name */
   if (! GetDlgItemText(window, IDC_NAME, name, sizeof(name))) {
-    MessageBox(0, "No valid service name was specified!", NSSM, MB_OK);
+    popup_message(MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_MISSING_SERVICE_NAME);
     return 2;
   }
 
   /* Confirm */
-  char blurb[MAX_PATH];
-  if (_snprintf(blurb, sizeof(blurb), "Remove the \"%s\" service?", name) < 0) {
-    if (MessageBox(0, "Remove the service?", NSSM, MB_YESNO) != IDYES) return 0;
-  }
-  else if (MessageBox(0, blurb, NSSM, MB_YESNO) != IDYES) return 0;
+  if (popup_message(MB_YESNO, NSSM_GUI_ASK_REMOVE_SERVICE, name) != IDYES) return 0;
 
   /* See if it works */
   switch (remove_service(name)) {
     case 2:
-      MessageBox(0, "Can't open service manager!\nPerhaps you need to be an administrator...", NSSM, MB_OK);
+      popup_message(MB_OK | MB_ICONEXCLAMATION, NSSM_MESSAGE_OPEN_SERVICE_MANAGER_FAILED);
       return 2;
 
     case 3:
-      MessageBox(0, "Can't open service!\nPerhaps it isn't installed...", NSSM, MB_OK);
+      popup_message(MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_SERVICE_NOT_INSTALLED);
       return 3;
 
     case 4:
-      MessageBox(0, "Can't delete service!  Make sure the service is stopped and try again.\nIf this error persists, you may need to set the service NOT to start\nautomatically, reboot your computer and try removing it again.", NSSM, MB_OK);
+      popup_message(MB_OK | MB_ICONEXCLAMATION, NSSM_GUI_REMOVE_SERVICE_FAILED);
       return 4;
   }
 
-  MessageBox(0, "Service successfully removed!", NSSM, MB_OK);
+  popup_message(MB_OK, NSSM_MESSAGE_SERVICE_REMOVED, name);
   return 0;
 }
 
-/* Browse for game */
+/* Browse for application */
 void browse(HWND window) {
   if (! window) return;
 
+  unsigned long bufsize = 256;
+  unsigned long len = bufsize;
   OPENFILENAME ofn;
   ZeroMemory(&ofn, sizeof(ofn));
   ofn.lStructSize = sizeof(ofn);
-  ofn.lpstrFilter = "Applications\0*.exe\0All files\0*.*\0\0";
+  ofn.lpstrFilter = (char *) HeapAlloc(GetProcessHeap(), 0, bufsize);
+  /* XXX: Escaping nulls with FormatMessage is tricky */
+  if (ofn.lpstrFilter) {
+    ZeroMemory((void *) ofn.lpstrFilter, bufsize);
+    char *localised = message_string(NSSM_GUI_BROWSE_FILTER_APPLICATIONS);
+    _snprintf((char *) ofn.lpstrFilter, bufsize, localised);
+    /* "Applications" + NULL + "*.exe" + NULL */
+    len = strlen(localised) + 1;
+    LocalFree(localised);
+    _snprintf((char *) ofn.lpstrFilter + len, bufsize - len, "*.exe");
+    /* "All files" + NULL + "*.*" + NULL */
+    len += 6;
+    localised = message_string(NSSM_GUI_BROWSE_FILTER_ALL_FILES);
+    _snprintf((char *) ofn.lpstrFilter + len, bufsize - len, localised);
+    len += strlen(localised) + 1;
+    LocalFree(localised);
+    _snprintf((char *) ofn.lpstrFilter + len, bufsize - len, "*.*");
+    /* Remainder of the buffer is already zeroed */
+  }
   ofn.lpstrFile = new char[MAX_PATH];
   ofn.lpstrFile[0] = '\0';
-  ofn.lpstrTitle = "Locate application file";
+  ofn.lpstrTitle = message_string(NSSM_GUI_BROWSE_TITLE);
   ofn.nMaxFile = MAX_PATH;
   ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY;
 
   if (GetOpenFileName(&ofn)) {
     SendMessage(window, WM_SETTEXT, 0, (LPARAM) ofn.lpstrFile);
   }
+  if (ofn.lpstrFilter) HeapFree(GetProcessHeap(), 0, (void *) ofn.lpstrFilter);
 
   delete[] ofn.lpstrFile;
 }

+ 320 - 0
messages.mc

@@ -4,6 +4,326 @@ English=0x0409:MSG00409
 French=0x40C:MSG0040C
 )
 
+MessageId = 501
+SymbolicName = NSSM_MESSAGE_USAGE
+Severity = Informational
+Language = English
+NSSM: The non-sucking service manager
+Version %s, %s
+Usage: nssm <option> [args]
+
+To show service installation GUI:
+
+        nssm install [<servicename>]
+
+To install a service without confirmation:
+
+        nssm install <servicename> <app> [<args>]
+
+To show service removal GUI:
+
+        nssm remove [<servicename>]
+
+To remove a service without confirmation:
+
+        nssm remove <servicename> confirm
+.
+Language = French
+NSSM: Le gestionnaire de services Windows pour les professionnels!
+Version %s, %s
+Syntaxe: nssm <option> [arguments]
+
+Pour afficher l'écran d'installation du service:
+
+        nssm install [<nom_du_service>]
+
+Pour installer un service sans confirmation:
+
+        nssm install <nom_du_service> <application> [<arguments>]
+
+Pour afficher l'écran de désinstallation du service:
+
+        nssm remove [<nom_du_service>]
+
+Pour désinstaller un service sans confirmation:
+
+        nssm remove <nom_du_service> confirm
+.
+
+MessageId = +1
+SymbolicName = NSSM_MESSAGE_NOT_ADMINISTRATOR_CANNOT_INSTALL
+Severity = Informational
+Language = English
+Administrator access is needed to install a service.
+.
+Language = French
+Les droits d'administrateur sont requis pour installer un service.
+.
+
+MessageId = +1
+SymbolicName = NSSM_MESSAGE_NOT_ADMINISTRATOR_CANNOT_REMOVE
+Severity = Informational
+Language = English
+Administrator access is needed to remove a service.
+.
+Language = French
+Les droits d'administrateur sont requis pour désinstaller un service.
+.
+
+MessageId = +1
+SymbolicName = NSSM_MESSAGE_PRE_REMOVE_SERVICE
+Severity = Informational
+Language = English
+To remove a service without confirmation: nssm remove <servicename> confirm
+.
+Language = French
+Pour désinstaller un service sans confirmation: nssm remove <nom_du_service> confirm
+.
+
+MessageId = +1
+SymbolicName = NSSM_MESSAGE_OPEN_SERVICE_MANAGER_FAILED
+Severity = Informational
+Language = English
+Error opening service manager!
+.
+Language = French
+Erreur à l'ouverture du gestionnaire de services!
+.
+
+MessageId = +1
+SymbolicName = NSSM_MESSAGE_PATH_TOO_LONG
+Severity = Informational
+Language = English
+The full path to %s is too long!
+.
+Language = French
+Le chemin complet vers %s est trop long!
+.
+
+MessageId = +1
+SymbolicName = NSSM_MESSAGE_OUT_OF_MEMORY_FOR_IMAGEPATH
+Severity = Informational
+Language = English
+Out of memory for ImagePath!
+.
+Language = French
+Mémoire insuffisante pour spécifier le chemin de l'image (ImagePath)!
+.
+
+MessageId = +1
+SymbolicName = NSSM_MESSAGE_CREATESERVICE_FAILED
+Severity = Informational
+Language = English
+Error creating service!
+.
+Language = French
+Erreur à la création du service!
+.
+
+MessageId = +1
+SymbolicName = NSSM_MESSAGE_CREATE_PARAMETERS_FAILED
+Severity = Informational
+Language = English
+Error setting startup parameters for the service!
+.
+Language = French
+Erreur en essayant de régler les paramètres de démarrage du service!
+.
+
+MessageId = +1
+SymbolicName = NSSM_MESSAGE_SERVICE_INSTALLED
+Severity = Informational
+Language = English
+Service "%s" installed successfully!
+.
+Language = French
+Le service "%s" a été installé avec succès!
+.
+
+MessageId = +1
+SymbolicName = NSSM_MESSAGE_OPENSERVICE_FAILED
+Severity = Informational
+Language = English
+Can't open service!
+.
+Language = French
+Impossible d'ouvrir le service!
+.
+
+MessageId = +1
+SymbolicName = NSSM_MESSAGE_DELETESERVICE_FAILED
+Severity = Informational
+Language = English
+Error deleting service!
+.
+Language = French
+Erreur à la suppression du service!
+.
+
+MessageId = +1
+SymbolicName = NSSM_MESSAGE_SERVICE_REMOVED
+Severity = Informational
+Language = English
+Service "%s" removed successfully!
+.
+Language = French
+Le service "%s" a été désinstallé avec succès!
+.
+
+MessageId = +1
+SymbolicName = NSSM_GUI_CREATEDIALOG_FAILED
+Severity = Informational
+Language = English
+CreateDialog() failed:
+%s
+.
+Language = French
+CreateDialog() a échoué:
+%s
+.
+
+MessageId = +1
+SymbolicName = NSSM_GUI_MISSING_SERVICE_NAME
+Severity = Informational
+Language = English
+No valid service name was specified!
+.
+Language = French
+Aucun nom de service valide n'a été spécifié!
+.
+
+MessageId = +1
+SymbolicName = NSSM_GUI_MISSING_PATH
+Severity = Informational
+Language = English
+No valid executable path was specified!
+.
+Language = French
+Aucun chemin valide de fichier exécutable n'a été spécifié!
+.
+
+MessageId = +1
+SymbolicName = NSSM_GUI_INVALID_OPTIONS
+Severity = Informational
+Language = English
+No valid options were specified!
+.
+Language = French
+Aucun option valide n'a été spécifiée!
+.
+
+MessageId = +1
+SymbolicName = NSSM_GUI_OUT_OF_MEMORY_FOR_IMAGEPATH
+Severity = Informational
+Language = English
+Error constructing ImagePath!\nThis really shouldn't happen.  You could be out of memory
+or the world may be about to end or something equally bad.
+.
+Language = French
+Mémoire insuffisante pour spécifier le chemin de l'image (ImagePath)!
+Cette situation ne devrait jamais se produire.  Vous êtes peut-être à court de mémoire RAM,
+ou la fin du monde est proche, ou un autre désastre du même type.
+.
+
+MessageId = +1
+SymbolicName = NSSM_GUI_INSTALL_SERVICE_FAILED
+Severity = Informational
+Language = English
+Couldn't create service!
+Perhaps it is already installed...
+.
+Language = French
+Impossible de créer le service!
+Peut-être est-il déjà installé...
+.
+
+MessageId = +1
+SymbolicName = NSSM_GUI_CREATE_PARAMETERS_FAILED
+Severity = Informational
+Language = English
+Couldn't set startup parameters for the service!
+Deleting the service...
+.
+Language = French
+Impossible de régler les paramètres de démarrage pour le service!
+Suppression du dit service...
+.
+
+MessageId = +1
+SymbolicName = NSSM_GUI_ASK_REMOVE_SERVICE
+Severity = Informational
+Language = English
+.
+Language = French
+Supprimer le service "%s" ?
+.
+
+MessageId = +1
+SymbolicName = NSSM_GUI_SERVICE_NOT_INSTALLED
+Severity = Informational
+Language = English
+Can't open service!
+Perhaps it isn't installed...
+.
+Language = French
+Impossible d'ouvrir le service!
+Celui-ci n'est peut-être pas installé...
+.
+
+MessageId = +1
+SymbolicName = NSSM_GUI_REMOVE_SERVICE_FAILED
+Severity = Informational
+Language = English
+Can't delete service!  Make sure the service is stopped and try again.
+If this error persists, you may need to set the service NOT to start
+automatically, reboot your computer and try removing it again.
+.
+Language = French
+Impossible de supprimer le service!  Assurez-vous que ce service est arrêté et réessayez.
+Si cette erreur persiste, réglez ce service en lancement MANUEL
+(non automatique), redémarrez votre ordinateur et tentez de nouveau la suppression.
+.
+
+MessageId = +1
+SymbolicName = NSSM_GUI_BROWSE_FILTER
+Severity = Informational
+Language = English
+Applications%sAll files%s%0
+.
+Language = French
+Applications%sTous les fichiers%s%0
+.
+
+MessageId = +1
+SymbolicName = NSSM_GUI_BROWSE_FILTER_APPLICATIONS
+Severity = Informational
+Language = English
+Applications%0
+.
+Language = French
+Applications%0
+.
+
+MessageId = +1
+SymbolicName = NSSM_GUI_BROWSE_FILTER_ALL_FILES
+Severity = Informational
+Language = English
+All files%0
+.
+Language = French
+Tous les fichiers%0
+.
+
+MessageId = +1
+SymbolicName = NSSM_GUI_BROWSE_TITLE
+Severity = Informational
+Language = English
+Locate application file
+.
+Language = French
+Indiquez le fichier exécutable
+.
+
 MessageId = 1001
 SymbolicName = NSSM_EVENT_DISPATCHER_FAILED
 Severity = Error

+ 8 - 17
nssm.cpp

@@ -14,17 +14,7 @@ int str_equiv(const char *a, const char *b) {
 
 /* How to use me correctly */
 int usage(int ret) {
-  fprintf(stderr, "NSSM: The non-sucking service manager\n");
-  fprintf(stderr, "Version %s, %s\n", NSSM_VERSION, NSSM_DATE);
-  fprintf(stderr, "Usage: nssm <option> [args]\n\n");
-  fprintf(stderr, "To show service installation GUI:\n\n");
-  fprintf(stderr, "        nssm install [<servicename>]\n\n");
-  fprintf(stderr, "To install a service without confirmation:\n\n");
-  fprintf(stderr, "        nssm install <servicename> <app> [<args>]\n\n");
-  fprintf(stderr, "To show service removal GUI:\n\n");
-  fprintf(stderr, "        nssm remove [<servicename>]\n\n");
-  fprintf(stderr, "To remove a service without confirmation:\n\n");
-  fprintf(stderr, "        nssm remove <servicename> confirm\n");
+  print_message(stderr, NSSM_MESSAGE_USAGE, NSSM_VERSION, NSSM_DATE);
   return(ret);
 }
 
@@ -45,18 +35,19 @@ int main(int argc, char **argv) {
 
   /* Elevate */
   if (argc > 1) {
-    if (str_equiv(argv[1], "install") || str_equiv(argv[1], "remove")) {
+    /* Valid commands are install or remove */
+    if (str_equiv(argv[1], "install")) {
       if (! is_admin) {
-        fprintf(stderr, "Administrator access is needed to %s a service.\n", argv[1]);
+        print_message(stderr, NSSM_MESSAGE_NOT_ADMINISTRATOR_CANNOT_INSTALL);
         exit(100);
       }
-    }
-
-    /* Valid commands are install or remove */
-    if (str_equiv(argv[1], "install")) {
       exit(pre_install_service(argc - 2, argv + 2));
     }
     if (str_equiv(argv[1], "remove")) {
+      if (! is_admin) {
+        print_message(stderr, NSSM_MESSAGE_NOT_ADMINISTRATOR_CANNOT_REMOVE);
+        exit(100);
+      }
       exit(pre_remove_service(argc - 2, argv + 2));
     }
   }

+ 12 - 12
service.cpp

@@ -39,7 +39,7 @@ SC_HANDLE open_service_manager() {
 
 /* About to install the service */
 int pre_install_service(int argc, char **argv) {
-  /* Show the dialogue box if we didn't give the */
+  /* Show the dialogue box if we didn't give the service name and path */
   if (argc < 2) return nssm_gui(IDD_INSTALL, argv[0]);
 
   /* Arguments are optional */
@@ -78,7 +78,7 @@ int pre_remove_service(int argc, char **argv) {
   /* Show dialogue box if we didn't pass service name and "confirm" */
   if (argc < 2) return nssm_gui(IDD_REMOVE, argv[0]);
   if (str_equiv(argv[1], "confirm")) return remove_service(argv[0]);
-  fprintf(stderr, "To remove a service without confirmation: nssm remove <servicename> confirm\n");
+  print_message(stderr, NSSM_MESSAGE_PRE_REMOVE_SERVICE);
   return 100;
 }
 
@@ -87,7 +87,7 @@ int install_service(char *name, char *exe, char *flags) {
   /* Open service manager */
   SC_HANDLE services = open_service_manager();
   if (! services) {
-    fprintf(stderr, "Error opening service manager!\n");
+    print_message(stderr, NSSM_MESSAGE_OPEN_SERVICE_MANAGER_FAILED);
     return 2;
   }
   
@@ -99,11 +99,11 @@ int install_service(char *name, char *exe, char *flags) {
   char command[CMD_LENGTH];
   size_t pathlen = strlen(path);
   if (pathlen + 1 >= VALUE_LENGTH) {
-    fprintf(stderr, "The full path to " NSSM " is too long!\n");
+    print_message(stderr, NSSM_MESSAGE_PATH_TOO_LONG, NSSM);
     return 3;
   }
   if (_snprintf(command, sizeof(command), "\"%s\"", path) < 0) {
-    fprintf(stderr, "Out of memory for ImagePath!\n");
+    print_message(stderr, NSSM_MESSAGE_OUT_OF_MEMORY_FOR_IMAGEPATH);
     return 4;
   }
 
@@ -118,14 +118,14 @@ int install_service(char *name, char *exe, char *flags) {
   /* Create the service */
   SC_HANDLE service = CreateService(services, name, name, SC_MANAGER_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, command, 0, 0, 0, 0, 0);
   if (! service) {
-    fprintf(stderr, "Error creating service!\n");
+    print_message(stderr, NSSM_MESSAGE_CREATESERVICE_FAILED);
     CloseServiceHandle(services);
     return 5;
   }
 
   /* Now we need to put the parameters into the registry */
   if (create_parameters(name, exe, flags, dir)) {
-    fprintf(stderr, "Error setting startup parameters for the service!\n");
+    print_message(stderr, NSSM_MESSAGE_CREATE_PARAMETERS_FAILED);
     DeleteService(service);
     CloseServiceHandle(services);
     return 6;
@@ -137,7 +137,7 @@ int install_service(char *name, char *exe, char *flags) {
   CloseServiceHandle(service);
   CloseServiceHandle(services);
 
-  printf("Service \"%s\" installed successfully!\n", name);
+  print_message(stdout, NSSM_MESSAGE_SERVICE_INSTALLED, name);
   return 0;
 }
 
@@ -146,21 +146,21 @@ int remove_service(char *name) {
   /* Open service manager */
   SC_HANDLE services = open_service_manager();
   if (! services) {
-    fprintf(stderr, "Error opening service manager!\n");
+    print_message(stderr, NSSM_MESSAGE_OPEN_SERVICE_MANAGER_FAILED);
     return 2;
   }
   
   /* Try to open the service */
   SC_HANDLE service = OpenService(services, name, SC_MANAGER_ALL_ACCESS);
   if (! service) {
-    fprintf(stderr, "Can't open service!");
+    print_message(stderr, NSSM_MESSAGE_OPENSERVICE_FAILED);
     CloseServiceHandle(services);
     return 3;
   }
 
   /* Try to delete the service */
   if (! DeleteService(service)) {
-    fprintf(stderr, "Error deleting service!\n");
+    print_message(stderr, NSSM_MESSAGE_DELETESERVICE_FAILED);
     CloseServiceHandle(service);
     CloseServiceHandle(services);
     return 4;
@@ -170,7 +170,7 @@ int remove_service(char *name) {
   CloseServiceHandle(service);
   CloseServiceHandle(services);
 
-  printf("Service \"%s\" removed successfully!\n", name);
+  print_message(stdout, NSSM_MESSAGE_SERVICE_REMOVED, name);
   return 0;
 }