Results 1 to 21 of 21

Thread: Running a DOS command, and show output in textbox, realtime?

  1. #1

    Thread Starter
    Lively Member
    Join Date
    May 2010
    Posts
    93

    Running a DOS command, and show output in textbox, realtime?

    I want to run some dos commands (eg: a ROBOCOPY) and show the output from this realtime in a text window to show the user something is happening...

    The command may take a number of minutes so it's important the output is showing in the VB application realtime, and not just all at the end. Obviously the user will wonder what is happening during this time.

    Is there an easy way to achieve this?

    ps: I've only been using Visual Basic 2010 for a couple of weeks, so go easy on me please

  2. #2
    Wait... what? weirddemon's Avatar
    Join Date
    Jan 2009
    Location
    USA
    Posts
    3,826

    Re: Running a DOS command, and show output in textbox, realtime?

    There's a code example to do exactly this, in the CodeBank
    CodeBank contributions: Process Manager, Temp File Cleaner

    Quote Originally Posted by SJWhiteley
    "game trainer" is the same as calling the act of robbing a bank "wealth redistribution"....

  3. #3

    Thread Starter
    Lively Member
    Join Date
    May 2010
    Posts
    93

    Re: Running a DOS command, and show output in textbox, realtime?

    Quote Originally Posted by weirddemon View Post
    There's a code example to do exactly this, in the CodeBank
    Any chance of a link?

    If this example - http://www.vbforums.com/showthread.p...&highlight=dos

    Then that's the sort of thing I've tried so far, but only updates the text in the VB application once the dos command has completed, not during the running of the dos command.

  4. #4
    Frenzied Member
    Join Date
    May 2003
    Location
    So Cal
    Posts
    1,564

    Re: Running a DOS command, and show output in textbox, realtime?

    What about piping the output to a text file then reading it every so often?

  5. #5
    King of sapila
    Join Date
    Oct 2006
    Location
    Greece
    Posts
    6,763

    Re: Running a DOS command, and show output in textbox, realtime?

    Are you saying that your dos command will do something like:
    running....
    Info on screen
    running
    Info on screen
    Something like this?
    I don't know if you can step withing the execution of an exe file.Maybe getting a pointer on some address of exe but it's gonna get messy.
    ἄνδρα μοι ἔννεπε, μοῦσα, πολύτροπον, ὃς μάλα πολλὰ
    πλάγχθη, ἐπεὶ Τροίης ἱερὸν πτολίεθρον ἔπερσεν·

  6. #6

    Thread Starter
    Lively Member
    Join Date
    May 2010
    Posts
    93

    Re: Running a DOS command, and show output in textbox, realtime?

    Quote Originally Posted by BrianS View Post
    What about piping the output to a text file then reading it every so often?
    That sounds like a possibility. So the only hurdles there are:-
    1) Kicking the DOS command off and not just waiting for it to finish, but instead entering a loop in VB, say polling every 5 seconds, until it finishes.
    2) In the loop picking up the txt output (every 5 seconds) and displaying it in a text box.


    (2) Sound easy (even for me)
    (1) I believe the VB function I have to initiate the DOS command says whether to wait for it to finish or not, but I'm not sure how I'd monitor if it's still in existance or not (ie: has it finished)? - ie: Do I stay in my polling loop or not?

    Additionally, if I want to 'abort' the run, the command I'd need to terminate the DOS process!?


    Thanks for the help guys!

  7. #7

    Thread Starter
    Lively Member
    Join Date
    May 2010
    Posts
    93

    Re: Running a DOS command, and show output in textbox, realtime?

    Quote Originally Posted by sapator View Post
    Are you saying that your dos command will do something like:
    running....
    Info on screen
    running
    Info on screen
    Something like this?
    I don't know if you can step withing the execution of an exe file.Maybe getting a pointer on some address of exe but it's gonna get messy.
    Yes, think of a massive ROBOCOPY taking place copying thousands of files. This would put out a line for each file copied... So all I want to do is show this output in the controlling VB application so the user knows something is happening and it's not just hung...

  8. #8
    PowerPoster cicatrix's Avatar
    Join Date
    Dec 2009
    Location
    Moscow, Russia
    Posts
    3,654

    Re: Running a DOS command, and show output in textbox, realtime?

    This is a sample wrapper around cmd.exe that demonstrates how to capture standard output in realtime.


    vb Code:
    1. Imports System.Diagnostics
    2.  
    3. Public Class frmConsoleDemo
    4.  
    5.     Friend WithEvents txtConsoleOut As System.Windows.Forms.TextBox
    6.     Friend WithEvents txtConsoleIn As System.Windows.Forms.TextBox
    7.  
    8.     Private psi As ProcessStartInfo
    9.     Private cmd As Process
    10.     Private Delegate Sub InvokeWithString(ByVal text As String)
    11.  
    12.     Private Sub frmConsoleDemo_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    13.  
    14.         psi = New ProcessStartInfo("cmd.exe")
    15.  
    16.         Dim systemencoding As System.Text.Encoding = _
    17.             System.Text.Encoding.GetEncoding(Globalization.CultureInfo.CurrentUICulture.TextInfo.OEMCodePage)
    18.  
    19.         With psi
    20.             .UseShellExecute = False  ' Required for redirection
    21.             .RedirectStandardError = True
    22.             .RedirectStandardOutput = True
    23.             .RedirectStandardInput = True
    24.             .CreateNoWindow = True
    25.             .StandardOutputEncoding = systemencoding  ' Use OEM encoding for console applications
    26.             .StandardErrorEncoding = systemencoding
    27.         End With
    28.  
    29.         ' EnableraisingEvents is required for Exited event
    30.         cmd = New Process With {.StartInfo = psi, .EnableRaisingEvents = True}
    31.  
    32.         AddHandler cmd.ErrorDataReceived, AddressOf Async_Data_Received
    33.         AddHandler cmd.OutputDataReceived, AddressOf Async_Data_Received
    34.         AddHandler cmd.Exited, AddressOf CMD_Exited
    35.  
    36.         cmd.Start()
    37.         ' Start async reading of the redirected streams
    38.         ' Without these calls the events won't fire
    39.         cmd.BeginOutputReadLine()
    40.         cmd.BeginErrorReadLine()
    41.  
    42.         Me.txtConsoleIn.Select()
    43.     End Sub
    44.  
    45.     Private Sub CMD_Exited(ByVal sender As Object, ByVal e As EventArgs)
    46.         Me.Close()
    47.     End Sub
    48.  
    49.     ' This sub gets called in a different thread so invokation is required
    50.     Private Sub Async_Data_Received(ByVal sender As Object, ByVal e As DataReceivedEventArgs)
    51.         Me.Invoke(New InvokeWithString(AddressOf Sync_Output), e.Data)
    52.     End Sub
    53.  
    54.     Private Sub Sync_Output(ByVal text As String)
    55.         txtConsoleOut.AppendText(text & Environment.NewLine)
    56.         txtConsoleOut.ScrollToCaret()
    57.     End Sub
    58.  
    59.     ' Sending console commands here
    60.     Private Sub txtConsoleIn_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles txtConsoleIn.KeyPress
    61.         If e.KeyChar = ControlChars.Cr Then
    62.             cmd.StandardInput.WriteLine(txtConsoleIn.Text)
    63.             txtConsoleIn.Clear()
    64.         End If
    65.     End Sub
    66.  
    67.     ' Two text boxes called txtConsoleOut and txtConsoleIn
    68.     Public Sub New()
    69.         Me.txtConsoleOut = New System.Windows.Forms.TextBox()
    70.         Me.txtConsoleIn = New System.Windows.Forms.TextBox()
    71.         Me.SuspendLayout()
    72.         '
    73.         'txtConsoleOut
    74.         '
    75.         Me.txtConsoleOut.Anchor = CType((((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _
    76.                     Or System.Windows.Forms.AnchorStyles.Left) _
    77.                     Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
    78.         Me.txtConsoleOut.Location = New System.Drawing.Point(12, 12)
    79.         Me.txtConsoleOut.Multiline = True
    80.         Me.txtConsoleOut.Name = "txtConsoleOut"
    81.         Me.txtConsoleOut.ReadOnly = True
    82.         Me.txtConsoleOut.ScrollBars = System.Windows.Forms.ScrollBars.Both
    83.         Me.txtConsoleOut.Size = New System.Drawing.Size(665, 494)
    84.         Me.txtConsoleOut.TabIndex = 0
    85.         '
    86.         'txtConsoleIn
    87.         '
    88.         Me.txtConsoleIn.Anchor = CType(((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left) _
    89.                     Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
    90.         Me.txtConsoleIn.Location = New System.Drawing.Point(10, 512)
    91.         Me.txtConsoleIn.Name = "txtConsoleIn"
    92.         Me.txtConsoleIn.Size = New System.Drawing.Size(667, 20)
    93.         Me.txtConsoleIn.TabIndex = 1
    94.         '
    95.         'frmConsoleDemo
    96.         '
    97.         Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
    98.         Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
    99.         Me.ClientSize = New System.Drawing.Size(689, 544)
    100.         Me.Controls.Add(Me.txtConsoleIn)
    101.         Me.Controls.Add(Me.txtConsoleOut)
    102.         Me.Name = "frmConsoleDemo"
    103.         Me.Text = "Console redirect demo"
    104.         Me.ResumeLayout(False)
    105.         Me.PerformLayout()
    106.  
    107.     End Sub
    108.  
    109. End Class

  9. #9

    Thread Starter
    Lively Member
    Join Date
    May 2010
    Posts
    93

    Re: Running a DOS command, and show output in textbox, realtime?

    Quote Originally Posted by cicatrix View Post
    This is a sample wrapper around cmd.exe that demonstrates how to capture standard output in realtime.


    vb Code:
    1. Imports System.Diagnostics
    2.  
    3. Public Class frmConsoleDemo
    4.  
    5.     Friend WithEvents txtConsoleOut As System.Windows.Forms.TextBox
    6.     Friend WithEvents txtConsoleIn As System.Windows.Forms.TextBox
    7.  
    8.     Private psi As ProcessStartInfo
    9.     Private cmd As Process
    10.     Private Delegate Sub InvokeWithString(ByVal text As String)
    11.  
    12.     Private Sub frmConsoleDemo_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    13.  
    14.         psi = New ProcessStartInfo("cmd.exe")
    15.  
    16.         Dim systemencoding As System.Text.Encoding = _
    17.             System.Text.Encoding.GetEncoding(Globalization.CultureInfo.CurrentUICulture.TextInfo.OEMCodePage)
    18.  
    19.         With psi
    20.             .UseShellExecute = False  ' Required for redirection
    21.             .RedirectStandardError = True
    22.             .RedirectStandardOutput = True
    23.             .RedirectStandardInput = True
    24.             .CreateNoWindow = True
    25.             .StandardOutputEncoding = systemencoding  ' Use OEM encoding for console applications
    26.             .StandardErrorEncoding = systemencoding
    27.         End With
    28.  
    29.         ' EnableraisingEvents is required for Exited event
    30.         cmd = New Process With {.StartInfo = psi, .EnableRaisingEvents = True}
    31.  
    32.         AddHandler cmd.ErrorDataReceived, AddressOf Async_Data_Received
    33.         AddHandler cmd.OutputDataReceived, AddressOf Async_Data_Received
    34.         AddHandler cmd.Exited, AddressOf CMD_Exited
    35.  
    36.         cmd.Start()
    37.         ' Start async reading of the redirected streams
    38.         ' Without these calls the events won't fire
    39.         cmd.BeginOutputReadLine()
    40.         cmd.BeginErrorReadLine()
    41.  
    42.         Me.txtConsoleIn.Select()
    43.     End Sub
    44.  
    45.     Private Sub CMD_Exited(ByVal sender As Object, ByVal e As EventArgs)
    46.         Me.Close()
    47.     End Sub
    48.  
    49.     ' This sub gets called in a different thread so invokation is required
    50.     Private Sub Async_Data_Received(ByVal sender As Object, ByVal e As DataReceivedEventArgs)
    51.         Me.Invoke(New InvokeWithString(AddressOf Sync_Output), e.Data)
    52.     End Sub
    53.  
    54.     Private Sub Sync_Output(ByVal text As String)
    55.         txtConsoleOut.AppendText(text & Environment.NewLine)
    56.         txtConsoleOut.ScrollToCaret()
    57.     End Sub
    58.  
    59.     ' Sending console commands here
    60.     Private Sub txtConsoleIn_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles txtConsoleIn.KeyPress
    61.         If e.KeyChar = ControlChars.Cr Then
    62.             cmd.StandardInput.WriteLine(txtConsoleIn.Text)
    63.             txtConsoleIn.Clear()
    64.         End If
    65.     End Sub
    66.  
    67.     ' Two text boxes called txtConsoleOut and txtConsoleIn
    68.     Public Sub New()
    69.         Me.txtConsoleOut = New System.Windows.Forms.TextBox()
    70.         Me.txtConsoleIn = New System.Windows.Forms.TextBox()
    71.         Me.SuspendLayout()
    72.         '
    73.         'txtConsoleOut
    74.         '
    75.         Me.txtConsoleOut.Anchor = CType((((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _
    76.                     Or System.Windows.Forms.AnchorStyles.Left) _
    77.                     Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
    78.         Me.txtConsoleOut.Location = New System.Drawing.Point(12, 12)
    79.         Me.txtConsoleOut.Multiline = True
    80.         Me.txtConsoleOut.Name = "txtConsoleOut"
    81.         Me.txtConsoleOut.ReadOnly = True
    82.         Me.txtConsoleOut.ScrollBars = System.Windows.Forms.ScrollBars.Both
    83.         Me.txtConsoleOut.Size = New System.Drawing.Size(665, 494)
    84.         Me.txtConsoleOut.TabIndex = 0
    85.         '
    86.         'txtConsoleIn
    87.         '
    88.         Me.txtConsoleIn.Anchor = CType(((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left) _
    89.                     Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
    90.         Me.txtConsoleIn.Location = New System.Drawing.Point(10, 512)
    91.         Me.txtConsoleIn.Name = "txtConsoleIn"
    92.         Me.txtConsoleIn.Size = New System.Drawing.Size(667, 20)
    93.         Me.txtConsoleIn.TabIndex = 1
    94.         '
    95.         'frmConsoleDemo
    96.         '
    97.         Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
    98.         Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
    99.         Me.ClientSize = New System.Drawing.Size(689, 544)
    100.         Me.Controls.Add(Me.txtConsoleIn)
    101.         Me.Controls.Add(Me.txtConsoleOut)
    102.         Me.Name = "frmConsoleDemo"
    103.         Me.Text = "Console redirect demo"
    104.         Me.ResumeLayout(False)
    105.         Me.PerformLayout()
    106.  
    107.     End Sub
    108.  
    109. End Class
    I'm afraid although that works, my knowlegde of VB makes it seemingly impossible to take the code out that I need

    If I paint my form with two big text boxes txtConsoleIn and txtConsoleOut, then the form shown at runtime doesn't resemble that at all and has been completely redrawn

    I've tried playing around with that final Sub New, but can't seem to get the form to work then and get errors


    If it just did a "tracert www.bbc.co.uk" for example (no need for txtConsoleIn), out to txtConsoleOut, that would be a perfect example. Obviously without having to redraw my entire form to do so...

  10. #10
    PowerPoster cicatrix's Avatar
    Join Date
    Dec 2009
    Location
    Moscow, Russia
    Posts
    3,654

    Re: Running a DOS command, and show output in textbox, realtime?

    Actually you don't need to redraw your form.
    The txtConsoleIn and txtConsoleOut textboxes are just for example.
    If you need only to display the output of a command you a) don't need txtConsoleIn at all and b) this example shows how to receive data from the command's standard output stream (see Async_Data_Received sub). This sub is invoked each time the command sends something to its standard output stream (and e.Data will hold the string it 'displayed'). Having received this event you simply use this text as you see fit (it's in another thread so you should invoke a sub in the UI thread to manipulate your controls - that's why you need to invoke Sync_Output sub and pass the output text to it). In the Sync_Output sub you simply display the received text in the textbox while you can do something different.

    Here's how it works.

    1. I start a process and assign an EventHandler for its OutputDataReceived event so each time this command sends something to its' StdOut your programm will be notified.
    2. If something is received the Async_Data_Received handler is invoked.
    3. It invokes a syncronous with the UI Sync_Output and passes the data it has just received to it.
    4. In the Sync_Output you can do whatever you want with the text - display it, parse it, etc.
    5. To exit this particular app you need to type Exit but if you run some other command it will exit as soon as the execution finishes.

    You need to change "cmd.exe" to "tracert" and pass "www.bbc.co.uk" as its argument and then remove all code for txtConsoleIn, that's all.

  11. #11

    Thread Starter
    Lively Member
    Join Date
    May 2010
    Posts
    93

    Re: Running a DOS command, and show output in textbox, realtime?

    Quote Originally Posted by cicatrix View Post
    Actually you don't need to redraw your form.
    The txtConsoleIn and txtConsoleOut textboxes are just for example.
    If you need only to display the output of a command you a) don't need txtConsoleIn at all and b) this example shows how to receive data from the command's standard output stream (see Async_Data_Received sub). This sub is invoked each time the command sends something to its standard output stream (and e.Data will hold the string it 'displayed'). Having received this event you simply use this text as you see fit (it's in another thread so you should invoke a sub in the UI thread to manipulate your controls - that's why you need to invoke Sync_Output sub and pass the output text to it). In the Sync_Output sub you simply display the received text in the textbox while you can do something different.

    Here's how it works.

    1. I start a process and assign an EventHandler for its OutputDataReceived event so each time this command sends something to its' StdOut your programm will be notified.
    2. If something is received the Async_Data_Received handler is invoked.
    3. It invokes a syncronous with the UI Sync_Output and passes the data it has just received to it.
    4. In the Sync_Output you can do whatever you want with the text - display it, parse it, etc.
    5. To exit this particular app you need to type Exit but if you run some other command it will exit as soon as the execution finishes.

    You need to change "cmd.exe" to "tracert" and pass "www.bbc.co.uk" as its argument and then remove all code for txtConsoleIn, that's all.
    I understand the principle, but just cannot get the code to work - I've just spent an hour and half kicking the code around, and got no where.

    I literally just want to be able to specify a command. eg: "tracert www.bbc.co.uk" or a ROBOCOPY, for example, and then catch the output, and add it to a text box to show

  12. #12
    PowerPoster cicatrix's Avatar
    Join Date
    Dec 2009
    Location
    Moscow, Russia
    Posts
    3,654

    Re: Running a DOS command, and show output in textbox, realtime?

    In my example change

    Code:
    psi = New ProcessStartInfo("cmd.exe")
    to
    Code:
    Dim psi As New ProcessStartInfo("tracert", "www.bbc.co.uk")

  13. #13

    Thread Starter
    Lively Member
    Join Date
    May 2010
    Posts
    93

    Re: Running a DOS command, and show output in textbox, realtime?

    OK... Making some headway at last!

    This is now working! I can paint my form, just with a text box (txtConsoleOut) and a button (btnRun).

    The thing I can now not work out is:-
    - While the command is running, how do I prevent the form being used? ie: I don't want them to be able to click the button again, while the last/previous process is still running obviously!
    - CMD_Exited is not getting run? This is something to do with me changing EnableRaisingEvents to False. If it was set to True then the form would exit at the end of the process for some odd reason!?
    - Is the process I start actually closing afterwards? ie: I'm not leaving orphaned things around?

    ps: Thanks for your help...
    Code:
    Imports System.Diagnostics
    
    Public Class frmConsoleDemo
        Private psi As ProcessStartInfo
        Private cmd As Process
    
        Private Delegate Sub InvokeWithString(ByVal text As String)
        Private Sub frmConsoleDemo_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    
        End Sub
        Private Sub CMD_Exited(ByVal sender As Object, ByVal e As EventArgs)
            'Me.Close()
            txtConsoleOut.AppendText(Text & "All done!!!")
            txtConsoleOut.ScrollToCaret()
        End Sub
        ' This sub gets called in a different thread so invokation is required
        Private Sub Async_Data_Received(ByVal sender As Object, ByVal e As DataReceivedEventArgs)
            Me.Invoke(New InvokeWithString(AddressOf Sync_Output), e.Data)
        End Sub
        Private Sub Sync_Output(ByVal text As String)
            txtConsoleOut.AppendText(text & Environment.NewLine)
            txtConsoleOut.ScrollToCaret()
        End Sub
    
        Private Sub btnRun_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRun.Click
            psi = New ProcessStartInfo("robocopy", "d:\foldera d:\folderb /MIR /NP")
    
            Dim systemencoding As System.Text.Encoding = _
                System.Text.Encoding.GetEncoding(Globalization.CultureInfo.CurrentUICulture.TextInfo.OEMCodePage)
            With psi
                .UseShellExecute = False  ' Required for redirection
                .RedirectStandardError = True
                .RedirectStandardOutput = True
                .RedirectStandardInput = True
                .CreateNoWindow = True
                .StandardOutputEncoding = systemencoding  ' Use OEM encoding for console applications
                .StandardErrorEncoding = systemencoding
            End With
            ' EnableraisingEvents is required for Exited event
            cmd = New Process With {.StartInfo = psi, .EnableRaisingEvents = False}
            AddHandler cmd.ErrorDataReceived, AddressOf Async_Data_Received
            AddHandler cmd.OutputDataReceived, AddressOf Async_Data_Received
            AddHandler cmd.Exited, AddressOf CMD_Exited
    
            cmd.Start()
    
            ' Start async reading of the redirected streams
            ' Without these calls the events won't fire
            cmd.BeginOutputReadLine()
            cmd.BeginErrorReadLine()
        End Sub
    End Class
    Last edited by NeilF; May 27th, 2010 at 08:08 AM.

  14. #14
    PowerPoster cicatrix's Avatar
    Join Date
    Dec 2009
    Location
    Moscow, Russia
    Posts
    3,654

    Re: Running a DOS command, and show output in textbox, realtime?

    In the btnRun_click add this line:

    Code:
    btnRun.Enabled = False
    In order to correctly catch the Exited event Set EnableRaisingEvents back to true

    Code:
    Private Sub CMD_Exited(ByVal sender As Object, ByVal e As EventArgs)
            btnRun.Enabled = True ' < --- Add THis
            'Me.Close() <- This is what caused the form to close. If you leave this commented the form won't close
            txtConsoleOut.AppendText(Text & "All done!!!")
            txtConsoleOut.ScrollToCaret()
    End Sub

  15. #15

    Thread Starter
    Lively Member
    Join Date
    May 2010
    Posts
    93

    Re: Running a DOS command, and show output in textbox, realtime?

    Quote Originally Posted by cicatrix View Post
    In the btnRun_click add this line:

    Code:
    btnRun.Enabled = False
    In order to correctly catch the Exited event Set EnableRaisingEvents back to true

    Code:
    Private Sub CMD_Exited(ByVal sender As Object, ByVal e As EventArgs)
            btnRun.Enabled = True ' < --- Add THis
            'Me.Close() <- This is what caused the form to close. If you leave this commented the form won't close
            txtConsoleOut.AppendText(Text & "All done!!!")
            txtConsoleOut.ScrollToCaret()
    End Sub
    Sorry, that's not the case, strangely.

    That "Me.Close" WAS already commented out (infact I can even remove it). And with ".EnableRaisingEvents = True" the form closes, via the CMD_EXITED sub.

    With " .EnableRaisingEvents = False" the form remains open, but CMD_EXITED is not entered.

  16. #16
    PowerPoster cicatrix's Avatar
    Join Date
    Dec 2009
    Location
    Moscow, Russia
    Posts
    3,654

    Re: Running a DOS command, and show output in textbox, realtime?

    The form cannot close without any 'help'.
    Set .EnableRaisingEvents = True and put a breakpoint in the cmd_exited sub.
    Then step through your code to see which line makes it close.

  17. #17

    Thread Starter
    Lively Member
    Join Date
    May 2010
    Posts
    93

    Re: Running a DOS command, and show output in textbox, realtime?

    Quote Originally Posted by cicatrix View Post
    The form cannot close without any 'help'.
    Set .EnableRaisingEvents = True and put a breakpoint in the cmd_exited sub.
    Then step through your code to see which line makes it close.
    LOL!

    It's the code trying to set the text of txtConsoleOut causing VB to seemingly to bomb out! My CMD_EXITED reads:-
    Code:
        Private Sub CMD_Exited(ByVal sender As Object, ByVal e As EventArgs)
            txtConsoleOut.Text = "Done"
        End Sub
    And I can see the error popping up in the logs of "A first chance exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll"

    Very odd! Does something still own txtConsoleOut?


    If I take that line out of CMD_EXITED (so it does nothing), then all works fine, the form remains up, and I can press the button to run the script over and over...
    Last edited by NeilF; May 27th, 2010 at 01:05 PM.

  18. #18

    Thread Starter
    Lively Member
    Join Date
    May 2010
    Posts
    93

    Re: Running a DOS command, and show output in textbox, realtime?

    Any code to do with any of the forms properties causes the form to terminate/end...

    eg. Even this makes the form end...

    Code:
        Private Sub CMD_Exited(ByVal sender As Object, ByVal e As EventArgs)
            btnRun.Text = "Finished"
        End Sub
    Where as this means the form stays open, and I can press btnRun over and over:-
    Code:
        Private Sub CMD_Exited(ByVal sender As Object, ByVal e As EventArgs)
            Dim x As String
            x = "Finished"
        End Sub


    Here's the entire example (needs textbox txtConsoleout, and a button btnRun):-
    Code:
    Imports System.Diagnostics
    
    Public Class frmConsoleDemo
        Private psi As ProcessStartInfo
        Private cmd As Process
    
        Private Delegate Sub InvokeWithString(ByVal text As String)
        Private Sub frmConsoleDemo_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    
        End Sub
        Private Sub CMD_Exited(ByVal sender As Object, ByVal e As EventArgs)
            btnRun.Text = "Finished"
            'Dim x As String
            'x = "Finished"
        End Sub
        ' This sub gets called in a different thread so invokation is required
        Private Sub Async_Data_Received(ByVal sender As Object, ByVal e As DataReceivedEventArgs)
            Me.Invoke(New InvokeWithString(AddressOf Sync_Output), e.Data)
        End Sub
        Private Sub Sync_Output(ByVal text As String)
            txtConsoleOut.AppendText(text & Environment.NewLine)
            txtConsoleOut.ScrollToCaret()
        End Sub
    
        Private Sub btnRun_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRun.Click
            btnRun.Text = "Starting!!!"
            psi = New ProcessStartInfo("robocopy", "d:\foldera d:\folderb /MIR /NP")
    
            Dim systemencoding As System.Text.Encoding = _
                System.Text.Encoding.GetEncoding(Globalization.CultureInfo.CurrentUICulture.TextInfo.OEMCodePage)
            With psi
                .UseShellExecute = False  ' Required for redirection
                .RedirectStandardError = True
                .RedirectStandardOutput = True
                .RedirectStandardInput = True
                .CreateNoWindow = True
                .StandardOutputEncoding = systemencoding  ' Use OEM encoding for console applications
                .StandardErrorEncoding = systemencoding
            End With
            ' EnableraisingEvents is required for Exited event
            cmd = New Process With {.StartInfo = psi, .EnableRaisingEvents = True}
            AddHandler cmd.ErrorDataReceived, AddressOf Async_Data_Received
            AddHandler cmd.OutputDataReceived, AddressOf Async_Data_Received
            AddHandler cmd.Exited, AddressOf CMD_Exited
    
            cmd.Start()
    
            ' Start async reading of the redirected streams
            ' Without these calls the events won't fire
            cmd.BeginOutputReadLine()
            cmd.BeginErrorReadLine()
        End Sub
        'Option Explicit
        'Private  Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
    End Class
    This is doing my head in

  19. #19
    Pro Grammar chris128's Avatar
    Join Date
    Jun 2007
    Location
    England
    Posts
    7,604

    Re: Running a DOS command, and show output in textbox, realtime?

    Well from a quick glance at your code I'm guessing your CMD_Exited method is also being run from another thread so you need to handle it in the same way that you handle the Async_Data_Received method (i.e by using Invoke).
    My free .NET Windows API library (Version 2.2 Released 12/06/2011)

    Blog: cjwdev.wordpress.com
    Web: www.cjwdev.co.uk


  20. #20

    Thread Starter
    Lively Member
    Join Date
    May 2010
    Posts
    93

    Re: Running a DOS command, and show output in textbox, realtime?

    Quote Originally Posted by chris128 View Post
    Well from a quick glance at your code I'm guessing your CMD_Exited method is also being run from another thread so you need to handle it in the same way that you handle the Async_Data_Received method (i.e by using Invoke).
    That should tie up perfectly then with the solution to my other problem - http://www.vbforums.com/showthread.php?t=616434

  21. #21
    New Member
    Join Date
    Dec 2013
    Posts
    5

    Question Re: Running a DOS command, and show output in textbox, realtime?

    One question, I know this is an old thread..The code works, but what I need to do is keep the console reading..I am running a dedicated server for a video game, and the console for that reads out constantly (everything that happens in game is directed to this console) For some reason when I run the servers .exe file it does about 20 lines and then errors with "CTextConsoleWin32:Getline: !GetNumberOfConsoleInputEvents"..I want to be able to keep the thread open so I can send commands via my app. Basically I am creating a map selector app that you can choose what options you want then it will send all of that to the console, and keep the console open since it must be open for the game server to remain online. Example: (scdrs.exe -game -insurgency +map hijacked -diff 5 -yada -yada)..after this initial command the console could be written to via a textbox (Example: Changelevel Skirmish_v1 checkpoint). ... ANY help would be greatly appreciated!!
    Last edited by section.echo; Sep 2nd, 2016 at 08:32 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