The Subprocess extension: running subprocesses

Download Subprocess extension

This extension allows you to create and run subprocesses. You can either wait for your subprocess to finish or let it continue running in the background.

Starting subprocesses asynchronously

Subprocess.Async spawns an instance of the executable at the given path in the background without waiting. Here's how I use it to start my X server:

launch X = Subprocess.Async(c:\cygwin\bin\XWin.exe, XWin.exe,
                            -ac, -multiwindow, -clipboard);

The fine print for this procedure:

Starting subprocesses synchronously

Subprocess.Sync is similar but waits for the created subprocess to finish before returning. Normally Subprocess.Sync raises a runtime error if a nonzero exit code is returned by the subprocess.

If you wish to handle any errors yourself, add "-" to the end of the executable path. In this case, Subprocess.Sync simply sets the variable exit_code to the subprocess's exit code then returns. This lets you check the subprocess's exit status by calling Variable.Get(exit_code).

Alternative simpler syntax

If your arguments do not contain spaces, you may find a convenience procedure, Subprocess.Run, easier to use. Here's the X server command again using Subprocess.Run:

launch X = 
    Subprocess.Run(c:\cygwin\bin\XWin.exe, "-ac -multiwindow -clipboard");

Subprocess.Run automatically determines the name of your executable and splits its second argument into the executable's arguments by splitting at spaces. Run can also run subprocesses synchronously: just append "!" to the end of the executable path ("-!" if you want to handle errors yourself).

Shell commands

An experimental procedure, Subprocess.System, is available. It attempts to run its single argument as a shell command. It now (4/17/2016) throws a runtime error if the command returns a non-zero exit code. Here's a test command using it:

wait for me = Subprocess.System("timeout 5 && timeout 5");

If you want to ignore the exit code, pass False as a second argument to Subprocess.System.

How Subprocess's behavior differs from AppBringUp's

AppBringUp is meant to call up a program with a GUI window and remember that window for future use with AppSwapWith. To do that, Dragon switches focus to a Dragon window (the results box in old versions I believe), runs your command in the background then waits for the focus to change to the new window. As soon as the focus changes, it remembers the window ID of the window with focus and returns. If the focus never changes, Dragon times out after something like 30 seconds and returns anyways.

Because of this behavior, you should only use AppBringUp for executables that create windows or change focus. Because Subprocess does not wait for focus to change, it can be used even for executables that do not create Windows or change focus.