Use a Pipe to get a Console Command's Output into a String

Started by Theo Gottwald, February 03, 2024, 10:02:43 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Theo Gottwald

We're excited to share the results from the discussion in the Third Party Forum! 💬 A breakthrough came from using a DLL that was originally created in a different language. 🤝🔧🌐

Exploring cross-language solutions opens up a world of possibilities! 🌟 #Innovation #TechTalk #Programming #DLL #SoftwareDevelopment #CrossLanguageCoding 🛠�💻🌍🔄

'========================================================================================================
'Demonstration for PBCC and PBWin of using a pipe to get the output from a console command into a string
'This avoids the commmon method of using Shell, directing the command's output to a file, reading the file and the deleting it
'Output string is displayed in a messagebox or console depending on compiler
'=========================================================================================================
'========================================================================================================
'PipeToString SLL for PBCC
'=========================================================================================================
#COMPILE SLL "PipeToString-PBCC.SLL"
#DIM ALL
DECLARE FUNCTION popen CDECL LIB "msvcrt.dll" ALIAS "_popen" (BYREF cmd AS STRINGZ, BYREF MODE AS STRINGZ) AS DWORD
DECLARE FUNCTION fread CDECL LIB "msvcrt.dll" ALIAS "fread" (BYVAL buffer AS DWORD, BYVAL elemSize AS DWORD, BYVAL elemCount AS DWORD, BYVAL fp AS DWORD) AS DWORD
DECLARE FUNCTION fclose CDECL LIB "msvcrt.dll" ALIAS "fclose" (BYVAL fp AS DWORD) AS LONG

FUNCTION PipeToString(cmdIn AS STRING) COMMON AS STRING
    LOCAL sbOut AS ISTRINGBUILDERA
    LOCAL szBuf AS STRINGZ * 1024
    LOCAL szCmdIn AS STRINGZ * 256
    LOCAL hP,dwBytesRead  AS DWORD
    szCmdIn = cmdIn
    hP = popen(szCmdIn, "rb")
    IF hP = 0 THEN : EXIT FUNCTION
    sbOut = CLASS "StringBuilderA"
    DO
        dwBytesRead = fread(VARPTR(szBuf), 1, SIZEOF(szBuf), hP)
        sbOut.Add(LEFT$(szBuf, dwBytesRead))
    LOOP WHILE dwBytesRead = SIZEOF(szBuf)
    fclose(hP)
    FUNCTION = sbOut.string
END FUNCTION


#COMPILE EXE "PipeToStringSLLDemo-PBCC"
#DIM ALL
#LINK "PipeToString-PBCC.SLL"
FUNCTION PBMAIN () AS LONG
    LOCAL sResult AS STRING
    LOCAL sCmd AS STRING
    sCmd = "ipconfig /all"
    sResult = PipeToString(sCmd)
    STDOUT sResult ' sends formatted output to console (CON.PRINT doesn't recognise line breaks)
    WAITKEY$
END FUNCTION
'


'========================================================================================================
'PipeToString SLL for PBWin
'=========================================================================================================
#COMPILE SLL "PipeToString-PBWin"
#DIM ALL
#INCLUDE "win32api.inc"
DECLARE FUNCTION popen CDECL LIB "msvcrt.dll" ALIAS "_popen" (BYREF cmd AS STRINGZ, BYREF MODE AS STRINGZ) AS DWORD
DECLARE FUNCTION fread CDECL LIB "msvcrt.dll" ALIAS "fread" (BYVAL buffer AS DWORD, BYVAL elemSize AS DWORD, BYVAL elemCount AS DWORD, BYVAL fp AS DWORD) AS DWORD
DECLARE FUNCTION fclose CDECL LIB "msvcrt.dll" ALIAS "fclose" (BYVAL fp AS DWORD) AS LONG

FUNCTION PipeToString(cmdIn AS STRING) COMMON AS WSTRING
    LOCAL sbOut AS ISTRINGBUILDERA
    LOCAL szBuf AS STRINGZ * 1024
    LOCAL szCmdIn AS STRINGZ * 256
    LOCAL hP,dwBytesRead  AS DWORD
    szCmdIn = cmdIn
    allocconsole
    SetWindowPos(GetConsoleWindow(), %NULL, 0, 0, 0, 0, %SWP_NOZORDER)
    hP = popen(szCmdIn, "rb")
    IF hP = 0 THEN : EXIT FUNCTION
    sbOut = CLASS "StringBuilderA"
    DO
        dwBytesRead = fread(VARPTR(szBuf), 1, SIZEOF(szBuf), hP)
        sbOut.Add(LEFT$(szBuf, dwBytesRead))
    LOOP WHILE dwBytesRead = SIZEOF(szBuf)
    fclose(hP)
    Freeconsole
    FUNCTION = OEMTOCHR$(sbOut.string)
END FUNCTION
'

#COMPILE EXE "PipeToStringSLL-PBWinDemo"
#DIM ALL
#LINK "PipeToString-PBWIn.SLL"

FUNCTION PBMAIN () AS LONG
    LOCAL wsResult AS WSTRING
    LOCAL sCmd AS STRING
    sCmd = "tree c:\devsystems\pbmisc"
     wsResult = PipeToString(sCmd)
     ? wsResult,,sCmd
     CLIPBOARD RESET
     CLIPBOARD SET TEXT wsResult  'paste into an editor with a fixed width font to see it properly formatted.
END FUNCTION
'