Can't find the information you are looking for here? Then leave a message over on our WinBatch Tech Support Forum.
Keywords: stdin DOS redirection pipe guiguy gui guy
;============================================================================================= ;= udflib.redirection.wbt ;= WinBatch Library of User Defined Functions for Redirecting the Output of a Child Process ;= ;= Translated to WinBatch by GUI Guy, August 2002 (http://guiguy.wminds.com) ;= ;= The following references were used as a guide: ;= http://msdn.microsoft.com/library/en-us/dllproc/prothred_4uus.asp ;= http://community.borland.com/article/0,1410,10387,00.html ;= http://support.microsoft.com/default.aspx?scid=KB;EN-US;q190351& ;= http://doc.ddart.net/msdn/header/include/winbase.h.html ;= http://forum.winbatch.com ;============================================================================================= ;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ #DefineFunction udfRunRedirected(app, params) ;<<<<<< udfRunRedirected >>>>>>>>>>>>>>>>>>>>>> ;///////////////////////////////////////////////////////////////////////////////////////////// ; Runs an executable file with redirected STDOUT & STDERR (I may add support for STDIN soon) ; Returns an array containing the following elements: ; [0] handle to pipe which receives the redirected output (or -1 if the function fails) ; [1] PROCID (process ID) of the child process ; ; app = path of program to execute as child ; params = command-line parameters to pass to child process ;API Constants ; uncomment the ones you use if you modify the code ;STD_INPUT_HANDLE = -10 STD_OUTPUT_HANDLE = -11 STD_ERROR_HANDLE = -12 DUPLICATE_SAME_ACCESS = 2 CREATE_NEW_CONSOLE = 16 STARTF_USESTDHANDLES = 256 STARTF_USESHOWWINDOW = 1 SECURITY_DESCRIPTOR_REVISION = 1 ;constants for SHOWWINDOW options SW_HIDE = 0 ;SW_SHOWNORMAL = 1 ;SW_NORMAL = 1 ;SW_SHOWMINIMIZED = 2 ;SW_SHOWMAXIMIZED = 3 ;SW_MAXIMIZE = 3 ;SW_SHOWNOACTIVATE = 4 ;SW_SHOW = 5 ;SW_MINIMIZE = 6 ;SW_SHOWMINNOACTIVATE = 7 ;SW_SHOWNA = 8 ;SW_RESTORE = 9 ;SW_SHOWDEFAULT = 10 ;SW_MAX = 10 ReturnInfo=ArrDimension(2) ;Initialize array to hold info returned by this function ; Save the handle to the current STDOUT & STDERR. (For restoration after child process is created.) Win95/98/ME only If WinVersion(4)==5 ;If running on Win95/98/ME hSaveStdout = DllCall(StrCat(DirWindows(1),"kernel32.dll"),long:"GetStdHandle",long:STD_OUTPUT_HANDLE) If !hSaveStdout ;if API call failed, set error and return function ReturnInfo[0]=-1 ReturnInfo[1]=StrCat("GetStdHandle for STDOUT failed. Errorcode = ",DllLastError()) return(ReturnInfo) endif hSaveStderr = DllCall(StrCat(DirWindows(1),"kernel32.dll"),long:"GetStdHandle",long:STD_ERROR_HANDLE) If !hSaveStderr ReturnInfo[0]=-1 ReturnInfo[1]=StrCat("GetStdHandle for STDERR failed. Errorcode = ",DllLastError()) return(ReturnInfo) endif endif ; Create a pipe for the child process's STDOUT & STDERR. (one pipe for both - future versions may handle STDERR and STDOUT separately) bbChildStdoutRd=BinaryAlloc(4) ;allocate buffer to hold read handle for STDOUT & STDERR bbChildStdoutWr=BinaryAlloc(4) ;allocate buffer to hold write handle for STDOUT & STDERR ;Define SECURITY_ATTRIBUTES structure for CreatePipe API call so that handles are inheritable by the child bbSEC_ATTR = BinaryAlloc(12) ; allocate buffer to hold structure BinaryPoke4(bbSEC_ATTR,0,12) ; size of SECURITY_ATTRIBUTES structure (DWORD nLength;) If WinVersion(4)==4 ;If running on WinNT/2000/XP initialize security descriptor bbSEC_DESC = BinaryAlloc(20) if !DllCall(StrCat(DirWindows(1),"advapi32.dll"),long:"InitializeSecurityDescriptor",lpbinary:bbSEC_DESC,long:SECURITY_DESCRIPTOR_REVISION) ReturnInfo[0]=-1 ReturnInfo[1]=StrCat("InitializeSecurityDescriptor failed. Errorcode = ",DllLastError()) return(ReturnInfo) endif if !DllCall(StrCat(DirWindows(1),"advapi32.dll"),long:"SetSecurityDescriptorDacl",lpbinary:bbSEC_DESC,long:1,lpnull,long:0) ReturnInfo[0]=-1 ReturnInfo[1]=StrCat("SetSecurityDescriptorDacl failed. Errorcode = ",DllLastError()) return(ReturnInfo) endif BinaryPoke4(bbSEC_ATTR,4,IntControl (42, bbSEC_DESC, 0, 0, 0)) ; pointer to security descriptor else BinaryPoke4(bbSEC_ATTR,4,0) ; null pointer for security descriptor (LPVOID lpSecurityDescriptor;) endif BinaryPoke4(bbSEC_ATTR,8,@TRUE) ;inheritable attribute of SECURITY_ATTRIBUTES structure (BOOL bInheritHandle;) ;Create the pipe: if !DllCall(StrCat(DirWindows(1),"kernel32.dll"),long:"CreatePipe",lpbinary:bbChildStdoutRd,lpbinary:bbChildStdoutWr,lpbinary:bbSEC_ATTR,long:0) ReturnInfo[0]=-1 ReturnInfo[1]=StrCat("CreatePipe failed. Errorcode = ",DllLastError()) return(ReturnInfo) endif BinaryFree(bbSEC_ATTR) ; Free buffer BinaryFree(bbSEC_DESC) ; Free buffer BinaryEodSet(bbChildStdoutWr, 4) ;Set EOD so handle can be accessed with BinaryPeek hChildStdoutWr=BinaryPeek4(bbChildStdoutWr,0) ; write handle for pipe to redirect child's output BinaryFree(bbChildStdoutWr) ;free buffer BinaryEodSet(bbChildStdoutRd, 4) ;Set EOD so handle can be accessed with BinaryPeek hChildStdoutRd=BinaryPeek4(bbChildStdoutRd,0) ; read handle for pipe to redirect child's output BinaryFree(bbChildStdoutRd) ;free buffer ; set child's STDOUT & STDERR handle to the write end of the pipe If !DllCall(StrCat(DirWindows(1),"kernel32.dll"),long:"SetStdHandle",long:STD_OUTPUT_HANDLE,long:hChildStdoutWr) ReturnInfo[0]=-1 ReturnInfo[1]=StrCat("SetStdHandle failed while setting child STDOUT to write pipe. Errorcode = ",DllLastError()) return(ReturnInfo) endif If !DllCall(StrCat(DirWindows(1),"kernel32.dll"),long:"SetStdHandle",long:STD_ERROR_HANDLE,long:hChildStdoutWr) ReturnInfo[0]=-1 ReturnInfo[1]=StrCat("SetStdHandle failed while setting child STDERR to write pipe. Errorcode = ",DllLastError()) return(ReturnInfo) endif ; Create noninheritable read handle and close the inheritable read handle. hCurProcess=DllCall(StrCat(DirWindows(1),"kernel32.dll"),long:"GetCurrentProcess") ;handle for current process is needed for DuplicateHandle API call bbChildStdoutRdDup=BinaryAlloc(4) ;allocate buffer to hold duplicate handle if !DllCall(StrCat(DirWindows(1),"kernel32.dll"),long:"DuplicateHandle",long:hCurProcess,long:hChildStdoutRd,long:hCurProcess,lpbinary:bbChildStdoutRdDup,long:0,long:0,long:DUPLICATE_SAME_ACCESS) ReturnInfo[0]=-1 ReturnInfo[1]=StrCat("DuplicateHandle failed. Errorcode = ",DllLastError()) return(ReturnInfo) endif hChildStdoutRdDup=BinaryPeek4(bbChildStdoutRdDup,0) BinaryFree(bbChildStdoutRdDup) ;free buffer DllCall(StrCat(DirWindows(1),"kernel32.dll"),long:"CloseHandle",long:hChildStdoutRd) ;close the inheritable read handle ; Create Process ; Set up members of the PROCESS_INFORMATION structure. bbPROC_INFO=BinaryAlloc(16) ; allocate buffer to hold structure BinaryPoke4(bbPROC_INFO,0,0) ; HANDLE hProcess BinaryPoke4(bbPROC_INFO,4,0) ; HANDLE hThread BinaryPoke4(bbPROC_INFO,8,0) ; DWORD dwProcessId BinaryPoke4(bbPROC_INFO,12,0); DWORD dwThreadId ; Set up members of the STARTUPINFO structure. bbSTARTINFO=BinaryAlloc(68) BinaryPoke4(bbSTARTINFO,0,68); DWORD cb size of structure BinaryPoke4(bbSTARTINFO,4,0) ; LPTSTR lpReserved BinaryPoke4(bbSTARTINFO,8,0) ; LPTSTR lpDesktop BinaryPoke4(bbSTARTINFO,12,0); LPTSTR lpTitle BinaryPoke4(bbSTARTINFO,16,0); DWORD dwX BinaryPoke4(bbSTARTINFO,20,0); DWORD dwY BinaryPoke4(bbSTARTINFO,24,0); DWORD dwXSize BinaryPoke4(bbSTARTINFO,28,0); DWORD dwYSize BinaryPoke4(bbSTARTINFO,32,0); DWORD dwXCountChars BinaryPoke4(bbSTARTINFO,36,0); DWORD dwYCountChars BinaryPoke4(bbSTARTINFO,40,0); DWORD dwFillAttribute BinaryPoke4(bbSTARTINFO,44,STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES); DWORD dwFlags BinaryPoke2(bbSTARTINFO,48,SW_HIDE); WORD wShowWindow (dwFlags must have STARTF_USESHOWWINDOW bitwise OR'd else this setting is ignored) BinaryPoke2(bbSTARTINFO,50,0); WORD cbReserved2 BinaryPoke4(bbSTARTINFO,52,0); LPBYTE lpReserved2 BinaryPoke4(bbSTARTINFO,56,0); HANDLE hStdInput BinaryPoke4(bbSTARTINFO,60,hChildStdoutWr); HANDLE hStdOutput BinaryPoke4(bbSTARTINFO,64,hChildStdoutWr); HANDLE hStdError ; Create the child process. ; return CreateProcess( ; &app, // application to execute ; ¶ms, // command-line parameters ; NULL, // process security attributes ; NULL, // primary thread security attributes ; TRUE, // handles are inherited ; 0, // creation flags ; NULL, // use parent's environment ; NULL, // use parent's current directory ; &siStartInfo, // STARTUPINFO pointer ; &piProcInfo); // receives PROCESS_INFORMATION if !DllCall(StrCat(DirWindows(1),"kernel32.dll"),long:"CreateProcessA",lpnull,lpstr:StrCat('"',app,'" ',params),lpnull,lpnull,long:1,long:0,lpnull,lpnull,lpbinary:bbSTARTINFO,lpbinary:bbPROC_INFO) ReturnInfo[0]=-1 ReturnInfo[1]=StrCat("CreateProcess failed. Errorcode = ",DllLastError()) return(ReturnInfo) endif BinaryFree(bbSTARTINFO) ;restore saved STDOUT & STDERR (Win95/98/ME only) If WinVersion(4)==5 ;If running on Win95/98/ME if !DllCall(StrCat(DirWindows(1),"kernel32.dll"),long:"SetStdHandle",long:STD_OUTPUT_HANDLE,long:hSaveStdout) ReturnInfo[0]=-1 ReturnInfo[1]=StrCat("SetStdHandle failed (STDOUT). Errorcode = ",DllLastError()) return(ReturnInfo) endif if !DllCall(StrCat(DirWindows(1),"kernel32.dll"),long:"SetStdHandle",long:STD_ERROR_HANDLE,long:hSaveStderr) ReturnInfo[0]=-1 ReturnInfo[1]=StrCat("SetStdHandle failed (STDERR). Errorcode = ",DllLastError()) return(ReturnInfo) endif endif ReturnInfo[0]=hChildStdoutRdDup ;handle to pipe ReturnInfo[1]=BinaryPeek4(bbPROC_INFO,8) ;ProcessID BinaryFree(bbPROC_INFO) Return(ReturnInfo) #EndFunction ;<<<<< udfRunRedirected >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ #DefineFunction udfPipeDataWaiting(handle) ;<<<<< udfPipeDataWaiting >>>>>>>>>>>>>>>>>>>>>>>>> ;///////////////////////////////////////////////////////////////////////////////////////////// ; ; Checks a pipe to see if there is DATA waiting to be read ; Returns number of unread bytes in pipe or -1 if function failed (use DllLastError to determine the error) ; ; handle = handle of pipe to check bbNumBytesInBuffer=BinaryAlloc(4) if !DllCall(StrCat(DirWindows(1),"kernel32.dll"),long:"PeekNamedPipe",long:handle, lpnull, long:0, lpnull, lpbinary:bbNumBytesInBuffer, lpnull) then Return(-1) BinaryEodSet(bbNumBytesInBuffer, 4) BytesInPipe= BinaryPeek4(bbNumBytesInBuffer,0) BinaryFree(bbNumBytesInBuffer) Return (BytesInPipe) #EndFunction ;<<<<< udfPipeDataWaiting >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ #DefineFunction udfPipeReadLine(handle) ;<<<<< udfPipeReadLine >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ;///////////////////////////////////////////////////////////////////////////////////////////// ; ; Read a line from child's stdout ; Returns one line of data from pipe if CR or LF found, else returns remaining data in pipe (or -1 on failure) ; ; handle = handle of pipe to check readLine="" ;Get number of bytes in Pipe bbNumBytesInPipe=BinaryAlloc(4) if !DllCall(StrCat(DirWindows(1),"kernel32.dll"),long:"PeekNamedPipe",long:handle, lpnull, long:0, lpnull, lpbinary:bbNumBytesInPipe, lpnull) return(-1) endif BinaryEodSet(bbNumBytesInPipe, 4) BytesInPipe= BinaryPeek4(bbNumBytesInPipe,0) BinaryFree(bbNumBytesInPipe) ;Copy contents of pipe into binary buffer bb=BinaryAlloc(BytesInPipe) bbRead=BinaryAlloc(4) if !DllCall(StrCat(DirWindows(1),"kernel32.dll"),long:"PeekNamedPipe",long:handle, lpbinary:bb, long:BytesInPipe, lpbinary:bbRead, lpnull, lpnull) return(-1) endif BinaryEodSet(bbRead, 4) BytesRead= BinaryPeek4(bbRead,0) BinaryEodSet(bb, BytesRead) BinaryFree(bbRead) ;find EOL (end of line) eol=BinaryIndexEx(bb, 0, @CR, @FWDSCAN, 0) if eol==-1 eol=BinaryIndexEx(bb, 0, @LF, @FWDSCAN, 0) if eol==-1 eol=BytesRead ;if no EOL character, get ALL remaining data in pipe else eol=eol+1 ;since BinaryIndexEx returns 0 based index endif else if BinaryIndexEx(bb, eol, @LF, @FWDSCAN, 0)==1 then eol=eol+1 ;if linefeed after carraige return, we want to remove it from pipe too eol=eol+1 ;since BinaryIndexEx returns 0 based index endif BinaryFree(bb) ;Read one line of data from Pipe bbReadLine=BinaryAlloc(BytesRead) bbBytesRead=BinaryAlloc(4) if !DllCall(StrCat(DirWindows(1),"kernel32.dll"),long:"ReadFile",long:handle, lpbinary:bbReadLine, long:eol, lpbinary:bbBytesRead, long:0) then return(-1) BinaryEodSet(bbBytesRead, 4) length=BinaryPeek4(bbBytesRead,0) BinaryEodSet(bbReadLine, length) readLine=BinaryPeekStr(bbReadLine, 0, length) BinaryFree(bbReadLine) BinaryFree(bbBytesRead) ;Standardize all EOL characters readLine=StrReplace(readline, @CR, "") readline=StrReplace(readline, @LF, "") readLine=StrCat(readLine,@CRLF) return(readline) #EndFunction ;<<<<< udfPipeReadLine >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;============================================================================================= ;= RedirectionExample.wbt ;= Example program for demonstrating the use of the udflib.redirection.wbt library ;= ;= Coded in WinBatch by GUI Guy, August 2002 (http://guiguy.wminds.com) ;============================================================================================= ;Change the path below to reflect where you placed the library on your system #include "Redirection UDF.wbt" ;Dynamic dialog constants DIALOG_INIT = 0 DIALOG_TIMERTICK = 1 DIALOG_PUSH = 2 DIALOG_RADIO = 3 DIALOG_CHECK = 4 DIALOG_EDIT = 5 DIALOG_FILESEL = 6 DIALOG_ITEMSEL = 7 DIALOG_ITEMCHANGE = 8 DIALOG_DATECHANGE = 9 DIALOG_NUMCHANGE = 10 DIALOG_CLOSE = 11 #DEFINESUBROUTINE procRedirEx(DialogHandle, EventCode, ControlNum, Res4, Res5) oncancel="exit" switch(EventCode) case DIALOG_INIT DialogProcOptions(DialogHandle, DIALOG_PUSH, 1) DialogProcOptions(DialogHandle, DIALOG_EDIT, 1) break case DIALOG_PUSH if ControlNum == 5 ;Browse gosub Browse DialogControlSet(DialogHandle, 10, 4, StrCat(edtApp," ",edtParams)) return -2 endif if ControlNum == 11 ;Run gosub RunRedirected return -2 endif if ControlNum == 12 ;Exit return 99 endif break case DIALOG_EDIT DialogControlSet(DialogHandle, 10, 4, StrCat(DialogControlGet(DialogHandle,4,3)," ",DialogControlGet(DialogHandle,8,3))) break case DIALOG_TIMERTICK while udfPipeDataWaiting(Pipe_Info[0]) > 0 ReadLine=udfPipeReadLine(Pipe_Info[0]) if ReadLine == -1 Message("Error (udfReadLine):",DLLLastError()) exit endif newOutput=StrCat(newOutput,ReadLine) DialogControlSet(DialogHandle,1,3, newOutput) endwhile if !WinExist(title) then DialogProcOptions(DialogHandle, DIALOG_TIMERTICK, 0) ;if child has exited, then turn off timer event return -1 break endswitch return -1 :browse oncancel="goto bresume" temp=edtApp edtApp=AskfileName("Select the DOS program to run redirected...", "", "Executable Files (*.exe,*.com)|*.exe;*.com|All Files (*.*)|*.*|", edtApp, 2) :bresume if edtApp=="0" then edtApp = temp DialogControlSet(DialogHandle, 4, 3, edtApp) return :RunRedirected if DialogControlGet(DialogHandle,4,3) != "" if !FileExist(DialogControlGet(DialogHandle,4,3)) message("Oops","Specified program doesn't exist...") else params=DialogControlGet(DialogHandle,8,3) Pipe_Info=udfRunRedirected(DialogControlGet(DialogHandle,4,3), params) DialogProcOptions(DialogHandle, DIALOG_TIMERTICK, 1) ;timer event every 1/4 second newoutput="" delay(.125) title = WinItemProcId(Pipe_Info[1], 2|8, 0) ;get title of DOS window launched above endif endif return :cancel ; CANCEL Handler %oncancel% exit #ENDSUBROUTINE dlgRedirExFormat=`WWWDLGED,6.1` dlgRedirExCaption=`Redirection Example Dialog` dlgRedirExX=-01 dlgRedirExY=-01 dlgRedirExWidth=240 dlgRedirExHeight=157 dlgRedirExNumControls=012 dlgRedirExProcedure=`procRedirEx` dlgRedirExFont=`DEFAULT` dlgRedirExTextColor=`DEFAULT` dlgRedirExBackground=`DEFAULT,DEFAULT` dlgRedirEx001=`006,079,225,067,MULTILINEBOX,medtOutput,DEFAULT,DEFAULT,12,8,DEFAULT,DEFAULT,DEFAULT` dlgRedirEx002=`001,071,233,080,GROUPBOX,DEFAULT,"Redirected output:",DEFAULT,11,DEFAULT,DEFAULT,DEFAULT,DEFAULT` dlgRedirEx003=`001,001,233,057,GROUPBOX,DEFAULT,"Command-line program to run with redirected STDOUT && STDERR:",DEFAULT,1,DEFAULT,DEFAULT,DEFAULT,DEFAULT` dlgRedirEx004=`031,012,161,011,EDITBOX,edtApp,DEFAULT,DEFAULT,2,DEFAULT,DEFAULT,DEFAULT,DEFAULT` dlgRedirEx005=`196,012,035,011,PUSHBUTTON,DEFAULT,"Browse",1,3,DEFAULT,DEFAULT,DEFAULT,DEFAULT` dlgRedirEx006=`006,014,023,010,STATICTEXT,DEFAULT,"Program:",DEFAULT,7,DEFAULT,DEFAULT,DEFAULT,DEFAULT` dlgRedirEx007=`006,030,063,010,STATICTEXT,DEFAULT,"Parameters:",DEFAULT,8,DEFAULT,DEFAULT,DEFAULT,DEFAULT` dlgRedirEx008=`071,028,160,011,EDITBOX,edtParams,DEFAULT,DEFAULT,4,DEFAULT,DEFAULT,DEFAULT,DEFAULT` dlgRedirEx009=`001,039,233,019,GROUPBOX,DEFAULT,DEFAULT,DEFAULT,9,DEFAULT,DEFAULT,DEFAULT,DEFAULT` dlgRedirEx010=`006,047,225,011,STATICTEXT,DEFAULT,DEFAULT,DEFAULT,10,DEFAULT,DEFAULT,DEFAULT,DEFAULT` dlgRedirEx011=`158,062,034,010,PUSHBUTTON,DEFAULT,"Run",2,5,32,DEFAULT,DEFAULT,DEFAULT` dlgRedirEx012=`196,062,035,010,PUSHBUTTON,DEFAULT,"Exit",0,6,DEFAULT,DEFAULT,DEFAULT,DEFAULT` ButtonPushed=Dialog("dlgRedirEx") exit
But I did notice how slickly it packages the output. No pif files, no temp files to hold output text. Really tidy.
So here's my attempt to simplify the RunRedirected idea for when you are willing to simply wait to get all your output at once. One call runs the command and returns the output.
#include "udflib_redirection.wbt" #definefunction udfSimpleRunRedirected(app, params, maxtime, maxchars) ; app is executeable program ; params is parameter string for app ; maxtime is seconds to spend waiting for completion ; maxchars is maximum chars to accept for return data ; ; return is array: [0] is status, 1=success, -1=fail inside runredirected, -2=out of time ; [1] output data string ; arrStat = udfRunRedirected(app, params) if arrstat[0] < 0 then return arrStat incr = 0.25 ; granularity of delay buf = "" while 1 ; grab window (if still there) pid = WinItemProcId(arrStat[1],2|8,0) ; loop for any data remaining in the pipe while strlen(buf) gosub piperead if bit == "*ERR*" then goto errorret if bit == "*EOF*" then break buf = strcat(buf, bit) endwhile ; was window gone? if pid == "" || pid == 0 arrStat[0] = 1 arrStat[1] = buf return arrStat endif ; decrement wait time maxtime = maxtime - incr if maxtime < 0 arrStat[0] = -2 arrStat[1] = buf return arrStat endif ; snooze timedelay(incr) endwhile x=1/0 :errorret arrStat[0] = -3 arrStat[1] = DllLastError() return arrStat :piperead ;--- subroutine --- bit = "" ; return data in here handle = arrStat[0] k32dll = StrCat(DirWindows(1),"kernel32.dll") ;Get number of bytes in Pipe bbBytesInPipe = BinaryAlloc(4) if !DllCall(k32dll,long:"PeekNamedPipe",long:handle, lpnull, long:0, lpnull, lpbinary:bbBytesInPipe, lpnull) bit = "*ERR*" return endif BinaryEodSet(bbBytesInPipe, 4) BytesInPipe = BinaryPeek4(bbBytesInPipe, 0) BinaryFree(bbBytesInPipe) ;nothing? were done if BytesInPipe == 0 bit = "*EOF*" return endif ;set to read remainder needed BytesToRead = Min(BytesInPipe,maxchars-strlen(buf)) ;Get pipe contents bbBit = BinaryAlloc(BytesToRead) bbBytesRead = BinaryAlloc(4) if !DllCall(k32dll,long:"ReadFile",long:handle, lpbinary:bbBit, long:BytesToRead, lpbinary:bbBytesRead, long:0) bit = "*ERR*" return endif BinaryEodSet(bbBytesRead, 4) length = BinaryPeek4(bbBytesRead, 0) BinaryEodSet(bbBit, length) bit = BinaryPeekStr(bbBit, 0, length) BinaryFree(bbBit) BinaryFree(bbBytesRead) return #endfunction a = udfSimpleRunRedirected("command.com","/c dir c:\*.dll /s",5,65535) a[1] = strreplace(a[1],@crlf,@lf) askitemlist(a[0],a[1],@lf,@unsorted,@single) exit
a = udfSimpleRunRedirected("command.com","/c dir c:\*.dll /s /-p",5,65535)... runs a little bit more 'continous' ...
Article ID: W15729
File Created: 2014:07:18:09:51:40
Last Updated: 2014:07:18:09:51:40