CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 10 of 10
  1. #1
    Join Date
    Nov 1999
    Location
    Ohio, USA
    Posts
    7

    Capturing DOS Output

    Hello,

    I am developing an application that needs to "capture" the text that a DOS prompt displays. For example, I am wanting to Shell out to a compiler for assembly language with a command line, and then capture the output to display in my program. I have tried "piping" the output to a file by doing this for example...

    "C:\compiler.exe -h" > "C:\test.txt"

    This will "pipe" the output to the file "C:\test.txt". This works for some executables, but not for all of them..? I am wanting to find a bullet proof method to doing this so that it will work for all compilers. Is there a way to read a console's output buffers from VB..?

    Any examples, thoughts, ideas, or leads to finding this information would be greatly appreciated.

    Thanks for your time...


    Please visit VB Overdrive at:
    http://extreme-vb.net/vboverdrive/

  2. #2
    Join Date
    Nov 1999
    Posts
    7

    Re: Capturing DOS Output

    Hi
    I think in this link you will find somthing to help you

    http://www.**************/ArticleBank...ID=ArticleBank

    Regards
    SulSDK




  3. #3
    Join Date
    Nov 1999
    Location
    Ohio, USA
    Posts
    7

    Re: Capturing DOS Output

    Thanks that was exactly what I was looking for..!

    But now I have another problem. One executable I want to read the output of apparently does not send it's output to stdOut. Is there any other way to do this so that you could read the output to any device..?

    Thanks,
    Jared Hoylman

    Please visit VB Overdrive at:
    http://extreme-vb.net/vboverdrive/

  4. #4
    Join Date
    May 1999
    Posts
    3,332

    Re: Capturing DOS Output

    This looked like an excellent link.
    But, then I downloaded it and wanted to use it and found that it sucked in so many parts, that I finally gave up. Did you try it?
    did you get it to work?
    No matter what DOS program I used, I never got any redirection to work, although all the DOS programs I tried direct their output to stdout or stderr.


  5. #5
    Join Date
    May 1999
    Posts
    3,332

    Re: Capturing DOS Output

    if you got that sample to work, I'd like to see your source code. I failed miserably.

    you can not only redirect output to stdout, but also to stderr.
    si.hStdOutput = yourFirstFileOpenedbycreateFile
    si.hStdError = yourSecondFile



  6. #6
    Join Date
    May 1999
    Posts
    3,332

    Re: Capturing DOS Output

    I have just created a sample app in VB 6 and tested it under win NT.
    It allows you to capture output to stdout or stderr by a dos app.


    option Explicit

    public Declare Function WaitForSingleObject Lib "kernel32" (byval hHandle as Long, byval dwMilliseconds as Long) as Long
    public Const INFINITE = &HFFFF
    public Const STARTF_USESHOWWINDOW = &H1
    public Const SW_HIDE = 0

    public Const DUPLICATE_SAME_ACCESS = &H2
    public Declare Function DuplicateHandle Lib "kernel32" (byval hSourceProcessHandle as Long, byval hSourceHandle as Long, byval hTargetProcessHandle as Long, lpTargetHandle as Long, byval dwDesiredAccess as Long, byval bInheritHandle as Long, byval dwOptions as Long) as Long

    public Declare Function GetCurrentProcess Lib "kernel32" () as Long

    private Declare Function CreatePipe Lib "kernel32" ( _
    phReadPipe as Long, _
    phWritePipe as Long, _
    lpPipeAttributes as Any, _
    byval nSize as Long) as Long

    public Type OVERLAPPED
    Internal as Long
    InternalHigh as Long
    offset as Long
    OffsetHigh as Long
    hEvent as Long
    End Type

    public Declare Function ReadFile Lib "kernel32" (byval hFile as Long, _
    lpBuffer as Any, _
    byval nNumberOfBytesToRead as Long, _
    lpNumberOfBytesRead as Long, _
    lpOverlapped as Any) as Long
    private Type SECURITY_ATTRIBUTES
    nLength as Long
    lpSecurityDescriptor as Long
    bInheritHandle as Long
    End Type

    private Type STARTUPINFO
    cb as Long
    lpReserved as Long
    lpDesktop as Long
    lpTitle as Long
    dwX as Long
    dwY as Long
    dwXSize as Long
    dwYSize as Long
    dwXCountChars as Long
    dwYCountChars as Long
    dwFillAttribute as Long
    dwFlags as Long
    wShowWindow as Integer
    cbReserved2 as Integer
    lpReserved2 as Long
    hStdInput as Long
    hStdOutput as Long
    hStdError as Long
    End Type

    private Type PROCESS_INFORMATION
    hProcess as Long
    hThread as Long
    dwProcessID as Long
    dwThreadID as Long
    End Type

    private Declare Function CreateProcessA Lib "kernel32" (byval _
    lpApplicationName as Long, byval lpCommandLine as string, _
    lpProcessAttributes as Any, lpThreadAttributes as Any, _
    byval bInheritHandles as Long, byval dwCreationFlags as Long, _
    byval lpEnvironment as Long, byval lpCurrentDirectory as Long, _
    lpStartupInfo as Any, lpProcessInformation as Any) as Long

    private Declare Function CloseHandle Lib "kernel32" (byval _
    hObject as Long) as Long

    private Const NORMAL_PRIORITY_CLASS = &H20&
    private Const STARTF_USESTDHANDLES = &H100&

    public Function ExecCmd(byval strcmd as string) as string
    Dim proc as PROCESS_INFORMATION, ret as Long, bSuccess as Long
    Dim start as STARTUPINFO
    Dim sa as SECURITY_ATTRIBUTES, hReadPipe as Long, hWritePipe _
    as Long
    Dim hReadErrpipe as Long
    Dim hWriteErrpipe as Long
    Dim bytesread as Long, mybuff as string
    Dim i as Integer

    mybuff = string(1000, vbNullChar)

    sa.nLength = len(sa)
    sa.bInheritHandle = 1&
    sa.lpSecurityDescriptor = 0&

    ret = CreatePipe(hReadPipe, hWritePipe, sa, 0)
    If ret = 0 then
    MsgBox "CreatePipe failed. error: " & Err.LastDllError
    Exit Function
    End If
    ret = CreatePipe(hReadErrpipe, hWriteErrpipe, sa, 0)
    If ret = 0 then
    MsgBox "CreatePipe failed for stderr. error: " & Err.LastDllError
    Exit Function
    End If


    Dim hReadpipedup as Long
    bSuccess = DuplicateHandle(GetCurrentProcess(), hReadPipe, GetCurrentProcess(), _
    hReadpipedup, 0&, 0&, DUPLICATE_SAME_ACCESS)
    If bSuccess = 0 then
    MsgBox "failed to dup"
    End If
    CloseHandle hReadPipe

    Dim hReaderrpipedup as Long
    bSuccess = DuplicateHandle(GetCurrentProcess(), hReadErrpipe, GetCurrentProcess(), _
    hReaderrpipedup, 0&, 0&, DUPLICATE_SAME_ACCESS)
    If bSuccess = 0 then
    MsgBox "failed to dup"
    End If
    CloseHandle hReadErrpipe

    start.cb = len(start)
    start.dwFlags = STARTF_USESTDHANDLES Or STARTF_USESHOWWINDOW
    start.wShowWindow = SW_HIDE
    start.hStdOutput = hWritePipe
    start.hStdError = hWriteErrpipe
    ' start app
    ret& = CreateProcessA(0&, strcmd, sa, sa, 1&, _
    NORMAL_PRIORITY_CLASS, 0&, 0&, start, proc)
    If ret <> 0 then
    WaitForSingleObject proc.hProcess, INFINITE
    else
    MsgBox "CreateProcess failed. error: " & Err.LastDllError
    End If

    CloseHandle hWritePipe
    CloseHandle hWriteErrpipe
    Dim strText as string
    bSuccess = ReadFile(hReadpipedup, byval mybuff, 1000, bytesread, byval 0&)
    If bSuccess = 1 then
    strText = Left(mybuff, bytesread)
    End If
    bSuccess = ReadFile(hReaderrpipedup, byval mybuff, 1000, bytesread, byval 0&)
    If bSuccess = 1 then
    strText = strText & Left(mybuff, bytesread)
    End If

    CloseHandle proc.hProcess
    CloseHandle proc.hThread
    CloseHandle hReadPipe
    CloseHandle hReadErrpipe
    CloseHandle hReadpipedup
    CloseHandle hReaderrpipedup
    ExecCmd = strText
    End Function




    call the function like this:
    msgbox execcmd("link.exe")
    or
    msgbox execcmd("dumpbin /?")
    or
    msgbox execcmd("mc.exe")

    it will return a concatenation of the output of the program to stdout and stderr.

    Is it bulletproof?
    no, because some DOS apps might still decide to write directly to the screen buffer.
    But, it will probably work for most apps.

    The ExecCMd function will restrict the output to 1000 bytes. Feel free to modify it.


  7. #7
    Join Date
    Nov 2000
    Posts
    6

    Re: Capturing DOS Output

    Hi There!
    I tried this code exactly as it is. I placed a module and pasted everything there. Next I had a command button on a form with a code:

    command1_click()
    msgbox execcmd("c:\TASM\compile.bat")
    end sub

    but the program hangs everytime. Please Help me.
    Thanks alot!

    (im using VB6 on Windows98)



  8. #8
    Join Date
    Jul 2000
    Location
    Milano, Italy
    Posts
    7,726

    Re: Capturing DOS Output

    It is great to read from you again, even at distant time.

    Special thanks to Lothar "the Great" Haensler. Come back soon, you Guru.
    ...at present time, using mainly Net 4.0, Vs 2010



    Special thanks to Lothar "the Great" Haensler, Chris Eastwood , dr_Michael, ClearCode, Iouri and
    all the other wonderful people who made and make Codeguru a great place.
    Come back soon, you Gurus.

  9. #9
    Join Date
    Apr 2001
    Posts
    19

    Re: Capturing DOS Output

    Hallo,
    I execute a my VB6 program from Dos prompt.
    The program write some word in the Dos prompt but, when I write chr(13), I see (obviously) "Comando o nome di file non valido".
    So, I want to capture this sentence so it doesn't appear in the Dos box.
    Your example is great, but it create the process while the process is already active in my program (is the batch who execute my program!).
    For example, if you go in Dos prompt and type "dir /?" you see the correct syntax; I want to optain an output like this; instead, when I write chr(13) from my program to the Dos Box I see the message above.

    How can I do this?

    Looking forward for prompt replay.

    b.r.

    Cristiano Larghi



  10. #10
    Join Date
    Jul 2000
    Location
    Milano, Italy
    Posts
    7,726

    Re: Capturing DOS Output

    Ciao, Cristiano. E' un peccato che il grande Lothar non frequnti più questo sito - senza dubbio ti avrebbe suggerito la dritta giusta!-
    Ti consiglio di riscrivere una nuova domanda, così il popolo di codeguru la legger* più facilmente.
    Ciao,
    Cesare

    Special thanks to Lothar "the Great" Haensler. Come back soon, you Guru.
    ...at present time, using mainly Net 4.0, Vs 2010



    Special thanks to Lothar "the Great" Haensler, Chris Eastwood , dr_Michael, ClearCode, Iouri and
    all the other wonderful people who made and make Codeguru a great place.
    Come back soon, you Gurus.

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

Featured