On this Page

    _run (Execute Another Program)

    Run a user-specified program, passing user-specified command line parameters.

    Syntax

    _run(program[, args[, logStdout]])

    Parameters

    program is the fully qualified program name. (fully is preferred but sufficiently will do.)

    args can be a text string that is the full command line or args can be a JavaScript object or array whose properties define the argument list. If args is a text string, the string will simply be passed as-is to the called program. If args is a JavaScript object, each object property name becomes a DocOrigin-style -name command line option name and the property's value becomes its value. E.g. args.form = "$F/myForm.xatw";. For third-party applications that don't use the -name=value syntax, use a numeric property name, e.g. args[0] = "3rd party command line part";.

    logStdout (As of 3.1.002.07) A Boolean which specifies whether the stdout and stderr outputs of the external executable should be captured and added to the calling program's log file.

    Returned Value

    If the selected program cannot be found or cannot be run (e.g. missing a DLL), the return code is platform-specific. On Windows, _run returns a value of 111 to indicate that the task could not be found or executed. If the program is run, the returned value is the exit code provided by the called program.

    Description

    The _run function is used to spawn other programs, both DocOrigin tasks and other executables. Your application will wait until that task has completed before resuming. (See also _runNoWait.)

    Note: While you can invoke DocOrigin Merge with the _run function, it is strongly recommended that you use the _merge function. It has been specifically created to spawn DocOrigin Merge. Similarly, you are strongly advised to use the _runScript function rather than using _run to launch RunScript. By using those purpose-built functions, the called program gets the same jobID as the calling program. Also, the log file is shared as well as any session file that is being used. Hence information can be passed between the programs by using session settings. 

    Examples

    First Variation
      var program = $E + "/Merge";
      var arglist = "-form=$F/myform.xatw -data=$D/mydata.xml";
      var rc = _run(program, arglist);
      // Note: better to use var rc = _merge(arglist);
      if (rc != 0) _logPrintf("The _run return code was: %d\n", rc);


    Second Variation
      var program = $E + "/Merge";        // or "$E/Merge";
      var args = {};
      args.form = $F + "/myform.xatw";    // or "$F/myform.xatw";
      args.data = $D + "/mydata.xml";     // or "$D/mydata.xml";
      var rc = _run(program, args);
      // Bote: better to use var rc = _merge(args);
      if (rc != 0) _logPrintf("The _run return code was: %d\n", rc);

    Remember that $E is pre-populated to refer to the appropriate program folder (.../DO/Bin) for your chosen installation folder. $F, and $D are presumed to be folder mapping variables that you defined in your $O/Paths.prm override file to refer to appropriate folders. See $X String Substitutions. Also, the example uses Merge, without the .exe to make this portable to *nix systems. Similarly, the example uses forward slashes (/) not backslashes (\) for portability reasons. Besides, backslashes would have to be doubled up when used in JavaScript strings.

    In the first variation, if the form name had a space in its name, e.g. Sample Invoice.xatw, then you would have to quote it as in '-form="$F/Sample Invoice.xatw"'. It has to be double quotes, not single quotes, and hence the overall quoting around the whole arglist, in JavaScript, would use single quotes. In the second variation, it is safe to use $X path substitutions on all platforms. In the first variation, on Linux systems, if you pass a $X it will be incorrectly interpreted as an environment variable reference.

    Consider using _sprintf:

      var program = $E + "/Merge";        // or "$E/Merge";
      var args = {};
      args.form = $F + "/myform.xatw";    // or "$F/myform.xatw";
      args.data = $D + "/mydata.xml";     // or "$D/mydata.xml";
      var rc = _run(program, args);
      // Bote: better to use var rc = _merge(args);
      if (rc != 0) _logPrintf("The _run return code was: %d\n", rc);

    Don't forget to put a slash at the start of the base file name. Do check your return codes.

    An "Args" Object or Array

    It is usually easier to use the _sprintf function rather than endless string concatenations.

    It's often quite tedious to produce an "args" list string. For running DocOrigin programs, ones that use the -option=value notation, it is preferred to use the second variation above. The resulting code is much easier to understand and to maintain. But suppose a command-line option can occur multiple times; what then?

    Clearly, it is pointless to use:

     args.option = "ABC";
     args.option = "XYZ";

    Naturally, the last value alone will win out. A classic example of this need is for when you wish to give Merge two -filter options. The way to accomplish that is by using numeric property "names" in your args variable. When building up the command line from the supplied args variable, the code discards any numeric property name and uses just the property value. Here is an example:

     var args = {};
     args.form = ...;
     args.data = ...;
     args[0] = "-filter filter1.wjs -symbolset cp1252";
     args[1] = "-filter filter2.wjs";
     var rc = _merge(args);
     if (rc != 0) _logPrintf("The _merge return code was: %d\n", rc);

    Do note that in this format the value side of the assignment includes the option name. It is not necessary to use the exact numbers: 0, 1, 2, ... You can use any numbers you like but do not use the same number multiple times in one args definition, else the latter one will overwrite the former one.

    Another method is to use a JavaScript array. Here is an example:

      var args = [];
      args.form = ...;
      args.data = ...;
      args[0] = "-filter filter1.wjs -symbolset cp1252";
      args.push("-filter filter2.wjs");
      var rc = _merge(args);
      if (rc != 0) _logPrintf("The _merge return code was: %d\n", rc);

    Notice the use of [] which signifies an array, rather than {} which signifies an object. JavaScript is very flexible. You can use args["form"] = ... or args.form = ..., or args.push("-form ...");. All of those syntaxes are supported and can be intermixed. The joy of using push() is that you don't have to dream up unique array index numbers.

    Use a PRM File

    Getting all the quoting of command line parts correct can be annoying. One way to make your life simpler is to use a, possibly temporary, PRM file. Of course, this is for only DocOrigin programs. Other programs do not know how to process PRM files. If you were to have or create a PRM file, named say, myParms.prm, you could use _run as follows:

     var rc = _run("a DO program", "@myParms.prm");

    The @ is OK, but not necessary if it is the first parameter and it ends in PRM. This PRM method may be more comfortable for some users.

    Redirecting Program Outputs

    Many programs write output to stdout and possibly error messages to stderr. By using the logStdout parameter, with a value of true, in your _run call, you can cause that stdout and stderr output to be captured and automatically copied into the calling program's log file. This is very handy for keeping all messages together in one log file. If you do capture that output into your log be aware that it won't also come out to the console.

    You may not want to capture that output in your log file but rather redirect that output to some file. The OS standard way to do that is by using the > operator. This is OS standard practice. If you create a command line (as opposed to an array of args) you can include the > operator (or other operators, e.g. >>, |) as you see fit. _run will feed that to the OS and the OS will do what it normally does.

    (As of 3.2.001.05) If you want to use the mpre easily maintainable convenience of an args array you can do the following:

     var args = [];
     args.push("parameter 1");
     args.push("parameter 2");
     args.push("parameter ...");
     args.push(">");
     args.push("myFile.txt");
     var rc = _run("myProgram", args);

    The > operator must be provided as a separate array item. The operators that are supported using this array syntax are: >, >>, 1>, 2>, 2>&1, |, and <. Indeed the OS supports more, less common, operators. If you have the need to use one of the less common operators, then you must use the command line method of the _run options, and not the args array/object option.

    Debugging

    It is hugely beneficial, during development, to log out the command line. Doing a

    _logf("args: '%s'\n", args);

    is a great way to do that. The DocOrigin JavaScript extensions support displaying JavaScript objects as %s. Also try %S.

    See Also

    _merge
    _runScript
    _runNoWait
    Session