VB.NET прогрессбар на основе вывода cmd - PullRequest
0 голосов
/ 20 мая 2018

В настоящее время я использую приложение на vb.net, используя VS2017.Одной из функций приложения является кнопка, которую пользователи нажимают, выбирают папку установки, и файлы для игрового сервера начинают загружаться.

Приложение загружает файлы игрового сервера через SteamCMD.Это как Windows CMD.SteamCMD запускается в фоновом режиме при запуске.В приложении есть текстовое поле, в котором пользователи смогут видеть вывод SteamCMD.

Я добавил индикатор прогресса в приложение.Чтобы оживить его, мне нужно получить несколько конкретных чисел из каждой строки вывода SteamCMD.

С помощью следующей функции я запускаю SteamCMD:

Private Sub StartSteamCMD()
        psi = New ProcessStartInfo("cmd.exe", "/C steamcmd +runscript " + temp + "my_app\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, .EnableRaisingEvents = True}
        AddHandler process.OutputDataReceived, AddressOf Async_Data_Received
        AddHandler process.ErrorDataReceived, AddressOf Async_Data_Received
        AddHandler process.Exited, AddressOf Process_Exited
        process.Start()
        process.BeginOutputReadLine()
        process.BeginErrorReadLine()
        process.Close()
    End Sub

И с двумя следующими функциями:перенести вывод SteamCMD в текстовое поле:

Private Sub Async_Data_Received(sender As Object, e As DataReceivedEventArgs)
    Invoke(New InvokeWithString(AddressOf Sync_Output), e.Data)
End Sub

Private Sub Sync_Output(text As String)
    TextBox1.AppendText(text + Environment.NewLine)
    TextBox1.ScrollToCaret()
End Sub

Пока SteamCMD загружает файлы, вывод выглядит следующим образом:

Update state (0x61) downloading, progress: 0.07 (12054911 / 16483164234)

Два числа, которые нужны индикатору выполнения, - это последние два.Самый последний - это общий размер файла, который будет загружен.Хотя 12054911 - это размер файла, который уже загружен и изменяется в каждой новой строке.

С помощью следующего кода приложение должно получать эти два числа из каждой новой строки и анимировать индикатор выполнения:

Try
    If (Not String.IsNullOrEmpty(e.Data)) And (e.Data.Contains("downloading")) Then
        Dim initialLine As String() = e.Data.Split(New String() {"(", " / ", ")"}, StringSplitOptions.RemoveEmptyEntries)
        If initialLine.Contains(" / ") Then
            Dim targetSize As String = initialLine(4)
            Dim targetSizeInt As Integer = 0
            Integer.TryParse(targetSize, targetSizeInt)
            Dim currentSize As String = initialLine(3)
            Dim currentSizeInt As Integer = 0
            Integer.TryParse(currentSize, currentSizeInt)
            ProgressBar1.Maximum = targetSizeInt
            ProgressBar1.Value = currentSizeInt
        End If
    End If
Catch ex As Exception
    MessageBox.Show(ex.Message)
End Try

.: ОБНОВЛЕНО:.

Я поместил приведенный выше код в функцию «Async_Data_Received» под функцией «Invoke»."Debug.Print (ex.ToString ())" ничего не возвращал.Я заменил его на «MessageBox.Show (ex.Message)» и получил следующее (переведено с греческого на английский):

Значение «252043» не является допустимым значением для «Значение»,«Значение» должно быть между «минимальным» и «максимальным».Имя параметра: Значение

Я прокомментировал строку «ProgressBar1.Value = currentSizeInt» и добавил «MsgBox (ProgressBar1.Maximum)» в строке «ProgressBar1.Maximum = targetSizeInt».По какой-то причине MsgBox продолжал давать мне «0» снова и снова.

Я изменил строки «Dim targetSizeInt As Integer = 0» и «Integer.TryParse (targetSize, targetSizeInt)» на «Dim targetSizeInt As Integer»= Convert.ToInt32 (targetSize) ".В качестве исключения я получил следующее:

Значение было слишком большим или слишком маленьким для Int32.

В этом случае хорошим шагом было бы изменить "Dim targetSizeInt As Integer = Convert.ToInt32 (targetSize) "строка в" Dim targetSizeInt As Long = Convert.ToInt64 (targetSize) ".Но это не решило бы проблему, потому что свойство «Maximum» индикатора выполнения - Int32.

В результате я добавил «targetSize = targetSize.Substring (0, 10)» в «Dim targetSize As String».= initialLine (4) ".Что касается currentSize, сначала я должен был получить его длину.Затем проверьте, если его длина> 1, и, если это так, выполните «currentSize = currentSize.Substring (0, currentLength - 1)».

Таким образом, количество символов, которое будет иметь currentSize и targetSize, всегда будетнаходиться в диапазоне целочисленных значений.Я также переключился на метод Integer.TryParse, так как считаю, что он лучше, безопаснее и надежнее.

Я добавил всю эту информацию, чтобы помочь другим, у кого может быть похожая проблема.Со всей этой информацией, я думаю, они поймут каждый шаг, который я предпринял, пока не получу окончательный рабочий код, а именно:

Try
    If (Not String.IsNullOrEmpty(text)) And (text.Contains("downloading")) Then
        Dim initialLine As String() = text.Split(New String() {"(", " / ", ")"}, StringSplitOptions.RemoveEmptyEntries)
        Dim targetSize As String = initialLine(4)
        targetSize = targetSize.Substring(0, 10)
        Dim targetSizeInt As Integer = 0
        Integer.TryParse(targetSize, targetSizeInt)
        ProgressBar1.Maximum = targetSizeInt
        Dim currentSize As String = initialLine(3)
        Dim currentLength As Integer = currentSize.Length
        If currentLength > 1 Then
            currentSize = currentSize.Substring(0, currentLength - 1)
            Dim currentSizeInt As Integer = 0
            Integer.TryParse(currentSize, currentSizeInt)
            ProgressBar1.Value = currentSizeInt
        End If
    End If
Catch ex As Exception
    MessageBox.Show(ex.Message)
End Try
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...