Automating GUI Tasks on Windows

You may need to automate Windows programs that require a desktop window and were not built for batch operation without a GUI.

Normally a Process Definition runs on Windows as either the System account, the default account set via the DefaultRunAsUser Process Server parameter, or the Process Definition Run As User attribute. Such processes can to create a GUI window, but they do so in such a way that all actions on it are disregarded. No Windows messages will ever arrive on such a process's message loop thread. If you take a screen shot, it will be completely black.

There are three main reasons why you may want a program to create a desktop window.

  • The program may not work if its GUI windows are not completely populated or its message loop does not function.
  • The program may not have automation capabilities that can be used to drive it to perform the desired action, leaving no other option than emulating a human operator by controlling it via its GUI.
  • The program may not be able to log errors or progress via any other means than its GUI.

Fortunately, a Platform Agent can create a full-blown Windows session. Because there is sizable overhead around creating such a session, though, the session is created (a user is logged on via RDP), and then it is used, and then it is closed (the user is logged off via RDP).

Because such sessions use a lot of Windows resources, and Windows normally restricts each computer to one session per user, their use should be minimized.

To use Windows sessions support, follow this procedure:

  1. Create a Queue that is served by only one Process Server with the Platform Agent service, running on Microsoft Windows 2012R2 or higher. This system must have enough RDP session licenses to serve the number of desired parallel sessions. Set the width of the Queue to the number of RDP sessions you want to run in parallel.
  2. Create at least one Windows user for every parallel session. For example, if you intend to have two parallel sessions, you must have at least two users. These users must have RDP privileges on the computer. You can test this by logging into the system as that account remotely using RDP.

The tasks that are scheduled on that server will all use this Queue. Do not use sessions in multiple Queues on the same server, nor schedule sessions on that server using multiple instances of the product.

For every task that needs to run (which can consist of multiple Process Definitions) create a Chain Definition that contains two special Process Definitions: one to create the session, and one to close it. Because this can take a long time, Redwood recommends using a Chain Definition to group tasks that can run in series or parallel together.

To run as part of the session, a Process Definitions must have an Opaque session handle JCS_SESSION parameter in their definition. The value for this parameter is not for use by the Process Definition itself, but for the session manager in the Platform Agent.

Built-in Definitions

The following built-in Process Definitions allow you to open and close RDP sessions on a remote Windows system. Note that the System_Windows_Session_Close only closes the sessions opened by System_Windows_Session_Create that it is linked to via the opaque session handle.

Use these Process Definitions in a Chain Definition, and map the opaque session handle JCS_SESSION parameter.

System_Windows_Session_Create has an Out parameter named JCS_SESSION. Your Process Definitions and System_Windows_Session_Close must contain an In parameter named JCS_SESSION.

How it Works

The System_Windows_Session_Create Process Definition is treated specially by the system because it has an Out JCS_SESSION parameter. Such a Process Definition will try to allocate a Windows User Session using one of the accounts allowed by the JCS_SESSION_ACCOUNTS parameter. The first account in that list that is not yet running a session according to its own administration will be used.

The JCS_SESSION_TIMEOUT parameter can be set on the session creation definition to specify the maximum time that the session may last. If the session is active longer, it will be aborted by the system. The standard definition takes a Number parameter containing the maximum number of minutes, but you can also specify a DateTimeZone by duplicating the Process Definition.

System_Windows_Session_Close is treated as the last Process Definition in the Windows Session because it uses the special keyword {logoff} in its Run As User attribute.

The Run As User field, in any of these definitions, is ignored other than the special {logoff} flag. This is useful because it means you can specify credentials and other flags for use in other situations where it is not called in the context of a Windows Session.

If needed, you can duplicate these system definitions and tune them for your own use.

Note that it is not required to use a Chain Definition. Any way in which the JCS_SESSION parameter is passed on to later Process Definitions is permitted. It is also possible to run multiple Process Definitions in parallel in the same Windows Session by using a Chain Definition with multiple calls in a Step. The only condition that the system makes is that you tell it when you are done with a session by running a Process Definition with the {logoff} Run As User attribute. Also, if you do use a Chain Definition, it is not necessary for every process in it to run on this particular Windows server. You can run other processes on other servers if necessary.

You can use the jtool screenshot facility to monitor progress and any visual errors.

Example

Chain with Steps for Opening and Closing the Session

A basic Chain using Windows Sessions support has the following layout:

Copy
Step 1
  System_Windows_Session_Create
Step 2
  MSLN_Screenshot
Step 3
  System_Windows_Session_Close

In the Chain editor, under Step 3, select the field of the Opaque session handle JCS_SESSION parameter. Then hover over the process in Step 1 and select the JCS_SESSION from the parameter list. Add a new parameter on the Chain named Accounts of type String array, and map that with the JCS_SESSION_ACCOUNTS of System_Windows_Session_Create in Step 1. Finally, choose the JCS_SESSION parameter of Step 2, then hover over the process in Step 1 and select JCS_SESSION from the parameter list.

The MSLN_Screenshot Process Definition is of type CMD and uses the following Source script:

jtool screenshot

Make sure the Process Definition has a String parameter named JCS_SESSION with direction In.

Result

Submitting the Chain Definition with Accounts set to jdoe@example creates an RDP session for user jdoe (Step 1), takes a screen shot (Step 2), and finally closes the RDP session (Step 3).

Single Process

  1. Duplicate System_Windows_Session_Create and give it a new name.
  2. Specify {logoff} in the Run As User field. This makes sure the user is logged off once the code in the Source field has been run.
  3. Select a Script Type. In this example, the script is PS1 (PowerShell). It creates a temporary file with some text, opens the text file with notepad.exe, takes a screen shot, and finally closes the notepad.exe window.
Copy
jtool echo 'Created session'
jtool screenshot

$tmpfile = [System.IO.Path]::GetTempFilename()
Set-Content -Value "Hello World" $tmpfile
$ntpd = start-process notepad $tmpfile -PassThru
Start-Sleep -m 500
jtool screenshot
$tmpout = $ntpd.CloseMainWindow()
$ntpd.Close()