Catalog · How the catalog works
gllAutomationServer
In-app automation server for Delphi VCL applications
- ★ 2 on GitHub
Anyone may press Interesting, signed in or not. It helps others find this project.
README
gllAutomationServer
An in-app automation server for Delphi VCL applications. Link one unit, start it on an explicit
opt-in, and an external agent can drive and inspect the running application over a loopback
socket: click, type, read and write properties (including nested ones like Font.Size), answer
modal dialogs, read and edit datasets, and take screenshots. It works on the live VCL component
model, not on pixels, so it is coordinate-free and DPI-independent, and it runs in Release builds.
Built for unattended UI testing by an AI agent (GITLAKMCP's app_* tools, a private client), and by
DUnitX suites with no AI in the loop (gllAutomationServer.Client, the public client in this
repository: launch an app, drive it, assert, close it). The protocol is plain newline-delimited JSON,
and any client can speak it.
- Users Guide.md — add it to an application and drive it.
- Help.md — the reference: commands, addressing, error codes, threading, API.
- CHANGELOG.md — the history.
At a glance
// the .dpr
uses ..., gllAutomationServer;
...
Application.Initialize;
if FindCmdLineSwitch( 'AUTOMATION' ) then
TAutomationServer.Start( 'MyApp' );{ "token":"…", "id":1, "cmd":"keys", "form":"main", "name":"edtCustomer", "text":"ACME", "keys":"Tab" }
{ "id":1, "ok":true, "result":{ "target":"edtCustomer", "strokes":5, "strokesSent":5, "completed":true, "modalOpen":false } }Without the opt-in nothing is created. With it, the server listens on 127.0.0.1 only, and every
request must carry a per-session token from a discovery file that only the current user,
Administrators and SYSTEM can read.
Requirements
-
Delphi 13 Florence (RAD Studio 37.0), VCL, Win32 and Win64.
-
Packages that ship with Delphi:
rtl,vcl,vclimg,dbrtl; and Indy'sIndySystem,IndyCore(bundled with Delphi, or Indy 10 from GitHub - see below). -
Indy: developed and tested with Indy 10 from GitHub (IndySockets/Indy), through gllIndy10, GITLAK's private fork of it; here "Indy 10 from GitHub" always means that upstream repository. It should work fine with the Indy that ships with Delphi too: it uses only Indy 10's basics (
TIdTCPServer,TIdTCPClient,ReadLn/WriteLnwith a line-length limit,ReadLnTimedout,IndyTextEncoding_UTF8), all present in Delphi 13's bundled Indy 10.6.3.The GitHub Indy 10 is preferred, for three reasons:
- It fixes a hang this server reaches.
TIdTCPServercould wait for ever when it shut down: a finished connection thread was left in the scheduler's active list (TIdSchedulerOfThread.TerminateYarn). We found and fixed it, and the fix was merged upstream on 2026-09-30 as Indy issue #699 / PR #700, after Delphi 13 shipped, so the bundled copy does not have it. This server shuts its listener down every time an app closes, so with the bundled Indy an app driven with/AUTOMATIONcan occasionally hang on exit; a GUI suite that launches and closes apps many times a run would see that as sporadic time-outs. - It is newer. Upstream is well ahead of Delphi 13's snapshot (gllIndy10 is level with upstream
10.6.3.15), and carries the fixes made since it. - It is what this was tested with, through gllIndy10, which tracks upstream and whose fixes have regression tests of their own.
So use the bundled Indy if you must, and expect the occasional shutdown hang until a Delphi update ships an Indy with the fix.
- It fixes a hang this server reaches.
Building
gllAutomationServerPkg.dproj is a runtime-only package ({$RUNONLY}). Build all four modes (Win32 and
Win64, Debug and Release). The package is gllAutomationServerPkg (gllAutomationServerPkg370.bpl), not
gllAutomationServer: a package must never share a name with a unit it contains (see the .dpk header;
on Win32 the clash hung every IDE that loaded a package requiring this one). The DCUs land in 37.0\<Platform>\<Config>, and the BPL and DCP go to the
shared Bpl / Dcp folders (Release in <Platform>, Debug in <Platform>\Debug).
- An application links the unit statically: put
<your clone>\37.0\<Platform>\Releaseon the IDE's library path (Tools > Options > Language > Delphi > Library) for both platforms. - A package that uses it (gllIdeAutomation does) puts
gllAutomationServerPkgin itsrequiresclause.
Tests
Tests\gllAutomationServerTests.dproj is a DUnitX console project (Win64). To build it:
- Build this package first: the suite links its DCUs from
..\37.0\<Platform>\<Config>. - Clone gllDUnitX (public, a fork of DUnitX) beside this
repository, so that the two folders share a parent: the project's search path takes
..\..\gllDUnitX\Source\GllforGllDUnitX.Station. - DUnitX itself comes from the library path, as RAD Studio installs it.
Run the suite on an interactive desktop: several tests are GUI tests (a modal dialog, screenshots) that need a painted window and ignore themselves without one.
Who uses it
- The 27 applications of GITLAK Software's DBiWorkflow suite, started on
/AUTOMATION. - gllIdeAutomation, in
gllIdeAutomation\in this repository: a design-time package that runs the server inside the Delphi IDE and adds the IDE's own commands (ToolsAPI, debugger panes) withRegisterCommand. It has its own README, Help, Users Guide and CHANGELOG there.
Repository layout
gllAutomationServerPkg.dpk / .dproj the runtime package
gllAutomationServer.pas the server unit, linked statically by applications
Tests\ its DUnitX suite
gllIdeAutomation\ the IDE host - a design-time package that requires the serverThe two were separate repositories until 2026-10-13; gllIdeAutomation's history came across in a
subtree merge, and its old tags are gllIdeAutomation-v1.0.0, -v1.0.1 and -v1.2.0.
Licence
Proprietary - GITLAK Software; the source is published for reference. See LICENSE: viewing and forking on GitHub are permitted, and nothing else is licensed. Commits that carry an MIT LICENSE file (2026-08-08 to the relicensing commit of 2026-10-13) are MIT as that file says, and copies of them keep the rights MIT granted; nothing from the relicensing commit onward is.
Credits
Portions adapted from GExperts' GxInspect by Thomas Mueller, by permission (see LICENSE);
the tree_text technique is his.
Contributing
Issues are welcome. Pull requests are not accepted: the code is proprietary.

