Print to the consoleTag(s): Win API


Many thanks to J. Vendra for the help

With Powerbuilder, it's possible to create a program to process data and terminate immediately without any user interaction. This kind of program, called batch program, is launched in a DOS shell, typically from scripting file like a CMD or BAT file)

One missing thing is that Powerbuilder provides no direct API to display information in the console to display processing or debugging information.

To do that you need to make WinAPI calls.

First create a UserObject

[UserObject  uo_console  autoinstantiate]

[instance variables]
CONSTANT long ATTACH_PARENT_PROCESS = -1

CONSTANT long STD_OUTPUT_HANDLE = -11
CONSTANT long STD_ERROR_HANDLE = -12
CONSTANT long STD_INPUT_HANDLE = -10
long hwnd

[local external functions]
FUNCTION boolean AttachConsole(long ProcID) LIBRARY "kernel32.dll"
FUNCTION long GetStdHandle(long nStdHandle) LIBRARY "kernel32.dll"
FUNCTION int FreeConsole() LIBRARY "Kernel32.dll"
FUNCTION ulong WriteConsole(long Handle, String OutPut, long NumCharsToWrite, &
     REF long NumCharsWritten, long reserved) LIBRARY "Kernel32.dll" ALIAS FOR "WriteConsoleW"
SUBROUTINE keybd_event( int bVk, int bScan, int dwFlags, int dwExtraInfo) LIBRARY "user32.dll"
SUBROUTINE ExitProcess(ulong uExitCode) LIBRARY "kernel32.dll"

[constructor event]
IF Handle(GetApplication()) > 0 THEN
   IF AttachConsole(ATTACH_PARENT_PROCESS) THEN
      hwnd = GetStdHandle(STD_OUTPUT_HANDLE)
   ELSE
      SetNull(hwnd)
   END IF
END IF

[destructor event]
IF Handle(GetApplication()) > 0 THEN
   keybd_event( 13, 1, 0, 0 )
   FreeConsole()
   ExitProcess(1)
END IF

[function println (string as_string) returns none]
string s
long result

IF Handle(GetApplication()) = 0 OR IsNull(hwnd) THEN
   MessageBox("Debug", as_string)
ELSE
   s = as_string + "~r~n"
   WriteConsole(hwnd, s, len(s), result, 0)
END IF
To use it, create a small application (name console). In the open event, add this code :
uo_console debug

debug.println("")
debug.println("Hello world")
debug.println("from Real's HowTo")
debug.println("bye!")
Compile and Deploy as a EXE file (called console.exe). Open a DOS Windows where console.exe is located and launch it.

Expected output :

> start /wait console.exe
Hello World
from Real's HowTo
bye!

>

NOTES:
If running from the IDE then a MessageBox is used, the Windows console API is used only when the code is running from an executable and a console is available.

You can't redirect the output to a file ( console.exe > output.log ), the Windows Console API can't do that.

See also : Use Windows Debugging API


blog comments powered by Disqus