You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by la...@apache.org on 2001/09/06 21:12:19 UTC

cvs commit: jakarta-tomcat/src/native/mod_jk/nt_service jk_nt_service.c

larryi      01/09/06 12:12:19

  Modified:    src/doc  NT-Service-howto.html
               src/native/mod_jk/nt_service jk_nt_service.c
  Log:
  Applying patch for Bugzilla #3370 which includes a documentation update.
  
  Allow adding of service dependancies
  Allow adding of service with different user name
  Allow adding of service as Automatic startup
  New functions to start and stop services on remote machines
  
  Submitted by: David Oxley
  
  Revision  Changes    Path
  1.6       +141 -132  jakarta-tomcat/src/doc/NT-Service-howto.html
  
  Index: NT-Service-howto.html
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/doc/NT-Service-howto.html,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- NT-Service-howto.html	2001/07/17 03:53:41	1.5
  +++ NT-Service-howto.html	2001/09/06 19:12:19	1.6
  @@ -1,148 +1,157 @@
  +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
   <html>
   <head>
  -  <!-- $Id: NT-Service-howto.html,v 1.5 2001/07/17 03:53:41 costin Exp $ -->
  -  <!-- Copyright 1999-2001, Apache Software Foundation -->
  +      <!-- $Id: NT-Service-howto.html,v 1.6 2001/09/06 19:12:19 larryi Exp $ -->
  +      <!-- Copyright 1999-2001, Apache Software Foundation -->          
  + 
     <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  +               
     <link rel="stylesheet" href="style.css">
     <title>Working with the Jakarta NT Service</title>
  +    
   </head>
  -
  -<body>
  -
  +  <body>
   <h1>Working with the Jakarta NT Service</h1>
  -
  -<p>By Gal Shachor
  -<tt>&lt;<a href="mailto:shachor@il.ibm.com">shachor@il.ibm.com</a>&gt;
  -</tt></p>
  -
  -
  -<p>The Jakarta NT service is an executable that wraps the
  -Tomcat servlet container and executes it in the background as an NT service. To
  -install it you will need to:</p>
  -
  +<p>By Gal Shachor <tt>&lt;<a href="mailto:shachor@il.ibm.com">shachor@il.ibm.com</a>
  +   &gt;</tt><br>
  +   Modified by Dave Oxley &lt;<a href="mailto:dave@junglemoss.com">dave@junglemoss.com</a>
  +   &gt;<br>
  +</p>
  +<p>The Jakarta NT service is an executable that wraps the Tomcat servlet container
  +and executes it in the background as an NT service. To install it you will
  +need to:</p>
   <ol>
  - <li>Get a
  -     hold on the NT executable (jk_nt_service.exe)</li>
  - <ul>
  -  <li>Download
  -      the executable from the win32/i386 directory  found where you downloaded the
  -      <a href="http://jakarta.apache.org/site/binindex.html"> Tomcat binary
  -      distribution.</a> For those using Netscape as your browser, try downloading
  -      a zip version of the file, if available. There can be problems using Netscape
  -      to download DLL files.</li>
  - </ul>
  - <li>Customize
  -     a properties file that provides the service with Tomcat information
  -     (wrapper.properties).</li>
  - <ul>
  -  <li>Locate the wrapper.properties template file in your Tomcat conf/jk directory.
  -  <li>Update
  -      the wrapper.tomcat_home property to point at your tomcat home.</li>
  -  <li>Update
  -      the wrapper.java_home property to point at your Java home.</li>
  - </ul>
  - <li>Install
  -     jk_nt_service by running it with the -i flag.</li>
  - <ul>
  -  <li>Execute
  -      jk_nt_service -I &lt;name of service&gt; &lt;path to updated wrapper
  -      properties&gt;</li>
  -  <li>&lt;name
  -      of service&gt; should be a single word (without and spaces) such as
  -      Jakarta</li>
  -  <li>&lt;path
  -      to updated wrapper properties&gt; should point to your wrapper.properties
  -      file (and the service will check it's existence.)</li>
  -  <li>For
  -      example, a valid command line can be jk_nt_service -I Jakarta wrapper.properties</li>
  - </ul>
  - <li>Start
  -     tomcat as a service.</li>
  - <ul>
  -  <li>From
  -      the command line, execute net start &lt;name of service&gt; (e.g. net
  -      start Jakarta)</li>
  -  <li>From
  -      the NT services applet, highlight your service and press start.</li>
  - </ul>
  - <b>Note:</b> If the log file location in your wrapper.properties file points to
  - the <tt>logs</tt> directory, and the <tt>logs</tt> directory doesn't yet exist,
  - manually create it before starting the service.
  - <li>Stop
  -     Tomcat as a service.</li>
  - <ul>
  -  <li>From
  -      the command line, execute net stop &lt;name of service&gt; (e.g. net
  -      stop Jakarta)</li>
  -  <li>From
  -      the NT services applet, highlight your service and press stop.</li>
  - </ul>
  +  <li>Get a      hold on the NT executable (jk_nt_service.exe)</li>
  +  <ul>
  +    <li>Download       the executable from the win32/i386 directory  found 
  + where you downloaded the       <a href="http://jakarta.apache.org/site/binindex.html">
  +    Tomcat binary       distribution.</a>
  +    For those using Netscape as your browser, try downloading       a zip 
  +version  of the file, if available. There can be problems using Netscape 
  +     to download DLL files.</li>
  +  </ul>
  +  <li>Customize      a properties file that provides the service with Tomcat 
  + information      (wrapper.properties).</li>
  +  <ul>
  +    <li>Locate the wrapper.properties template file in your Tomcat conf/jk 
  + directory.   </li>
  +    <li>Update       the wrapper.tomcat_home property to point at your tomcat 
  + home.</li>
  +    <li>Update       the wrapper.java_home property to point at your Java 
  + home.</li>
  +  </ul>
  +  <li>Install      jk_nt_service by running it with the -i flag.</li>
  +  <ul>
  +    <li>Execute       jk_nt_service -I &lt;name of service&gt; &lt;optional 
  + params&gt; &lt;path to updated wrapper       properties&gt;</li>
  +    <li>&lt;name       of service&gt; should be a single word (without and 
  + spaces) such as       Jakarta</li>
  +    <li>&lt;optional params&gt; are any of the following:</li>
  +    <ul>
  +      <li>-U &lt;user name&gt; - to set the user the service runs as. Make 
  + sure the user has 'Logon as a service right'. The &lt;user name&gt; must 
  +be in the format DomainName\UserName (e.g. Dev\Administrator for Administrator 
  + in the Dev domain or .\Administrator for the local Administrator)</li>
  +      <li>-P &lt;user password&gt; - Valid password for the user.</li>
  +      <li>-A - Sets the service to startup automatically.</li>
  +      <li>-D &lt;service dependancy&gt; - This sets the service that must 
  + be started prior to this one. -D &lt;service dependancy&gt; can be specified 
  + multiple times. &lt;service dependancy&gt; must be the 'Service Name' not 
  + the 'Display Name'.<br>
  +      </li>
  +    </ul>
  +    <li>&lt;path       to updated wrapper properties&gt; should point to your
  +wrapper.properties       file (and the service will check it's existence.)</li>
  +    <li>For       example, valid command lines can be:</li>
  +    <ul>
  +      <li>jk_nt_service -I Jakarta wrapper.properties</li>
  +      <li>jk_nt_service -I Jakarta -U .\Administrator -P password -A -D MSSQLSERVER&nbsp; 
  + wrapper.properties</li>
  +    </ul>
  +  </ul>
  +  <li>Start      tomcat as a service.</li>
  +  <ul>
  +    <li>From the command line, execute jk_nt_service -S &lt;name of service&gt; 
  + &lt;optional param&gt; where &lt;optional param&gt; is:</li>
  +    <ul>
  +      <li>-M &lt;machine name&gt; - Remote machine to start the service on. 
  + (e.g. jk_nt_service -S Jakarta -M DevBox)<br>
  +      </li>
  +    </ul>
  +    <li>From       the command line, execute net start &lt;name of service&gt; 
  + (e.g. net       start Jakarta)</li>
  +    <li>From       the NT services applet, highlight your service and press 
  + start.</li>
  +  </ul>
  +  <b>Note:</b> If the log file location in your wrapper.properties file points 
  +to  the <tt>logs</tt> directory, and the <tt>logs</tt> directory doesn't 
  +yet exist,  manually create it before starting the service.           
  +  <li>Stop      Tomcat as a service.</li>
  +  <ul>
  +    <li>From the command line, execute jk_nt_service -T &lt;name of service&gt; 
  + &lt;optional param&gt; where &lt;optional param&gt; is:</li>
  +    <ul>
  +      <li>-M &lt;machine name&gt; - Remote machine to stop the service on. 
  + (e.g. jk_nt_service -T Jakarta -M DevBox)<br>
  +      </li>
  +    </ul>
  +    <li>From       the command line, execute net stop &lt;name of service&gt; 
  + (e.g. net       stop Jakarta)</li>
  +    <li>From       the NT services applet, highlight your service and press 
  + stop.</li>
  +  </ul>
   </ol>
  -
  -<p><b>Special note</b>: The Tomcat service is using AJPV12 to
  -perform clean shutdown and you should make sure that an AJPV12 connector is
  -defined in your server.xml. In the absence of a configured AJPV12 port the
  -Tomcat service will kill Tomcat abruptly (that is murder it) without giving it
  -a chance to clean up. </p>
  -
  -<p><b>Special note2</b>: Acording to 
  -<a href=http://nagoya.apache.org/bugzilla/show_bug.cgi?id=2337">
  -http://nagoya.apache.org/bugzilla/show_bug.cgi?id=2337</a>, you may have problems with
  -long filenames. You should use the 8.3 format. Thanks to Anthony Dodd for finding this
  -workaround.</p>
  -
  -<p><strong>Notice for JDK 1.3 users</strong>: There is a 
  -<a href="http://developer.java.sun.com/developer/bugParade/bugs/4323062.html">known problem</a>
  -in JDK 1.3 that affects Java applications being run as Windows NT services. The bug causes the
  -service to terminate when the currently logged in user logs out. The simplest way to work
  -around this problem is to use JDK 1.2. If your application requires JDK 1.3 features then you 
  -may want to look into <a href="http://www.kcmultimedia.com/javaserv/">javaserv</a> or
  -<a href="http://www.alexandriasc.com/software/JavaService/">JavaService</a>. Users have reported
  -success with both of these packages but there may be others that work as well.
  -</p>
  +<p><b>Special note</b>: The Tomcat service is using AJPV12 to perform clean 
  + shutdown and you should make sure that an AJPV12 connector is defined in 
  +your server.xml. In the absence of a configured AJPV12 port the Tomcat service 
  + will kill Tomcat abruptly (that is murder it) without giving it a chance 
  +to clean up. </p>
  +<p><b>Special note2</b>: Acording to  <a href="http://nagoya.apache.org/bugzilla/show_bug.cgi?id=2337%22">
  +    http://nagoya.apache.org/bugzilla/show_bug.cgi?id=2337</a>
  +   , you may have problems with long filenames. You should use the 8.3 format. 
  + Thanks to Anthony Dodd for finding this workaround.</p>
  +<p><strong>Notice for JDK 1.3 users</strong>: There is a  <a href="http://developer.java.sun.com/developer/bugParade/bugs/4323062.html">
  +   known problem</a>
  +    in JDK 1.3 that affects Java applications being run as Windows NT services. 
  + The bug causes the service to terminate when the currently logged in user 
  + logs out. The simplest way to work around this problem is to use JDK 1.2. 
  + If your application requires JDK 1.3 features then you  may want to look 
  +into <a href="http://www.kcmultimedia.com/javaserv/">javaserv</a>
  +    or <a href="http://www.alexandriasc.com/software/JavaService/">JavaService</a>
  +   . Users have reported success with both of these packages but there may
  + be others that work as well. </p>
   <p>To remove the installed service, execute jk_nt_service -R &lt;name of service&gt;</p>
  -
   <h1>Advance Setup</h1>
  -
   <ol>
  - <li>Modify
  -     the Tomcat NT service properties. By default the service will run in manual
  -     mode and under the local system user account. To modify this, open the NT
  -     services applet, highlight your service and press startup. A popup window
  -     is opened and you will be able to customize the service to your
  -     satisfaction.</li>
  - <li>Modify
  -     the classpath. The classpath is determined by the wrapper.class_path
  -     properties, to modify it just add/remove/modify wrapper.class_path lines.
  -     The complete classpath is calculated by concatenating all the
  -     wrapper.class_path lines and putting &quot;;&quot; between them.</li>
  - <li>Execute
  -     several Tomcat instances. Say that you want one Tomcat to run for
  -     &quot;production&quot; and one for development, you can do that. All you
  -     will need to do is to install the Tomcat service twice and under two
  -     different names (and with different wrapper.properties file and server.xml
  -     files). </li>
  - <ul>
  -  <li>Make
  -      sure that the AJPV12 and HTTP connectors are modified in each server.xml
  -      file to prevent a clash.</li>
  -  <li>Make
  -      sure to update the wrapper.shutdown_port property in wrapper.properties
  -      to point to the correct AJPV12 shutdown ports (default is 8007). </li>
  - </ul>
  - <li>Modify
  -     the command line used to start Tomcat. The Tomcat service is taking all
  -     it's command line configuration from wrapper.properties! To customize the
  -     command line, edit the property wrapper.cmd_line and make sure that it
  -     makes a legal Java command line.</li>
  +  <li>Modify      the Tomcat NT service properties. By default the service 
  + will run in manual      mode and under the local system user account. To 
  +modify this, open the NT      services applet, highlight your service and 
  +press startup. A popup window      is opened and you will be able to customize 
  +the service to your      satisfaction.</li>
  +  <li>Modify      the classpath. The classpath is determined by the wrapper.class_path
  +       properties, to modify it just add/remove/modify wrapper.class_path
  +lines.       The complete classpath is calculated by concatenating all the
  +     wrapper.class_path lines and putting ";" between them.</li>
  +  <li>Execute      several Tomcat instances. Say that you want one Tomcat 
  + to run for      "production" and one for development, you can do that. All 
  + you      will need to do is to install the Tomcat service twice and under 
  + two      different names (and with different wrapper.properties file and 
  +server.xml      files). </li>
  +  <ul>
  +    <li>Make       sure that the AJPV12 and HTTP connectors are modified in
  +each server.xml       file to prevent a clash.</li>
  +    <li>Make       sure to update the wrapper.shutdown_port property in wrapper.properties
  +        to point to the correct AJPV12 shutdown ports (default is 8007).
  +    </li>
  +  </ul>
  +  <li>Modify      the command line used to start Tomcat. The Tomcat service 
  + is taking all      it's command line configuration from wrapper.properties! 
  + To customize the      command line, edit the property wrapper.cmd_line and 
  + make sure that it      makes a legal Java command line.</li>
   </ol>
  -
   <h1>Feedback</h1>
  -
  -<p>Please send feedback, bug report or any additional information to
  -<tt>&lt;<a href="mailto:tomcat-user@jakarta.apache.org">tomcat-user@jakarta.apache.org</a>&gt;
  -</tt>
  -</p>
  +<p>Please send feedback, bug report or any additional information to <tt>
  +   &lt;<a href="mailto:tomcat-user@jakarta.apache.org">tomcat-user@jakarta.apache.org</a>
  +   &gt; </tt></p>
   </body>
  -
   </html>
  
  
  
  1.5       +210 -38   jakarta-tomcat/src/native/mod_jk/nt_service/jk_nt_service.c
  
  Index: jk_nt_service.c
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat/src/native/mod_jk/nt_service/jk_nt_service.c,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- jk_nt_service.c	2001/08/31 13:53:41	1.4
  +++ jk_nt_service.c	2001/09/06 19:12:19	1.5
  @@ -56,14 +56,14 @@
   /***************************************************************************
    * Description: NT System service for Jakarta/Tomcat                       *
    * Author:      Gal Shachor <sh...@il.ibm.com>                           *
  - * Version:     $Revision: 1.4 $                                           *
  + *              Dave Oxley <Da...@JungleMoss.com>                           *
  + * Version:     $Revision: 1.5 $                                           *
    ***************************************************************************/
   
   #include "jk_global.h"
   #include "jk_util.h"
   #include "jk_ajp13.h"
   #include "jk_connect.h"
  -
   #include <windows.h>
   #include <stdio.h>
   #include <stdlib.h>
  @@ -84,6 +84,14 @@
   static HANDLE                  hServerStopEvent = NULL;
   static int                     shutdown_port;
   static char                    *shutdown_protocol = AJP12_TAG;
  +typedef enum ActionEnum
  +{   acNoAction  = 0,
  +    acInstall   = 1,
  +    acRemove    = 2,
  +    acStartTC   = 3,
  +    acStopTC    = 4
  +}   ActionEnum;
  +
   
   struct jk_tomcat_startup_data {
       char *classpath;
  @@ -106,8 +114,16 @@
   static void WINAPI service_main(DWORD dwArgc, 
                                   char **lpszArgv);
   static void install_service(char *name, 
  -                            char *prp_file);
  +                            char *user, 
  +                            char *password, 
  +                            char *deps, 
  +                            BOOL bAutomatic, 
  +                            char *rel_prp_file);
   static void remove_service(char *name);
  +static void start_service(char *name,
  +                          char *machine);
  +static void stop_service(char *name,
  +                         char *machine);
   static char *GetLastErrorText(char *lpszBuf, DWORD dwSize);
   static void AddToMessageLog(char *lpszMsg);
   static BOOL ReportStatusToSCMgr(DWORD dwCurrentState,
  @@ -137,19 +153,43 @@
   
   static void usage_message(const char *name)
   {
  -    printf("%s - Usage:\n", name);
  -    printf("%s -i <service name> <configuration properties file>\n", name);
  -    printf("\tto install the service\n");
  -    printf("%s -r <service name>\n", name);    
  -    printf("\tto remove the service\n");
  +    printf("%s - Usage:\n\n", name);
  +    printf("To install the service:\n");
  +    printf("%s -i <service name> {optional params} <config properties file>\n", name);
  +    printf("    Optional parameters\n");
  +    printf("        -u <user name> - In the form DomainName\\UserName (.\\UserName for local)\n");
  +    printf("        -p <user password>\n");
  +    printf("        -a - Set startup type to automatic\n");
  +    printf("        -d <sevice dependancy> - Can be entered multiple times\n\n");
  +    printf("To remove the service:\n");
  +    printf("%s -r <service name>\n\n", name);
  +    printf("To start the service:\n");
  +    printf("%s -s <service name> {optional params}\n", name);
  +    printf("    Optional parameters\n");
  +    printf("        -m <machine>\n\n");
  +    printf("To stop the service:\n");
  +    printf("%s -t <service name> {optional params}\n", name);
  +    printf("    Optional parameters\n");
  +    printf("        -m <machine>\n");
   }
   
   void main(int argc, char **argv)
   {
       WORD wVersionRequested;
       WSADATA wsaData;
  -    int err; 
  -        
  +    int i;
  +    int err;
  +    int count;
  +    int iAction = acNoAction;
  +    char *pServiceName = NULL;
  +    char *pUserName = NULL;
  +    char *pPassword = NULL;
  +    char *pMachine = NULL;
  +    BOOL bAutomatic = FALSE;
  +    char strDependancy[256] = "";
  +
  +    memset(strDependancy, 0, 255);
  +
       wVersionRequested = MAKEWORD(1, 1); 
       err = WSAStartup(wVersionRequested, &wsaData);
       if(0 != err) {
  @@ -170,21 +210,52 @@
                       LOBYTE(wsaData.wVersion),
                       HIBYTE(wsaData.wVersion));
   
  -
       __try {
  -        if((argc > 2) && ((*argv[1] == '-') || (*argv[1] == '/'))) {
  -            char *cmd = argv[1];
  -            cmd++;
  -            if(0 == stricmp("i", cmd) && (4 == argc)) {
  -                install_service(argv[2], argv[3]);
  +        if(argc > 2) {
  +            count=0;
  +            for (i=1;i<argc;i++) {
  +                if ((*argv[i] == '-') || (*argv[i] == '/')) {
  +                    char *cmd = argv[i];
  +                    cmd++;
  +                    if(0 == stricmp("i", cmd)) {
  +                        iAction = acInstall;
  +                        pServiceName = argv[i+1];
  +                    } else if(0 == stricmp("r", cmd)) {
  +                        iAction = acRemove;
  +                        pServiceName = argv[i+1];
  +                    } else if(0 == stricmp("s", cmd)) {
  +                        iAction = acStartTC;
  +                        pServiceName = argv[i+1];
  +                    } else if(0 == stricmp("t", cmd)) {
  +                        iAction = acStopTC;
  +                        pServiceName = argv[i+1];
  +                    } else if(0 == stricmp("u", cmd)) {
  +                        pUserName = argv[i+1];
  +                    } else if(0 == stricmp("p", cmd)) {
  +                        pPassword = argv[i+1];
  +                    } else if(0 == stricmp("m", cmd)) {
  +                        pMachine = argv[i+1];
  +                    } else if(0 == stricmp("a", cmd)) {
  +                        bAutomatic = TRUE;
  +                    } else if(0 == stricmp("d", cmd)) {
  +                        memcpy(strDependancy+count, argv[i+1], strlen(argv[i+1]));
  +                        count+= strlen(argv[i+1])+1;
  +                    }
  +                }
  +            }
  +            switch (iAction) {
  +            case acInstall:
  +                install_service(pServiceName, pUserName, pPassword, strDependancy, bAutomatic, argv[i-1]);
                   return;
  -            } else if(0 == stricmp("r", cmd) && (3 == argc)) {
  -                remove_service(argv[2]);
  +            case acRemove:
  +                remove_service(pServiceName);
                   return;
  -            } else if(0 == stricmp("s", cmd) && (3 == argc)) {
  -                HANDLE hTomcat;
  -                start_tomcat(argv[2], &hTomcat);
  +            case acStartTC:
  +                start_service(pServiceName, pMachine);
                   return;
  +            case acStopTC:
  +                stop_service(pServiceName, pMachine);
  +                return;
               }
           } else if(2  == argc) {
   
  @@ -304,6 +375,10 @@
   }
   
   void install_service(char *name, 
  +                     char *user, 
  +                     char *password, 
  +                     char *deps, 
  +                     BOOL bAutomatic,
                        char *rel_prp_file)
   {
       SC_HANDLE   schService;
  @@ -312,6 +387,9 @@
       char        szPropPath[2048];
       char        *dummy;
   
  +    if (0 == stricmp("", deps))
  +        deps = NULL;
  +
       if(!GetFullPathName(rel_prp_file, sizeof(szPropPath) - 1, szPropPath, &dummy)) {
           printf("Unable to install %s - %s\n", 
                  name, 
  @@ -333,8 +411,8 @@
           return;
       }
   
  -    schSCManager = OpenSCManager(NULL,  // machine (NULL == local)
  -                                 NULL,  // database (NULL == default)
  +    schSCManager = OpenSCManager(NULL,     // machine (NULL == local)
  +                                 NULL,     // database (NULL == default)
                                    SC_MANAGER_ALL_ACCESS);   // access required                       
       if(schSCManager) {
           schService = CreateService(schSCManager, // SCManager database
  @@ -342,14 +420,14 @@
                                      name,         // name to display
                                      SERVICE_ALL_ACCESS, // desired access
                                      SERVICE_WIN32_OWN_PROCESS,  // service type
  -                                   SERVICE_DEMAND_START,       // start type
  +                                   bAutomatic ? SERVICE_AUTO_START : SERVICE_DEMAND_START,       // start type
                                      SERVICE_ERROR_NORMAL,       // error control type
                                      szExecPath,                 // service's binary
                                      NULL,                       // no load ordering group
                                      NULL,                       // no tag identifier
  -                                   NULL,                       // dependencies
  -                                   NULL,                       // LocalSystem account
  -                                   NULL);                      // no password
  +                                   deps,                       // dependencies
  +                                   user,                       // account
  +                                   password);                  // password
   
           if(schService) {
               printf("The service named %s was created. Now adding registry entries\n", name);
  @@ -423,6 +501,100 @@
       }
   }
   
  +void start_service(char *name, char *machine)
  +{
  +    SC_HANDLE   schService;
  +    SC_HANDLE   schSCManager;
  +
  +    schSCManager = OpenSCManager(machine,  // machine (NULL == local)
  +                                 NULL,     // database (NULL == default)
  +                                 SC_MANAGER_ALL_ACCESS);   // access required                       
  +
  +    if(schSCManager) {
  +        schService = OpenService(schSCManager, name, SERVICE_ALL_ACCESS);
  +
  +        if(schService) {
  +            // try to start the service
  +            if(StartService(schService, 0, NULL)) {
  +                printf("Starting %s.", name);
  +                Sleep(1000);
  +
  +                while(QueryServiceStatus(schService, &ssStatus )) {
  +                    if(ssStatus.dwCurrentState == SERVICE_START_PENDING) {
  +                        printf(".");
  +                        Sleep(1000);
  +                    } else {
  +                        break;
  +                    }
  +                }
  +
  +                if(ssStatus.dwCurrentState == SERVICE_RUNNING) {
  +                    printf("\n%s started.\n", name);
  +                } else {
  +                    printf("\n%s failed to start.\n", name);
  +                }
  +            }
  +            else
  +                printf("StartService failed - %s\n", GetLastErrorText(szErr, sizeof(szErr)));
  +
  +            CloseServiceHandle(schService);
  +        } else {
  +            printf("OpenService failed - %s\n", GetLastErrorText(szErr, sizeof(szErr)));
  +        }
  +
  +        CloseServiceHandle(schSCManager);
  +    } else {
  +        printf("OpenSCManager failed - %s\n", GetLastErrorText(szErr, sizeof(szErr)));
  +    }
  +}
  +
  +void stop_service(char *name, char *machine)
  +{
  +    SC_HANDLE   schService;
  +    SC_HANDLE   schSCManager;
  +
  +    schSCManager = OpenSCManager(machine,  // machine (NULL == local)
  +                                 NULL,     // database (NULL == default)
  +                                 SC_MANAGER_ALL_ACCESS);   // access required                       
  +
  +    if(schSCManager) {
  +        schService = OpenService(schSCManager, name, SERVICE_ALL_ACCESS);
  +
  +        if(schService) {
  +            // try to stop the service
  +            if(ControlService( schService, SERVICE_CONTROL_STOP, &ssStatus )) {
  +                printf("Stopping %s.", name);
  +                Sleep(1000);
  +
  +                while(QueryServiceStatus(schService, &ssStatus )) {
  +                    if(ssStatus.dwCurrentState == SERVICE_STOP_PENDING) {
  +                        printf(".");
  +                        Sleep(1000);
  +                    } else {
  +                        break;
  +                    }
  +                }
  +
  +                if(ssStatus.dwCurrentState == SERVICE_STOPPED) {
  +                    printf("\n%s stopped.\n", name);
  +                } else {
  +                    printf("\n%s failed to stop.\n", name);
  +                }
  +            }
  +            else
  +                printf("StopService failed - %s\n", GetLastErrorText(szErr, sizeof(szErr)));
  +
  +            CloseServiceHandle(schService);
  +        } else {
  +            printf("OpenService failed - %s\n", GetLastErrorText(szErr, sizeof(szErr)));
  +        }
  +
  +        CloseServiceHandle(schSCManager);
  +    } else {
  +        printf("OpenSCManager failed - %s\n", GetLastErrorText(szErr, sizeof(szErr)));
  +    }
  +}
  +
   static int set_registry_values(char *name, 
                                  char *prp_file)
   {
  @@ -476,7 +648,7 @@
                                                      value);
                   if(rc) {
                       printf("Registry values were added\n");
  -                    printf("If you have already updated wrapper.properties you may start the %s service by executing \"net start %s\" from the command prompt\n",
  +                    printf("If you have already updated wrapper.properties you may start the %s service by executing \"jk_nt_service -s %s\" from the command prompt\n",
                              name,
                              name);                    
                   }
  @@ -802,13 +974,13 @@
   {
       LONG  lrc = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
                                  tag,
  -			                   0,
  -			                   NULL,
  -			                   REG_OPTION_NON_VOLATILE,
  -			                   KEY_WRITE,
  -			                   NULL,
  -			                   key,
  -			                   NULL);
  +                               0,
  +                               NULL,
  +                               REG_OPTION_NON_VOLATILE,
  +                               KEY_WRITE,
  +                               NULL,
  +                               key,
  +                               NULL);
       if(ERROR_SUCCESS != lrc) {
           return JK_FALSE;        
       }
  @@ -824,9 +996,9 @@
   
       lrc = RegSetValueEx(hkey, 
                           tag,            
  -			            0,              
  -			            REG_SZ,  
  -    			        value, 
  +                        0,              
  +                        REG_SZ,  
  +                        value, 
                           strlen(value));
   
       if(ERROR_SUCCESS != lrc) {