You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VB.NET如何基于SteamCMD输出驱动ProgressBar并解决数值范围问题?

解决SteamCMD下载进度解析与ProgressBar更新问题

嘿,我来帮你搞定这个VB.NET里SteamCMD进度条的问题!先拆解下你遇到的三个问题的根源,再给你一套靠谱的解决方案:

问题到底出在哪?

  1. Value超出范围/Int32溢出:SteamCMD输出的总文件大小(比如你示例里的16483164234)远远超过了Int32的最大值(也就是2147483647),强行用Int32转换肯定会报错。
  2. ProgressBar.Maximum始终为0:你的字符串分割逻辑有问题——split之后的数组里已经没有" / "这个分隔符了,所以那个判断条件永远不成立,自然不会设置Maximum。另外,你对分割后数组的索引定位也不对。
  3. Convert.ToInt32报错:和第一个问题本质一样,数值太大,超出了Int32的取值范围。

最优解决方案:用百分比驱动ProgressBar

既然大文件大小会突破Int32的限制,咱们换个思路——直接计算下载进度的百分比,把ProgressBar的Maximum固定为100,用百分比数值作为Value,完美避开大整数的转换问题。

步骤1:修正进度解析逻辑

我帮你重写了解析代码,更稳定且能处理超大数值:

Private Sub Async_Data_Received(sender As Object, e As DataReceivedEventArgs)
    If Not String.IsNullOrEmpty(e.Data) Then
        ' 先把输出同步到TextBox
        Invoke(New InvokeWithString(AddressOf Sync_Output), e.Data)
        
        ' 解析下载进度
        Try
            Dim line = e.Data.Trim()
            ' 精准匹配SteamCMD的下载进度行
            If line.Contains("downloading") AndAlso line.Contains("progress:") AndAlso line.Contains(" / ") Then
                ' 提取括号里的大小部分:(当前大小 / 总大小)
                Dim sizeStartIndex = line.IndexOf("(", line.IndexOf("progress:")) + 1
                Dim sizeEndIndex = line.IndexOf(")", sizeStartIndex)
                
                If sizeStartIndex > 0 AndAlso sizeEndIndex > sizeStartIndex Then
                    Dim sizePair = line.Substring(sizeStartIndex, sizeEndIndex - sizeStartIndex)
                    Dim sizeParts = sizePair.Split(New String() {" / "}, StringSplitOptions.RemoveEmptyEntries)
                    
                    If sizeParts.Length = 2 Then
                        Dim currentSize As Int64
                        Dim totalSize As Int64
                        ' 用Int64处理超大数值,避免溢出
                        If Int64.TryParse(sizeParts(0), currentSize) AndAlso Int64.TryParse(sizeParts(1), totalSize) AndAlso totalSize > 0 Then
                            ' 计算百分比,取整后确保在0-100之间
                            Dim progressPercent = CInt(Math.Round((currentSize / totalSize) * 100))
                            progressPercent = Math.Max(0, Math.Min(100, progressPercent))
                            
                            ' 必须在UI线程更新控件,用Invoke包裹
                            Invoke(Sub()
                                       ProgressBar1.Maximum = 100
                                       ProgressBar1.Value = progressPercent
                                   End Sub)
                        End If
                    End If
                End If
            End If
        Catch ex As Exception
            Invoke(Sub() MessageBox.Show($"解析进度出错:{ex.Message}"))
        End Try
    End If
End Sub

步骤2:额外优化建议

  • 用正则表达式更稳定:如果SteamCMD的输出格式有小变动,字符串索引的方式可能失效,换成正则表达式匹配更可靠:
    ' 先在模块顶部导入正则命名空间
    ' Imports System.Text.RegularExpressions
    
    Dim progressRegex As New Regex("progress: \d+\.\d+ \((\d+) / (\d+)\)")
    Dim matchResult = progressRegex.Match(line)
    If matchResult.Success Then
        Dim currentSize = Int64.Parse(matchResult.Groups(1).Value)
        Dim totalSize = Int64.Parse(matchResult.Groups(2).Value)
        ' 计算百分比并更新进度条...
    End If
    
  • 避免重复设置Maximum:可以加个判断,比如只在第一次解析到总大小时设置一次ProgressBar1.Maximum = 100,不用每次都设置。

为什么不直接用文件大小设置进度条?

如果你坚持要直接用文件大小作为ProgressBar的最大值,得注意:.NET Framework里ProgressBar的Maximum和Value都是Int32类型,总大小超过2147483647时根本没法设置。这种情况下你得自定义支持Int64的ProgressBar控件,但完全没必要——用百分比的方案简单又可靠。

测试一下上面的代码,应该就能解决你所有的问题了!

内容的提问来源于stack exchange,提问作者MsNs7

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:15:28