001/*
002 * The contents of this file are subject to the terms of the Common Development and
003 * Distribution License (the License). You may not use this file except in compliance with the
004 * License.
005 *
006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007 * specific language governing permission and limitations under the License.
008 *
009 * When distributing Covered Software, include this CDDL Header Notice in each file and include
010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011 * Header, with the fields enclosed by brackets [] replaced by your own identifying
012 * information: "Portions Copyright [year] [name of copyright owner]".
013 *
014 * Copyright 2008-2010 Sun Microsystems, Inc.
015 * Portions Copyright 2011-2016 ForgeRock AS.
016 */
017package org.opends.server.tools;
018
019import static com.forgerock.opendj.cli.CommonArguments.*;
020import static com.forgerock.opendj.cli.Utils.*;
021import static com.forgerock.opendj.util.OperatingSystem.*;
022
023import static org.opends.messages.ToolMessages.*;
024
025import java.io.BufferedReader;
026import java.io.File;
027import java.io.IOException;
028import java.io.InputStreamReader;
029import java.io.OutputStream;
030import java.io.PrintStream;
031
032import org.forgerock.i18n.LocalizableMessage;
033import org.opends.guitools.controlpanel.util.Utilities;
034import org.opends.quicksetup.util.Utils;
035import org.opends.server.core.DirectoryServer;
036import org.opends.server.loggers.JDKLogging;
037import org.opends.server.types.NullOutputStream;
038import org.opends.server.util.DynamicConstants;
039import org.opends.server.util.SetupUtils;
040
041import com.forgerock.opendj.cli.ArgumentException;
042import com.forgerock.opendj.cli.ArgumentParser;
043import com.forgerock.opendj.cli.BooleanArgument;
044import com.forgerock.opendj.cli.StringArgument;
045
046/**
047  * This class is used to configure the Windows service for this instance on
048  * this machine.
049  * This tool allows to enable and disable OpenDJ to run as a Windows service
050  * and allows to know if OpenDJ is running as a Windows service or not.
051  *
052  * Some comments about Vista:
053  * In Vista, when we launch the subcommands that require administrator
054  * privileges (enable, disable and cleanup) we cannot use the administrator
055  * launcher binary directly from Java (see
056  * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6410605) so we use
057  * winlauncher.exe.
058  * When we launch subcommands that required administrator privileges
059  * we must launch a binary containing the manifest that specifies that we
060  * require administrator privileges (requireAdministrator value): if UAC is
061  * enabled, the user will be asked for confirmation.
062  * To minimize the number of confirmation that the user must provide when
063  * launching the state subcommand we will use a binary whose manifest does
064  * not contain the requireAdministrator value.
065  *
066  * See the files under src/build-tools/windows for more details.
067  */
068public class ConfigureWindowsService
069{
070  /** The fully-qualified name of this class. */
071  private static final String CLASS_NAME = "org.opends.server.tools.ConfigureWindowsService";
072
073  private static final String DEBUG_OPTION = "--debug";
074  /** Option to be used when calling the launchers. */
075  public static final String LAUNCHER_OPTION = "run";
076
077  private static final int SUCCESS = 0;
078  private static final int ERROR = 1;
079
080  /** Return codes for the method enableService. */
081  /** The service was successfully enabled. */
082  public static final int SERVICE_ENABLE_SUCCESS = 0;
083  /** The service was already enabled. */
084  public static final int SERVICE_ALREADY_ENABLED = 1;
085  /** The service name was already in use. */
086  private static final int SERVICE_NAME_ALREADY_IN_USE = 2;
087  /** An error occurred enabling the service. */
088  private static final int SERVICE_ENABLE_ERROR = 3;
089
090  /** Return codes for the method disableService. */
091  /** The service was successfully disabled. */
092  public static final int SERVICE_DISABLE_SUCCESS = 0;
093  /** The service was already disabled. */
094  public static final int SERVICE_ALREADY_DISABLED = 1;
095  /** The service is marked for deletion. */
096  private static final int SERVICE_MARKED_FOR_DELETION = 2;
097  /** An error occurred disabling the service. */
098  public static final int SERVICE_DISABLE_ERROR = 3;
099
100  /** Return codes for the method serviceState. */
101  /** The service is enabled. */
102  public static final int SERVICE_STATE_ENABLED = 0;
103  /** The service is disabled. */
104  private static final int SERVICE_STATE_DISABLED = 1;
105  /** An error occurred checking the service state. */
106  private static final int SERVICE_STATE_ERROR = 2;
107
108  /** Return codes for the method cleanupService. */
109  /** The service cleanup worked. */
110  private static final int SERVICE_CLEANUP_SUCCESS = 0;
111  /** The service could not be found. */
112  private static final int SERVICE_NOT_FOUND = 1;
113  /** An error occurred cleaning up the service. */
114  private static final int SERVICE_CLEANUP_ERROR = 2;
115  /** The service is marked for deletion. */
116  private static final int SERVICE_CLEANUP_MARKED_FOR_DELETION = 3;
117
118  /**
119   * Configures the Windows service for this instance on this machine. This tool
120   * allows to enable and disable OpenDJ to run as a Windows service and allows
121   * to know if OpenDJ is running as a Windows service or not.
122   *
123   * @param args
124   *          The command-line arguments provided to this program.
125   */
126  public static void main(String[] args)
127  {
128    int result = configureWindowsService(args, System.out, System.err);
129
130    System.exit(filterExitCode(result));
131  }
132
133  /**
134   * Configures the Windows service for this instance on this machine. This tool
135   * allows to enable and disable OpenDJ to run as a Windows service and allows
136   * to know if OpenDJ is running as a Windows service or not.
137   *
138   * @param args
139   *          The command-line arguments provided to this program.
140   * @param outStream
141   *          the stream used to write the standard output.
142   * @param errStream
143   *          the stream used to write the error output.
144   * @return the integer code describing if the operation could be completed or
145   *         not.
146   */
147  private static int configureWindowsService(String[] args, OutputStream outStream, OutputStream errStream)
148  {
149    PrintStream out = NullOutputStream.wrapOrNullStream(outStream);
150    PrintStream err = NullOutputStream.wrapOrNullStream(errStream);
151    JDKLogging.disableLogging();
152
153    //  Define all the arguments that may be used with this program.
154    LocalizableMessage toolDescription = INFO_CONFIGURE_WINDOWS_SERVICE_TOOL_DESCRIPTION.get();
155    ArgumentParser argParser = new ArgumentParser(CLASS_NAME, toolDescription, false);
156    argParser.setShortToolDescription(REF_SHORT_DESC_WINDOWS_SERVICE.get());
157    BooleanArgument enableService = null;
158    BooleanArgument disableService = null;
159    BooleanArgument serviceState = null;
160    StringArgument cleanupService = null;
161    BooleanArgument showUsage = null;
162
163    try
164    {
165      enableService =
166              BooleanArgument.builder("enableService")
167                      .shortIdentifier('e')
168                      .description(INFO_CONFIGURE_WINDOWS_SERVICE_DESCRIPTION_ENABLE.get())
169                      .buildAndAddToParser(argParser);
170      disableService =
171              BooleanArgument.builder("disableService")
172                      .shortIdentifier('d')
173                      .description(INFO_CONFIGURE_WINDOWS_SERVICE_DESCRIPTION_DISABLE.get())
174                      .buildAndAddToParser(argParser);
175      serviceState =
176              BooleanArgument.builder("serviceState")
177                      .shortIdentifier('s')
178                      .description(INFO_CONFIGURE_WINDOWS_SERVICE_DESCRIPTION_STATE.get())
179                      .buildAndAddToParser(argParser);
180      cleanupService =
181              StringArgument.builder("cleanupService")
182                      .shortIdentifier('c')
183                      .description(INFO_CONFIGURE_WINDOWS_SERVICE_DESCRIPTION_CLEANUP.get())
184                      .valuePlaceholder(INFO_SERVICE_NAME_PLACEHOLDER.get())
185                      .buildAndAddToParser(argParser);
186
187      showUsage = showUsageArgument();
188      argParser.addArgument(showUsage);
189      argParser.setUsageArgument(showUsage, out);
190    }
191    catch (ArgumentException ae)
192    {
193      printWrappedText(err, ERR_CANNOT_INITIALIZE_ARGS.get(ae.getMessage()));
194      return ERROR;
195    }
196
197    try
198    {
199      argParser.parseArguments(args);
200    }
201    catch (ArgumentException ae)
202    {
203      argParser.displayMessageAndUsageReference(err, ERR_ERROR_PARSING_ARGS.get(ae.getMessage()));
204      return ERROR;
205    }
206
207    // If we should just display usage or version information,
208    // then it is already done
209    if (!argParser.usageOrVersionDisplayed())
210    {
211      /* Check that the user only asked for one argument */
212      int nArgs = 0;
213      if (enableService.isPresent())
214      {
215        nArgs++;
216      }
217      if (disableService.isPresent())
218      {
219        nArgs++;
220      }
221      if (serviceState.isPresent())
222      {
223        nArgs++;
224      }
225      if (cleanupService.isPresent())
226      {
227        nArgs++;
228      }
229      if (nArgs != 1)
230      {
231        argParser.displayMessageAndUsageReference(err, nArgs == 0 ? ERR_CONFIGURE_WINDOWS_SERVICE_TOO_FEW_ARGS.get()
232                                                                  : ERR_CONFIGURE_WINDOWS_SERVICE_TOO_MANY_ARGS.get());
233        return ERROR;
234      }
235    }
236
237    if (argParser.usageOrVersionDisplayed())
238    {
239      return SUCCESS;
240    }
241
242    if (enableService.isPresent())
243    {
244      return enableService(out, err);
245    }
246    else if (disableService.isPresent())
247    {
248      return disableService(out, err);
249    }
250    else if (serviceState.isPresent())
251    {
252      return serviceState(out, err);
253    }
254
255    return cleanupService(cleanupService.getValue(), out, err);
256  }
257
258  /**
259   * Returns the service name associated with OpenDJ or null if no service name
260   * could be found.
261   *
262   * @return the service name associated with OpenDJ or null if no service name
263   *         could be found.
264   */
265  static String getServiceName()
266  {
267    String serverRoot = getServerRoot();
268    String[] cmd = { getBinaryFullPath(), "state", serverRoot };
269    try
270    {
271      String serviceName = null;
272      Process p = Runtime.getRuntime().exec(cmd);
273      BufferedReader stdout = new BufferedReader(new InputStreamReader(p.getInputStream()));
274      boolean processDone = false;
275      String s;
276      while (!processDone)
277      {
278        try
279        {
280          p.exitValue();
281          processDone = true;
282        }
283        catch (Throwable t)
284        {
285        }
286        while ((s = stdout.readLine()) != null)
287        {
288          serviceName = s;
289          if (serviceName.trim().length() == 0)
290          {
291            serviceName = null;
292          }
293        }
294      }
295      return serviceName;
296    }
297    catch (Throwable t)
298    {
299      return null;
300    }
301  }
302
303  /**
304   * Enables OpenDJ to run as a windows service.
305   *
306   * @param out
307   *          the stream used to write the standard output.
308   * @param err
309   *          the stream used to write the error output.
310   * @return <CODE>SERVICE_ENABLE_SUCCESS</CODE>,
311   *         <CODE>SERVICE_ENABLE_ERROR</CODE>,
312   *         <CODE>SERVICE_NAME_ALREADY_IN_USE</CODE> or
313   *         <CODE>SERVICE_ALREADY_ENABLED</CODE> depending on whether the
314   *         service could be enabled or not.
315   */
316  public static int enableService(PrintStream out, PrintStream err)
317  {
318    LocalizableMessage serviceName = Utils.getCustomizedObject(
319        "INFO_WINDOWS_SERVICE_NAME",
320        INFO_WINDOWS_SERVICE_NAME.get(DynamicConstants.PRODUCT_NAME),
321        LocalizableMessage.class);
322    LocalizableMessage serviceDescription = Utils.getCustomizedObject(
323        "INFO_WINDOWS_SERVICE_DESCRIPTION",
324        INFO_WINDOWS_SERVICE_DESCRIPTION.get(getServerRoot()), LocalizableMessage.class);
325    return enableService(out, err, serviceName.toString(), serviceDescription.toString());
326  }
327
328  /**
329   * Enables OpenDJ to run as a windows service.
330   *
331   * @param out
332   *          the stream used to write the standard output.
333   * @param err
334   *          the stream used to write the error output.
335   * @param serviceName
336   *          the name of the service as it will appear in the registry.
337   * @param serviceDescription
338   *          the description of the service as it will appear in the registry.
339   * @return <CODE>SERVICE_ENABLE_SUCCESS</CODE>,
340   *         <CODE>SERVICE_ENABLE_ERROR</CODE>,
341   *         <CODE>SERVICE_NAME_ALREADY_IN_USE</CODE> or
342   *         <CODE>SERVICE_ALREADY_ENABLED</CODE> depending on whether the
343   *         service could be enabled or not.
344   */
345  private static int enableService(PrintStream out, PrintStream err, String serviceName, String serviceDescription)
346  {
347    String serverRoot = getServerRoot();
348    String[] cmd;
349
350    if (hasUAC())
351    {
352      cmd = new String[] {
353          getLauncherBinaryFullPath(),
354          LAUNCHER_OPTION,
355          getLauncherAdministratorBinaryFullPath(),
356          LAUNCHER_OPTION,
357          getBinaryFullPath(),
358          "create",
359          serverRoot,
360          serviceName,
361          serviceDescription,
362          DEBUG_OPTION
363      };
364    }
365    else
366    {
367      cmd = new String[] {
368          getBinaryFullPath(),
369          "create",
370          serverRoot,
371          serviceName,
372          serviceDescription,
373          DEBUG_OPTION
374      };
375    }
376
377    try
378    {
379      boolean isServerRunning = Utilities.isServerRunning(new File(serverRoot));
380
381      int resultCode = Runtime.getRuntime().exec(cmd).waitFor();
382      switch (resultCode)
383      {
384      case 0:
385        if (isServerRunning)
386        {
387          // We have to launch the windows service.  The service code already
388          // handles this case (the service binary is executed when the server
389          // already runs).
390          final int returnValue = StartWindowsService.startWindowsService(out, err);
391          if (returnValue == 0)
392          {
393            printWrappedText(out, INFO_WINDOWS_SERVICE_SUCCESSULLY_ENABLED.get());
394            return SERVICE_ENABLE_SUCCESS;
395          }
396          else
397          {
398            printWrappedText(err, ERR_WINDOWS_SERVICE_ENABLING_ERROR_STARTING_SERVER.get(SERVICE_ENABLE_ERROR));
399            return SERVICE_ENABLE_ERROR;
400          }
401        }
402        else
403        {
404          printWrappedText(out, INFO_WINDOWS_SERVICE_SUCCESSULLY_ENABLED.get());
405          return SERVICE_ENABLE_SUCCESS;
406        }
407      case 1:
408        printWrappedText(out, INFO_WINDOWS_SERVICE_ALREADY_ENABLED.get());
409        return SERVICE_ALREADY_ENABLED;
410      case 2:
411        printWrappedText(err, ERR_WINDOWS_SERVICE_NAME_ALREADY_IN_USE.get());
412        return SERVICE_NAME_ALREADY_IN_USE;
413      case 3:
414        printWrappedText(err, ERR_WINDOWS_SERVICE_ENABLE_ERROR.get());
415        return SERVICE_ENABLE_ERROR;
416      default:
417        printWrappedText(err, ERR_WINDOWS_SERVICE_ENABLE_ERROR.get());
418        return SERVICE_ENABLE_ERROR;
419      }
420    }
421    catch (Throwable t)
422    {
423      err.println("Unexpected throwable: "+t);
424      t.printStackTrace();
425      printWrappedText(err, ERR_WINDOWS_SERVICE_ENABLE_ERROR.get());
426      return SERVICE_ENABLE_ERROR;
427    }
428  }
429
430  /**
431   * Disables OpenDJ to run as a windows service.
432   *
433   * @param out
434   *          the stream used to write the standard output.
435   * @param err
436   *          the stream used to write the error output.
437   * @return <CODE>SERVICE_DISABLE_SUCCESS</CODE>,
438   *         <CODE>SERVICE_DISABLE_ERROR</CODE>,
439   *         <CODE>SERVICE_MARKED_FOR_DELETION</CODE> or
440   *         <CODE>SERVICE_ALREADY_DISABLED</CODE> depending on whether the
441   *         service could be disabled or not.
442   */
443  public static int disableService(PrintStream out, PrintStream err)
444  {
445    String serverRoot = getServerRoot();
446    String[] cmd;
447    if (hasUAC())
448    {
449      cmd = new String[] {
450          getLauncherBinaryFullPath(),
451          LAUNCHER_OPTION,
452          getLauncherAdministratorBinaryFullPath(),
453          LAUNCHER_OPTION,
454          getBinaryFullPath(),
455          "remove",
456          serverRoot,
457          DEBUG_OPTION
458      };
459    }
460    else
461    {
462      cmd = new String[] {
463        getBinaryFullPath(),
464        "remove",
465        serverRoot,
466        DEBUG_OPTION
467        };
468    }
469    try
470    {
471      int resultCode = Runtime.getRuntime().exec(cmd).waitFor();
472      switch (resultCode)
473      {
474      case 0:
475        printWrappedText(out, INFO_WINDOWS_SERVICE_SUCCESSULLY_DISABLED.get());
476        return SERVICE_DISABLE_SUCCESS;
477      case 1:
478        printWrappedText(out, INFO_WINDOWS_SERVICE_ALREADY_DISABLED.get());
479        return SERVICE_ALREADY_DISABLED;
480      case 2:
481        printWrappedText(out, WARN_WINDOWS_SERVICE_MARKED_FOR_DELETION.get());
482        return SERVICE_MARKED_FOR_DELETION;
483      case 3:
484        printWrappedText(err, ERR_WINDOWS_SERVICE_DISABLE_ERROR.get());
485        return SERVICE_DISABLE_ERROR;
486      default:
487        printWrappedText(err, ERR_WINDOWS_SERVICE_DISABLE_ERROR.get());
488        return SERVICE_DISABLE_ERROR;
489      }
490    }
491    catch (Throwable t)
492    {
493      t.printStackTrace();
494      printWrappedText(err, ERR_WINDOWS_SERVICE_DISABLE_ERROR.get());
495      return SERVICE_DISABLE_ERROR;
496    }
497  }
498
499  /**
500   * Cleans up a service for a given service name.
501   *
502   * @param serviceName
503   *          the service name to be cleaned up.
504   * @param out
505   *          the stream used to write the standard output.
506   * @param err
507   *          the stream used to write the error output.
508   * @return <CODE>SERVICE_CLEANUP_SUCCESS</CODE>,
509   *         <CODE>SERVICE_NOT_FOUND</CODE>,
510   *         <CODE>SERVICE_MARKED_FOR_DELETION</CODE> or
511   *         <CODE>SERVICE_CLEANUP_ERROR</CODE> depending on whether the service
512   *         could be found or not.
513   */
514  private static int cleanupService(String serviceName, PrintStream out, PrintStream err)
515  {
516    String[] cmd;
517    if (hasUAC())
518    {
519      cmd = new String[] {
520          getLauncherBinaryFullPath(),
521          LAUNCHER_OPTION,
522          getLauncherAdministratorBinaryFullPath(),
523          LAUNCHER_OPTION,
524          getBinaryFullPath(),
525          "cleanup",
526          serviceName,
527          DEBUG_OPTION
528      };
529    }
530    else
531    {
532      cmd = new String[] {
533          getBinaryFullPath(),
534          "cleanup",
535          serviceName,
536          DEBUG_OPTION
537      };
538    }
539    try
540    {
541      int resultCode = Runtime.getRuntime().exec(cmd).waitFor();
542      switch (resultCode)
543      {
544      case 0:
545        printWrappedText(out, INFO_WINDOWS_SERVICE_CLEANUP_SUCCESS.get(serviceName));
546        return SERVICE_CLEANUP_SUCCESS;
547      case 1:
548        printWrappedText(err, ERR_WINDOWS_SERVICE_CLEANUP_NOT_FOUND.get(serviceName));
549        return SERVICE_NOT_FOUND;
550      case 2:
551        printWrappedText(out, WARN_WINDOWS_SERVICE_CLEANUP_MARKED_FOR_DELETION.get(serviceName));
552        return SERVICE_CLEANUP_MARKED_FOR_DELETION;
553      case 3:
554        printWrappedText(err, ERR_WINDOWS_SERVICE_CLEANUP_ERROR.get(serviceName));
555        return SERVICE_CLEANUP_ERROR;
556      default:
557        printWrappedText(err, ERR_WINDOWS_SERVICE_CLEANUP_ERROR.get(serviceName));
558        return SERVICE_CLEANUP_ERROR;
559      }
560    }
561    catch (Throwable t)
562    {
563      err.println(ERR_WINDOWS_SERVICE_CLEANUP_ERROR.get(serviceName));
564      printWrappedText(err, "Exception:" + t);
565      return SERVICE_CLEANUP_ERROR;
566    }
567  }
568
569  /**
570   * Checks if OpenDJ is enabled as a windows service.
571   *
572   * @return <CODE>SERVICE_STATE_ENABLED</CODE>,
573   *         <CODE>SERVICE_STATE_DISABLED</CODE> or
574   *         <CODE>SERVICE_STATE_ERROR</CODE> depending on the state of the
575   *         service.
576   */
577  public static int serviceState()
578  {
579    return serviceState(NullOutputStream.printStream(), NullOutputStream.printStream());
580  }
581
582  /**
583   * Checks if OpenDJ is enabled as a windows service and if it is write the
584   * serviceName in the output stream (if it is not null).
585   *
586   * @param out
587   *          the stream used to write the standard output.
588   * @param err
589   *          the stream used to write the error output.
590   * @return <CODE>SERVICE_STATE_ENABLED</CODE>,
591   *         <CODE>SERVICE_STATE_DISABLED</CODE> or
592   *         <CODE>SERVICE_STATE_ERROR</CODE> depending on the state of the
593   *         service.
594   */
595  private static int serviceState(PrintStream out, PrintStream err)
596  {
597    String serviceName = null;
598
599    String serverRoot = getServerRoot();
600    String[] cmd = new String[] {
601        getBinaryFullPath(),
602        "state",
603        serverRoot,
604        DEBUG_OPTION
605    };
606
607    try
608    {
609      int resultCode = -1;
610      Process process = new ProcessBuilder(cmd).start();
611      BufferedReader stdout = new BufferedReader(new InputStreamReader(process.getInputStream()));
612
613      boolean processDone = false;
614      String s;
615      while (!processDone)
616      {
617        try
618        {
619          resultCode = process.exitValue();
620          processDone = true;
621        }
622        catch (Throwable t)
623        {
624        }
625        while ((s = stdout.readLine()) != null)
626        {
627          if (s.trim().length() != 0)
628          {
629            serviceName = s;
630          }
631        }
632      }
633      switch (resultCode)
634      {
635      case 0:
636        printWrappedText(out, INFO_WINDOWS_SERVICE_ENABLED.get(serviceName));
637        return SERVICE_STATE_ENABLED;
638      case 1:
639        printWrappedText(out, INFO_WINDOWS_SERVICE_DISABLED.get());
640        return SERVICE_STATE_DISABLED;
641      case 2:
642        printWrappedText(err, ERR_WINDOWS_SERVICE_STATE_ERROR.get());
643        return SERVICE_STATE_ERROR;
644      default:
645        printWrappedText(err, ERR_WINDOWS_SERVICE_STATE_ERROR.get());
646        return SERVICE_STATE_ERROR;
647      }
648    }
649    catch (Throwable t)
650    {
651      printWrappedText(err, ERR_WINDOWS_SERVICE_STATE_ERROR.get());
652      printWrappedText(err, t.toString());
653      return SERVICE_STATE_ERROR;
654    }
655  }
656
657  /**
658   * Returns the Directory Server installation path in a user friendly
659   * representation.
660   *
661   * @return the Directory Server installation path in a user friendly
662   *         representation.
663   */
664  private static String getServerRoot()
665  {
666    String serverRoot = DirectoryServer.getServerRoot();
667    File f = new File(serverRoot);
668    try
669    {
670      /*
671       * Do a best effort to avoid having a relative representation (for
672       * instance to avoid having ../../../).
673       */
674      f = f.getCanonicalFile();
675    }
676    catch (IOException ioe)
677    {
678      /* This is a best effort to get the best possible representation of the
679       * file: reporting the error is not necessary.
680       */
681    }
682    serverRoot = f.toString();
683    if (serverRoot.endsWith(File.separator))
684    {
685      serverRoot = serverRoot.substring(0, serverRoot.length() - 1);
686    }
687    return serverRoot;
688  }
689
690  /**
691   * Returns the full path of the executable used by this class to perform
692   * operations related to the service. This binaries file has the asInvoker
693   * value in its manifest.
694   *
695   * @return the full path of the executable used by this class to perform
696   *         operations related to the service.
697   */
698  private static String getBinaryFullPath()
699  {
700    return SetupUtils.getScriptPath(getServerRoot() + "\\lib\\opendj_service.exe");
701  }
702
703  /**
704   * Returns the full path of the executable that has a manifest requiring
705   * administrator privileges used by this class to perform operations related
706   * to the service.
707   *
708   * @return the full path of the executable that has a manifest requiring
709   *         administrator privileges used by this class to perform operations
710   *         related to the service.
711   */
712  public static String getLauncherAdministratorBinaryFullPath()
713  {
714    return getServerRoot() + "\\lib\\launcher_administrator.exe";
715  }
716
717  /**
718   * Returns the full path of the executable that has a manifest requiring
719   * administrator privileges used by this class to perform operations related
720   * to the service.
721   *
722   * @return the full path of the executable that has a manifest requiring
723   *         administrator privileges used by this class to perform operations
724   *         related to the service.
725   */
726  public static String getLauncherBinaryFullPath()
727  {
728    return getServerRoot() + "\\lib\\winlauncher.exe";
729  }
730}