В настоящее время я использую приложение на 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