Results 1 to 2 of 2

Thread: STDOut and STDErr

Threaded View

  1. #1

    Thread Starter
    Frenzied Member
    Join Date
    Nov 2005
    Posts
    1,834

    STDOut and STDErr

    Hello, I'm using the module below to write the output of a commandline tool to STDOut and STDErr. The problem is that both STDOut and STDErr get written to the same pipe and are eventually in the same string.

    Below is an example of what ExecCmd will show. Above the line is STDOut and below the line is STDErr.

    Is there a way to put STDOut and STDErr in two different strings, so I can show STDOut in a multiline textbox and STDErr in a msgbox?

    Code:
    UNRAR 3.50 freeware      Copyright (c) 1993-2005 Alexander Roshal
    
    
    Extracting from D:\Archives\My.Video.part1.rar
    
    Extracting  D:\My.Video.avi                                              
    
    Extracting from D:\Archives\My.Video.part2.rar
    
    ...         My.Video.avi                                                 
    
    Extracting from D:\Archives\My.Video.part3.rar
    
    ...         My.Video.avi                                                 
    
    Extracting from D:\Archives\My.Video.part4.rar
    
    ...         My.Video.avi                                     
    ----------------------------------------------------------------------------
    Cannot find volume D:\Archives\My.Video.part5.rar            
    My.Video.avi         - CRC failed
    Total errors: 1
    Module:

    VB Code:
    1. Option Explicit
    2.  
    3.  
    4. Private Declare Function CreateProcessA Lib "kernel32" (ByVal _
    5.     lpApplicationName As Long, ByVal lpCommandLine As String, _
    6.     lpProcessAttributes As Any, lpThreadAttributes As Any, _
    7.     ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, _
    8.     ByVal lpEnvironment As Long, ByVal lpCurrentDirectory As Long, _
    9.     lpStartupInfo As Any, lpProcessInformation As Any) As Long
    10.  
    11.  
    12. Private Declare Function CloseHandle Lib "kernel32" (ByVal _
    13.     hObject As Long) As Long
    14.  
    15.  
    16. Private Declare Function CreatePipe Lib "kernel32" ( _
    17.     phReadPipe As Long, _
    18.     phWritePipe As Long, _
    19.     lpPipeAttributes As Any, _
    20.     ByVal nSize As Long) As Long
    21.  
    22.  
    23. Private Declare Function ReadFile Lib "kernel32" ( _
    24.     ByVal hFile As Long, _
    25.     ByVal lpBuffer As String, _
    26.     ByVal nNumberOfBytesToRead As Long, _
    27.     lpNumberOfBytesRead As Long, _
    28.     ByVal lpOverlapped As Any) As Long
    29.  
    30.  
    31. Declare Function PeekNamedPipe Lib "kernel32" ( _
    32.     ByVal hNamedPipe As Long, _
    33.     lpBuffer As Any, _
    34.     ByVal nBufferSize As Long, _
    35.     lpBytesRead As Long, _
    36.     lpTotalBytesAvail As Long, _
    37.     lpBytesLeftThisMessage As Long _
    38.     ) As Long
    39.  
    40.  
    41. Private Declare Function GetExitCodeProcess Lib _
    42.     "kernel32" (ByVal hProcess As Long, lpExitCode _
    43.     As Long) As Long
    44.    
    45.  
    46.  
    47. Private Type SECURITY_ATTRIBUTES
    48.     nLength As Long
    49.     lpSecurityDescriptor As Long
    50.     bInheritHandle As Long
    51.     End Type
    52.    
    53.  
    54.  
    55. Private Type STARTUPINFO
    56.     cb As Long
    57.     lpReserved As Long
    58.     lpDesktop As Long
    59.     lpTitle As Long
    60.     dwX As Long
    61.     dwY As Long
    62.     dwXSize As Long
    63.     dwYSize As Long
    64.     dwXCountChars As Long
    65.     dwYCountChars As Long
    66.     dwFillAttribute As Long
    67.     dwFlags As Long
    68.     wShowWindow As Integer
    69.     cbReserved2 As Integer
    70.     lpReserved2 As Long
    71.     hStdInput As Long
    72.     hStdOutput As Long
    73.     hStdError As Long
    74.     End Type
    75.  
    76.  
    77. Private Type PROCESS_INFORMATION
    78.     hProcess As Long
    79.     hThread As Long
    80.     dwProcessId As Long
    81.     dwThreadId As Long
    82.     End Type
    83.  
    84.  
    85. Private Type PIPE
    86.     hReadPipe As Long
    87.     hWritePipe As Long
    88.     End Type
    89.     Private Const CREATE_NEW_CONSOLE = &H10
    90.     Public Const NORMAL_PRIORITY_CLASS = &H20&
    91.     Private Const STARTF_USESHOWWINDOW = &H1
    92.     Private Const STARTF_USESIZE = &H2
    93.     Private Const STARTF_USEPOSITION = &H4
    94.     Private Const STARTF_USECOUNTCHARS = &H8
    95.     Private Const STARTF_USEFILLATTRIBUTE = &H10
    96.     Private Const STARTF_RUNFULLSCREEN = &H20
    97.     Private Const STARTF_FORCEONFEEDBACK = &H40
    98.     Private Const STARTF_FORCEOFFFEEDBACK = &H80
    99.     Private Const STARTF_USESTDHANDLES = &H100
    100.     'Window settings flags
    101.     Private Const SW_HIDE = 0
    102.     Private Const SW_SHOWNORMAL = 1
    103.     Private Const SW_NORMAL = 1
    104.     Private Const SW_SHOWMINIMIZED = 2
    105.     Private Const SW_SHOWMAXIMIZED = 3
    106.     Private Const SW_MAXIMIZE = 3
    107.     Private Const SW_SHOWNOACTIVATE = 4
    108.     Private Const SW_SHOW = 5
    109.     Private Const SW_MINIMIZE = 6
    110.     Private Const SW_SHOWMINNOACTIVE = 7
    111.     'This displays the new window, but keeps the current window active
    112.     Private Const SW_SHOWNA = 8
    113.     Private Const SW_RESTORE = 9
    114.     'This passes on the settings from the SW_flags
    115.     Private Const SW_SHOWDEFAULT = 10
    116.     Private Const SW_MAX = 10
    117.     Private Const INVALID_HANDLE_VALUE = -1
    118.     Private Const STILL_ACTIVE = &H103&
    119.     'This function runs cmdLine$ and returns the stdout/err from that program
    120.     'The function does not end until cmdLine$ has closed
    121.     'The biggest problem with the original function was that if the shelled program did NOT
    122.     'write anything to stdout/err, the function would freeze up at
    123.     'bSuccess = ReadFile(hReadPipe, mybuff, 1024, bytesread, 0&)
    124.     'This rewrite of the code fixes that, and waits for the app to close before returning anything
    125.  
    126.  
    127. Public Function ExecCmd(cmdLine$) As String
    128.     Dim proc As PROCESS_INFORMATION, ret As Long, bSuccess As Long, pID As Long
    129.     Dim start As STARTUPINFO
    130.     Dim sa As SECURITY_ATTRIBUTES, hReadPipe As Long, hWritePipe As Long
    131.     Dim bytesread As Long, mybuff As String
    132.     Dim intBytesToRead As Long
    133.     Dim Result As Long
    134.     Dim tBytesA As Long, tBytesR As Long, tMsg As Long, Bytes As Long
    135.     Dim ExitCode As Long
    136.    
    137.     '4kb should be enough to read most things
    138.     intBytesToRead = 4096
    139.     mybuff = String(CInt(intBytesToRead), Chr$(65))
    140.     sa.nLength = Len(sa)
    141.     sa.bInheritHandle = 1&
    142.     sa.lpSecurityDescriptor = 0&
    143.     'Create the pipe
    144.     ret = CreatePipe(hReadPipe, hWritePipe, sa, 0)
    145.    
    146.     'If creating a pipe failed, we fail the function
    147.  
    148.  
    149.     If ret = 0 Then
    150.         ExecCmd = Null
    151.         Exit Function
    152.     End If
    153.     start.cb = Len(start)
    154.     'Any combination of the STARTF_ flags can be used here by writing
    155.     'start.dwFlags = STARTF_1 + STARTF_2...etc
    156.     start.dwFlags = STARTF_USESHOWWINDOW + STARTF_USESTDHANDLES 'Hidden the window
    157.     'start.dwFlags = STARTF_USESTDHANDLES 'Visible window
    158.     start.hStdOutput = hWritePipe
    159.     start.hStdError = hWritePipe
    160.     'The SW_ flags are only used if STARTF_USESHOWWINDOW is set above
    161.     start.wShowWindow = SW_HIDE
    162.    
    163.     ' Start the shelled application:
    164.     ret& = CreateProcessA(0&, cmdLine$, sa, sa, 1&, _
    165.     NORMAL_PRIORITY_CLASS, 0&, 0&, start, proc)
    166.    
    167.  
    168.  
    169.     Do
    170.         'Check to see if the app closed
    171.         GetExitCodeProcess proc.hProcess, ExitCode
    172.         'Check to see if there is any unread stuff in the pipe
    173.         'This check is nessasary, other the ReadFile function will hang if there is nothing in the pipe
    174.         Result = PeekNamedPipe(hReadPipe, ByVal 0&, 0, tBytesR, tBytesA, tMsg)
    175.         'If so, read it
    176.  
    177.  
    178.         If Result <> 0 And tBytesA > 0 Then
    179.             bSuccess = ReadFile(hReadPipe, mybuff, intBytesToRead, bytesread, 0&)
    180.             ExecCmd = ExecCmd & Left(mybuff, tBytesA)
    181.         End If
    182.         'This is needed to reduce overhead, otherwise our app will hang until this function ends
    183.  
    184.  
    185.         DoEvents
    186.             'Don't quit looping until the app has closed
    187.        
    188.         Loop While ExitCode = STILL_ACTIVE
    189.        
    190.         'Close everything down, if still running
    191.  
    192.         ret& = CloseHandle(proc.hProcess)
    193.         ret& = CloseHandle(proc.hThread)
    194.         ret& = CloseHandle(hReadPipe)
    195.         ret& = CloseHandle(hWritePipe)
    196.        
    197.     End Function
    Last edited by Chris001; Feb 17th, 2006 at 04:09 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width