Launch executable and capture its handleTag(s): Win API


This HowTo launch an executable using the Win API ShellExecuteEx and retrieve the handle of the launched executable. This handle can be used later to interact with it. Like, for example, if we want to terminate it form Powerbuilder.

First define a structure for ShellExecuteEx

[structure shellexecuteinfo]
 long      cbSize
 long      fMask
 long      hwnd
 string    lpVerb
 string    lpFile
 string    lpParameters
 string    lpDirectory
 long      nShow
 long      hInstApp
 long      lpIDList
 string    lpClass
 long      hkeyClass
 long      dwHotKey
 long      hIcon
 long      hProcess
Next declare the external functions
FUNCTION long ShellExecuteEx(REF shellexecuteinfo lpExecInfo) &
 LIBRARY "shell32.dll" ALIAS FOR "ShellExecuteExW"

FUNCTION long TerminateProcess(long hwndF, int exitcode) &
 LIBRARY "kernel32.dll"
This example will launch Chrome, display a MessageBox to show the Handle. When the MessageBox is closed, Chrome is terminated.
// https://docs.microsoft.com/en-us/windows/win32/api/shellapi/ns-shellapi-shellexecuteinfoa
CONSTANT long  SEE_MASK_CLASSNAME = 1
CONSTANT long  SEE_MASK_NOCLOSEPROCESS = 64
CONSTANT long  SEE_MASK_NOASYNC = 256
CONSTANT long SW_NORMAL = 1

string ls_class, ls_verb
long ll_ret
shellexecuteinfo s_shellexecuteinfo

s_shellexecuteinfo.cbsize = 60
s_shellexecuteinfo.fMask = SEE_MASK_NOCLOSEPROCESS
s_shellexecuteinfo.hwnd = Handle(this)
s_shellexecuteinfo.lpVerb = "open"
s_shellexecuteinfo.lpFile = "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"
s_shellexecuteinfo.lpParameters = "--window-size=600,700 --window-position=600,200 --new-window --user-data-dir=c:/temp/x" + string(rand(100)) + " --app=https://rgagnon.com"
//s_shellexecuteinfo.lpDirectory=""
s_shellexecuteinfo.lpClass = ls_class
s_shellexecuteinfo.nShow = SW_NORMAL

ll_ret = ShellExecuteEx(s_shellexecuteinfo)
IF ll_ret = 0 THEN
   messagebox("errcode", s_shellexecuteinfo.hInstApp)
ELSE
   messagebox("handle", String(s_shellexecuteinfo.hProcess))
   TerminateProcess(s_shellexecuteinfo.hProcess, 1)
END IF
Note: when launching Chrome, we specify a user-data-dir to make sure that a new Chrome is started.