File "conspawn.inc"
Path: /zrok launcher/inc/conspawn.inc
File size: 4.6 KB
MIME-type: text/plain
Charset: utf-8
'------------------------------------------------------------------------------
' conspawn.inc - library for PowerBasic.
' Allows to launch, attach, get info from, and close a console exe
' In your callback:
' - at the very beginning, call CON_CALLBACK
' - spawn a console exe via CON_LAUNCH CB.HNDL, "myprog.exe", visible, tempo
' (visible = 0|1 ; tempo is the frequence in ms to
' check on the exe and call the CON_HANDLER() Sub)
' - implement the following Sub:
DECLARE SUB CON_HANDLER(BYVAL ConContent AS STRING)
' (ConContent is the content of the spawned console)
'------------------------------------------------------------------------------
#INCLUDE ONCE "WinCon.inc"
'------------------------------------------------------------------------------
GLOBAL g_Con_Prog AS STRING
GLOBAL g_Con_Viso AS LONG
GLOBAL g_Con_Freq AS LONG
GLOBAL g_Con_Status AS LONG
'------------------------------------------------------------------------------
FUNCTION CON_LAUNCH(BYVAL hDlg AS DWORD, _
BYVAL prog AS STRING, _
BYVAL viso AS LONG, _
BYVAL freq AS LONG) AS LONG
g_Con_Prog = prog
g_Con_Viso = viso
g_Con_Freq = freq
g_Con_Status = %STILL_ACTIVE
DIALOG POST hDlg, %WM_APP, 0, 0
' WHILE g_Con_Status = %STILL_ACTIVE
' DIALOG DOEVENTS
' SLEEP 0
' WEND
FUNCTION = g_Con_Status
END FUNCTION
'------------------------------------------------------------------------------
'------------------------------------------------------------------------------
MACRO CON_CALLBACK
STATIC s_hCon, s_pid AS DWORD
STATIC s_tmr, s_visu AS LONG
LOCAL buf AS ASCIIZ * 512
LOCAL file AS STRING
LOCAL hInfo AS DWORD
LOCAL conStatus AS LONG
SELECT CASE AS LONG CB.MSG
CASE %WM_APP
' Check that the exe we need to spawn actually exists
conStatus = INSTR(LCASE$(g_Con_Prog), ".exe")
IF conStatus <> 0 THEN
buf = LEFT$(g_Con_Prog, conStatus + LEN(".exe")-1)
buf = TRIM$(buf, $DQ)
file = DIR$(buf) : DIR$ CLOSE
END IF
IF file = "" THEN
g_Con_Status = 1
CON_HANDLER "Fatal error: "+buf+" not found in " + EXE.PATH$
SLEEP 1000
CON_HANDLER "<end>"
EXIT FUNCTION
END IF
' Spawn exe via Shell
s_pid = SHELL (g_Con_Prog, g_Con_Viso)
SLEEP 1000
' Attach the corresponding console and get its handle
AttachConsole(s_pid)
s_hCon = GetStdHandle(%STD_OUTPUT_HANDLE)
' Start the timer to read console content at given frequence
s_tmr = SetTimer(CB.HNDL, %WM_USER + 42, g_Con_Freq, BYVAL 0)
DIALOG POST CB.HNDL, %WM_TIMER, %WM_USER + 42, 0
CASE %WM_APP + 1
IF s_pid = 0 THEN EXIT FUNCTION
' Attach the corresponding console and get its dialog handle
AttachConsole(s_pid)
hInfo = GetConsoleWindow()
IF hInfo = 0 THEN EXIT FUNCTION
s_visu = 1 - s_visu
ShowWindow hInfo, IIF(ISTRUE s_visu, %SW_SHOW, %SW_HIDE)
CASE %WM_DESTROY
' If parent dialog (this program) is killed then kill spawned process as well
IF ISTRUE s_tmr THEN KillTimer CB.HNDL, s_tmr
IF ISTRUE s_hCon THEN
FreeConsole ()
s_hCon = OpenProcess(%PROCESS_TERMINATE, %FALSE, s_pid)
TerminateProcess(s_hCon, 0)
CloseHandle(s_hCon)
END IF
ExitProcess(0)
CASE %WM_TIMER
IF CB.WPARAM = %WM_USER + 42 THEN
' Check status of spawn process
hInfo = OpenProcess(%PROCESS_QUERY_INFORMATION, %FALSE, s_pid)
GetExitCodeProcess(hInfo, conStatus)
CloseHandle(hInfo)
' Spawn is finished: end timer + call CON_HANDLER one last time with empty buffer
IF conStatus <> %STILL_ACTIVE THEN
KillTimer CB.HNDL, s_tmr : s_tmr = 0
FreeConsole () : s_hCon = 0
g_Con_Status = conStatus
CON_HANDLER "<end>"
EXIT FUNCTION
END IF
' Else spawn is active: call CON_HANDLER with console content
readConsoleOutputCharacter (s_hCon, BYVAL VARPTR (buf), 512, "", hInfo)
CON_HANDLER buf
END IF
END SELECT
END MACRO
'------------------------------------------------------------------------------