0

I have made an application in vb.net which launches a cmd like process in the background, reads its output asynchronously and redirects it in a textbox. Normally my application should show every new output line in the textbox in real time. Unfortunately here is what happens:

These are the first output lines which are shown in the textbox. screenshot 1

After a few seconds an unwanted pause occurs for some reason. No new lines are shown in the textbox even though there is output from the process. After a few minutes all that output i couldn't see because of the pause, shows up and then a pause occurs again. screenshot 2

Finally, the last bunch of lines show up and the process is terminated. screenshot 3

Here is my code:

Private Sub StartSteamCMD()
    Try
        Dim psi As ProcessStartInfo = New ProcessStartInfo("cmd.exe", "/C steamcmd +runscript " + temp + "Setti_SRCDS_Manager\install_update.txt")
        With psi
            .UseShellExecute = False
            .RedirectStandardInput = True
            .RedirectStandardOutput = True
            .RedirectStandardError = True
            .CreateNoWindow = True
            .StandardOutputEncoding = Encoding.GetEncoding(CultureInfo.CurrentUICulture.TextInfo.OEMCodePage)
            .StandardErrorEncoding = Encoding.GetEncoding(CultureInfo.CurrentUICulture.TextInfo.OEMCodePage)
        End With
        process = New Process With {.StartInfo = psi}
        AddHandler process.OutputDataReceived, AddressOf Async_Data_Received
        AddHandler process.ErrorDataReceived, AddressOf Async_Data_Received
        process.Start()
        process.BeginOutputReadLine()
        process.BeginErrorReadLine()
    Catch ex As Exception
        MessageBox.Show(ex.Message)
    End Try
End Sub


Private Sub Async_Data_Received(sender As Object, e As DataReceivedEventArgs)
    Try
        Invoke(New InvokeWithString(AddressOf Sync_Output), e.Data)
    Catch ex As Exception
        MessageBox.Show(ex.Message)
    End Try
End Sub


Private Sub Sync_Output(text As String)
    Try
        TextBox1.AppendText(text + Environment.NewLine)
        TextBox1.ScrollToCaret()
        If Not String.IsNullOrEmpty(text) Then
            If text.Contains("downloading") Or text.Contains("validating") Then
                <code to animate the progress bar here>
            ElseIf text.Contains("Success") Then
                <the server is installed successfully, some code to run here>
            ElseIf text.IndexOf("error", 0, StringComparison.CurrentCultureIgnoreCase) > -1 Then
                <some code to run in case of error>
            End If
        End If
    Catch ex As Exception
        MessageBox.Show(ex.Message)
    End Try
End Sub

Any thoughts of what can cause those pauses? I have been thinking the following. As you can see in the first screenshot, the last two lines are about establishing a connection with Steam servers (the place where the game server files will be downloaded from) and waiting for user info. Maybe that moment the process doesn't produce any output for a few seconds. So at some point during those seconds, the first pause of async reading occurs. Then the process starts producing output again but it's not redirected to the textbox because of the pause. Could it be the async reading gets paused because of the process not producing any output for a few seconds?

I don't know what else to think. I'm tired of searching the internet for a solution, because i can't find any post about my problem or at least something similar. I hope you guys can help me out. Thanks in advance

JayV
  • 3,238
  • 2
  • 9
  • 14
MsNs7
  • 9
  • 3
  • I'm not familiar with the program you're executing, I don't know how it operates. Some considerations: does it need `cmd.exe` to work? Have you tried launching it without it? Try to set the Process' [SynchronizingObject](https://learn.microsoft.com/en-us/dotnet/api/system.diagnostics.process.synchronizingobject) to the Form/Window instance (e.g. `process.SynchronizingObject = Me`) and eliminate the `Invoke()` part (I don't know what delegate you're using there) so you can call `Sync_Output()` directly – Jimi Dec 07 '19 at 21:05
  • Also, try testing it with this code: [How do I get output from a command to appear in a control on a Form in real-time?](https://stackoverflow.com/a/51682585/7444103) – Jimi Dec 07 '19 at 21:06
  • @Jimi Yes, it needs cmd.exe to work based on its documentation as you can see here: https://developer.valvesoftware.com/wiki/SteamCMD#Windows_2 – MsNs7 Dec 08 '19 at 10:43
  • @Jimi Then i edited my code so to use "SynchronizingObject = Me" as you suggested me. I can see information in the textbox but unfortunatelly it didn't solve the issue. What still happens is the textbox shows some info and pauses > unpauses, shows a bunch of info and pauses again > unpauses, shows the last bunch of info and the process is terminated. Later today i will try the "Also, try testing it with this code" part you recommended me. I will let you know the results. – MsNs7 Dec 08 '19 at 10:54
  • Try to run it without `cmd.exe`, which is used to show the program's command prompt. You're executing a command already, you may receive the output directly. But, I cannot test it, so... – Jimi Dec 08 '19 at 11:14
  • @Jimi I changed the ProcessStartInfo part to `ProcessStartInfo("steamcmd.exe", "+runscript " + temp + "Setti_SRCDS_Manager\install_update.txt")`. SteamCMD runs without `cmd.exe` and does its job but the pausing issue remains. I will keep the updated ProcessStartInfo. – MsNs7 Dec 09 '19 at 17:59

0 Answers0