Home All Groups Group Topic Archive Search About

Excuting a command line program from within VB

Author
9 May 2007 6:01 PM
Patrick Matthews
On a button click I want to execute a DOS batch file, what is the easiest
way doing this?

Author
9 May 2007 6:09 PM
Darhl Thomason
"Patrick Matthews" <pmatth***@chw.org> wrote in message
news:%233QtPQmkHHA.208@TK2MSFTNGP05.phx.gbl...
> On a button click I want to execute a DOS batch file, what is the easiest
> way doing this?
>

Use the Shell command.

' Specifying 1 as the second argument opens the application in
' normal size and gives it the focus.
Dim RunApp
RunApp = Shell("c:\mybatchfile.bat", 1)
Author
10 May 2007 4:39 PM
Patrick Matthews
Thanks that worked. How can I redirect the output of that command to a text
box on a form?

Show quoteHide quote
"Darhl Thomason" <darhlt@papamurphys.nospamplease.com> wrote in message
news:uaE64UmkHHA.744@TK2MSFTNGP05.phx.gbl...
>
> "Patrick Matthews" <pmatth***@chw.org> wrote in message
> news:%233QtPQmkHHA.208@TK2MSFTNGP05.phx.gbl...
>> On a button click I want to execute a DOS batch file, what is the easiest
>> way doing this?
>>
>
> Use the Shell command.
>
> ' Specifying 1 as the second argument opens the application in
> ' normal size and gives it the focus.
> Dim RunApp
> RunApp = Shell("c:\mybatchfile.bat", 1)
>
Author
10 May 2007 6:36 PM
MikeD
Show quote Hide quote
>> "Patrick Matthews" <pmatth***@chw.org> wrote in message
>> news:%233QtPQmkHHA.208@TK2MSFTNGP05.phx.gbl...
>>> On a button click I want to execute a DOS batch file, what is the
>>> easiest way doing this?
>>>
>>
>> Use the Shell command.
>>
>> ' Specifying 1 as the second argument opens the application in
>> ' normal size and gives it the focus.
>> Dim RunApp
>> RunApp = Shell("c:\mybatchfile.bat", 1)
>>
>

"Patrick Matthews" <pmatth***@chw.org> wrote in message
news:%23w4JaHykHHA.1220@TK2MSFTNGP03.phx.gbl...
> Thanks that worked. How can I redirect the output of that command to a
> text box on a form?


You can't.

Redirect the output to file, and then open and read that file and assign its
contents to your textbox.  To my knowledge, that's about the only thing you
can do.

You might want to tell us what this batch file does.  There might be a
better solution that doesn't involve running a batch file at all.

--
Mike
Microsoft Visual Basic MVP
Author
10 May 2007 7:42 PM
Patrick Matthews
I got rid of the batch file and am running the command directly. What I am
trying to do is... create an application that will run on users desktops
that will execute a command on a remote to run on the remote server. That
command generates a list of items known to that particular server for the
user to review. As i have it now, the command works, but it brings up a DOS
window, executes and closes the DOS window, in about 3 seconds. So what I
want it to do is place the contents of what is displayed in the DOS window,
into a text box. I'm thinking your idea below may work , I just thought I
could redirect the results directly to a (read-only)text box, so the user
could actually see it and close the window at thier own discreation.
Show quoteHide quote
"MikeD" <nob***@nowhere.edu> wrote in message
news:udfquIzkHHA.4628@TK2MSFTNGP06.phx.gbl...
>>> "Patrick Matthews" <pmatth***@chw.org> wrote in message
>>> news:%233QtPQmkHHA.208@TK2MSFTNGP05.phx.gbl...
>>>> On a button click I want to execute a DOS batch file, what is the
>>>> easiest way doing this?
>>>>
>>>
>>> Use the Shell command.
>>>
>>> ' Specifying 1 as the second argument opens the application in
>>> ' normal size and gives it the focus.
>>> Dim RunApp
>>> RunApp = Shell("c:\mybatchfile.bat", 1)
>>>
>>
>
> "Patrick Matthews" <pmatth***@chw.org> wrote in message
> news:%23w4JaHykHHA.1220@TK2MSFTNGP03.phx.gbl...
>> Thanks that worked. How can I redirect the output of that command to a
>> text box on a form?
>
>
> You can't.
>
> Redirect the output to file, and then open and read that file and assign
> its contents to your textbox.  To my knowledge, that's about the only
> thing you can do.
>
> You might want to tell us what this batch file does.  There might be a
> better solution that doesn't involve running a batch file at all.
>
> --
> Mike
> Microsoft Visual Basic MVP
>
>
>
>
Author
10 May 2007 8:04 PM
Karl E. Peterson
MikeD <nob***@nowhere.edu> wrote:
Show quoteHide quote
>>> "Patrick Matthews" <pmatth***@chw.org> wrote ...
>>>> On a button click I want to execute a DOS batch file, what is the
>>>> easiest way doing this?
>>>
>>> Use the Shell command.
>>>
>>> ' Specifying 1 as the second argument opens the application in
>>> ' normal size and gives it the focus.
>>> Dim RunApp
>>> RunApp = Shell("c:\mybatchfile.bat", 1)
>>
>> Thanks that worked. How can I redirect the output of that command to a
>> text box on a form?
>
> You can't.
>
> Redirect the output to file, and then open and read that file and assign its
> contents to your textbox.  To my knowledge, that's about the only thing you
> can do.

There's another option, but it's a real stretch whether to recommend it to a guy who
isn't altogether up on Shell.  Here's the rough outline, with attribution in the
comments...

   Private Function ExecAndCapture(ByVal CmdLine As String, Optional ByVal
StartFolder As String = vbNullString) As String
      ' http://www.vb-helper.com/howto_capture_console_stdout.html
      Dim hPipeRead As Long
      Dim hPipeWrite As Long
      Dim sa As SECURITY_ATTRIBUTES
      Dim si As STARTUPINFO
      Dim pi As PROCESS_INFORMATION
      Dim Buffer() As Byte
      Dim StdOut As New CStringBuilder
      Dim lBytesRead As Long
      Dim ExitCode As Long
      Const BUFSIZE As Long = 1024 * 10

      With sa
         .nLength = Len(sa)
         .bInheritHandle = 1    ' get inheritable pipe handles
      End With 'SA

      If CreatePipe(hPipeRead, hPipeWrite, sa, 0) = 0 Then
         Exit Function
      End If

      With si
         .cb = Len(si)
         .dwFlags = STARTF_USESHOWWINDOW Or STARTF_USESTDHANDLES
         .wShowWindow = SW_HIDE
         .hStdOutput = hPipeWrite
         .hStdError = hPipeWrite
      End With 'SI

      If CreateProcess(vbNullString, CmdLine, ByVal 0&, ByVal 0&, 1, 0&, ByVal 0&,
StartFolder, si, pi) Then
         Call CloseHandle(hPipeWrite)
         Call CloseHandle(pi.hThread)

         ReDim Buffer(0 To BUFSIZE - 1) As Byte
         Do
            DoEvents
            If ReadFile(hPipeRead, Buffer(0), UBound(Buffer) + 1, lBytesRead, ByVal
0&) = 0 Then
               Exit Do
            End If
            Debug.Print Replace$(Left$(StrConv(Buffer, vbUnicode), lBytesRead), vbCr
& vbCrLf, vbCrLf);
            StdOut.Append Replace$(Left$(StrConv(Buffer, vbUnicode), lBytesRead),
vbCr & vbCrLf, vbCrLf)
         Loop
         Call CloseHandle(pi.hProcess)
      End If

      ' To make sure...
      Call CloseHandle(hPipeRead)
      Call CloseHandle(hPipeWrite)

      ' Return results.
      ExecAndCapture = StdOut.ToString
   End Function

It works.
--
..NET: It's About Trust!
http://vfred.mvps.org
Author
10 May 2007 8:26 PM
Patrick Matthews
Thanks for the recommendation, but "a real stretch" is an understatement. I
used to do some VB programming back in the days of VB4 & 5 and I do a fair
amount of VB scripting now. So by NO means am I any kind of programmer. I'm
just trying to get something accomplished and VB script won't cut it. So...
on a whim I thought I would try it in straight VB. Things are coming back to
me but i have to ask the stupid questions to jog my memory. Thanks for the
help


Show quoteHide quote
"Karl E. Peterson" <k***@mvps.org> wrote in message
news:OIgil5zkHHA.4248@TK2MSFTNGP06.phx.gbl...
> MikeD <nob***@nowhere.edu> wrote:
>>>> "Patrick Matthews" <pmatth***@chw.org> wrote ...
>>>>> On a button click I want to execute a DOS batch file, what is the
>>>>> easiest way doing this?
>>>>
>>>> Use the Shell command.
>>>>
>>>> ' Specifying 1 as the second argument opens the application in
>>>> ' normal size and gives it the focus.
>>>> Dim RunApp
>>>> RunApp = Shell("c:\mybatchfile.bat", 1)
>>>
>>> Thanks that worked. How can I redirect the output of that command to a
>>> text box on a form?
>>
>> You can't.
>>
>> Redirect the output to file, and then open and read that file and assign
>> its
>> contents to your textbox.  To my knowledge, that's about the only thing
>> you
>> can do.
>
> There's another option, but it's a real stretch whether to recommend it to
> a guy who isn't altogether up on Shell.  Here's the rough outline, with
> attribution in the comments...
>
>   Private Function ExecAndCapture(ByVal CmdLine As String, Optional ByVal
> StartFolder As String = vbNullString) As String
>      ' http://www.vb-helper.com/howto_capture_console_stdout.html
>      Dim hPipeRead As Long
>      Dim hPipeWrite As Long
>      Dim sa As SECURITY_ATTRIBUTES
>      Dim si As STARTUPINFO
>      Dim pi As PROCESS_INFORMATION
>      Dim Buffer() As Byte
>      Dim StdOut As New CStringBuilder
>      Dim lBytesRead As Long
>      Dim ExitCode As Long
>      Const BUFSIZE As Long = 1024 * 10
>
>      With sa
>         .nLength = Len(sa)
>         .bInheritHandle = 1    ' get inheritable pipe handles
>      End With 'SA
>
>      If CreatePipe(hPipeRead, hPipeWrite, sa, 0) = 0 Then
>         Exit Function
>      End If
>
>      With si
>         .cb = Len(si)
>         .dwFlags = STARTF_USESHOWWINDOW Or STARTF_USESTDHANDLES
>         .wShowWindow = SW_HIDE
>         .hStdOutput = hPipeWrite
>         .hStdError = hPipeWrite
>      End With 'SI
>
>      If CreateProcess(vbNullString, CmdLine, ByVal 0&, ByVal 0&, 1, 0&,
> ByVal 0&, StartFolder, si, pi) Then
>         Call CloseHandle(hPipeWrite)
>         Call CloseHandle(pi.hThread)
>
>         ReDim Buffer(0 To BUFSIZE - 1) As Byte
>         Do
>            DoEvents
>            If ReadFile(hPipeRead, Buffer(0), UBound(Buffer) + 1,
> lBytesRead, ByVal 0&) = 0 Then
>               Exit Do
>            End If
>            Debug.Print Replace$(Left$(StrConv(Buffer, vbUnicode),
> lBytesRead), vbCr & vbCrLf, vbCrLf);
>            StdOut.Append Replace$(Left$(StrConv(Buffer, vbUnicode),
> lBytesRead), vbCr & vbCrLf, vbCrLf)
>         Loop
>         Call CloseHandle(pi.hProcess)
>      End If
>
>      ' To make sure...
>      Call CloseHandle(hPipeRead)
>      Call CloseHandle(hPipeWrite)
>
>      ' Return results.
>      ExecAndCapture = StdOut.ToString
>   End Function
>
> It works.
> --
> .NET: It's About Trust!
> http://vfred.mvps.org
>
Author
10 May 2007 8:36 PM
Karl E. Peterson
Patrick Matthews <pmatth***@chw.org> wrote:
> Thanks for the recommendation, but "a real stretch" is an understatement.

I'm glad you didn't take that the wrong way.  :-)

> used to do some VB programming back in the days of VB4 & 5 and I do a fair
> amount of VB scripting now. So by NO means am I any kind of programmer. I'm
> just trying to get something accomplished and VB script won't cut it. So...
> on a whim I thought I would try it in straight VB. Things are coming back to
> me but i have to ask the stupid questions to jog my memory. Thanks for the
> help

Yeah, Mike's method is probably preferable if it'll suit your needs.  This one's
really going nukyoulair.  Have fun!
--
..NET: It's About Trust!
http://vfred.mvps.org