记录一次纯AI写脚本
之前收集过一个脚本,使用powershell调用iperf来运行网络带宽的检查,后来就懂了信息,想要搞一个检查云桌面RTT延迟的工具,这样用户说云桌面卡的时候就能很清晰的看到网络的情况,之前见过一个类似的工具,叫Nping,查了一圈还是国内的一个程序员写的,在了解了基本原理就是使用icmp协议来执行ping命令后,收集返回信息,然后图形化以后我就想能不能用powershell写一个类似的工具。
自己二把刀写powershell的水平,大概率又要烂尾,所以就干脆直接问通译千问算了,结果还成了,所以记录一下。
需求提交
先整理了一下这个脚本的需求,和实现的逻辑
然后提交给AI
1 2 3 4 5 6 7 8 9 10 11
| #测试powershell版本
#检查powershell进程,如果有就先关掉,如果没有就进行执行
#创建进程
#执行命令,变量匹配UI的测试地址,变量匹配测试数量,变量匹配显示方式
#执行新打开窗口显示测试RTT效果,导出csvlog文件
#UI窗口,调用donet命令创建窗口,填写测试地址,勾选
|
然后收到了第一版本的脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
| Add-Type -AssemblyName System.Windows.Forms Add-Type -AssemblyName System.Drawing
# 创建窗体 $form = New-Object System.Windows.Forms.Form $form.Text = "PowerShell ICMP Ping 工具" $form.Size = New-Object System.Drawing.Size(600, 400) $form.StartPosition = 'CenterScreen'
# 输入地址 $labelTarget = New-Object System.Windows.Forms.Label $labelTarget.Location = New-Object System.Drawing.Point(20, 20) $labelTarget.Text = "请输入目标地址:" $form.Controls.Add($labelTarget)
$txtTarget = New-Object System.Windows.Forms.TextBox $txtTarget.Location = New-Object System.Drawing.Point(150, 20) $txtTarget.Size = New-Object System.Drawing.Size(300, 20) $form.Controls.Add($txtTarget)
# 测试次数 $labelCount = New-Object System.Windows.Forms.Label $labelCount.Location = New-Object System.Drawing.Point(20, 50) $labelCount.Text = "请选择测试次数:" $form.Controls.Add($labelCount)
$cboCount = New-Object System.Windows.Forms.ComboBox $cboCount.Location = New-Object System.Drawing.Point(150, 50) 1..10 | ForEach-Object { $cboCount.Items.Add($_) } | Out-Null $cboCount.SelectedItem = 3 $form.Controls.Add($cboCount)
# 开始按钮 $btnStart = New-Object System.Windows.Forms.Button $btnStart.Location = New-Object System.Drawing.Point(20, 80) $btnStart.Text = "开始测试" $form.Controls.Add($btnStart)
# 结果输出 RichTextBox $outputBox = New-Object System.Windows.Forms.RichTextBox $outputBox.Location = New-Object System.Drawing.Point(20, 120) $outputBox.Size = New-Object System.Drawing.Size(540, 200) $outputBox.ReadOnly = $true $form.Controls.Add($outputBox)
# 执行逻辑 $btnStart.Add_Click({ $target = $txtTarget.Text.Trim() $count = $cboCount.SelectedItem
if (-not $target) { [System.Windows.Forms.MessageBox]::Show("请输入目标地址!", "提示") return }
$outputBox.Clear() $outputBox.AppendText("正在执行 ICMP Ping 测试...`n")
# 初始化结果集合 $results = @()
for ($i = 1; $i -le $count; $i++) { try { $ping = New-Object System.Net.NetworkInformation.Ping $reply = $ping.Send($target, 1000) # 超时1秒 $status = $reply.Status $rtt = if ($reply.RoundtripTime) { $reply.RoundtripTime } else { "N/A" }
$outputBox.AppendText("`n第 $i 次测试: 地址=$target, 状态=$status, RTT=$rtt ms")
$results += [PSCustomObject]@{ 序号 = $i 地址 = $target 状态 = $status RTT_ms = $rtt 时间戳 = Get-Date -Format "yyyy-MM-dd HH:mm:ss" } } catch { $outputBox.AppendText("`n第 $i 次测试失败: $_") $results += [PSCustomObject]@{ 序号 = $i 地址 = $target 状态 = "Error" RTT_ms = "N/A" 时间戳 = Get-Date -Format "yyyy-MM-dd HH:mm:ss" } } }
# 显示在 GridView 中 $results | Out-GridView -Title "Ping 测试结果"
# 导出 CSV $csvPath = Join-Path $env:USERPROFILE "ICMP_Ping_$(Get-Date -Format yyyyMMdd_HHmmss).csv" $results | Export-Csv -Path $csvPath -NoTypeInformation -Encoding UTF8 $outputBox.AppendText("`n`n结果已导出到: $csvPath") })
# 启动窗体 [System.Windows.Forms.Application]::EnableVisualStyles() [System.Windows.Forms.Application]::Run($form)
|
执行了一次,还真能用

OK,我自己一行没写,实现了一个功能,还能筛选呢!,有点开心。
调试
第一轮调试 加数量控制
在实现了基本功能以后,熟话说饱暖思淫欲,我又有一个点子,能不能在这个测试的数量上增加一些
1 2
| 这个ping的数量我想要修改成自己填写(当然最大值是65535)这样就可以测试一段时间的网络情况
|
AI回复了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
| Add-Type -AssemblyName System.Windows.Forms Add-Type -AssemblyName System.Drawing
# 创建主窗体 $form = New-Object System.Windows.Forms.Form $form.Text = "PowerShell ICMP Ping 工具" $form.Size = New-Object System.Drawing.Size(600, 400) $form.StartPosition = 'CenterScreen'
# 标签和地址输入框 $labelTarget = New-Object System.Windows.Forms.Label $labelTarget.Location = New-Object System.Drawing.Point(20, 20) $labelTarget.Text = "请输入目标地址:" $form.Controls.Add($labelTarget)
$txtTarget = New-Object System.Windows.Forms.TextBox $txtTarget.Location = New-Object System.Drawing.Point(150, 20) $txtTarget.Size = New-Object System.Drawing.Size(300, 20) $form.Controls.Add($txtTarget)
# 自定义次数输入框 $labelCount = New-Object System.Windows.Forms.Label $labelCount.Location = New-Object System.Drawing.Point(20, 50) $labelCount.Text = "请输入测试次数 (最大 65535):" $form.Controls.Add($labelCount)
$txtCount = New-Object System.Windows.Forms.TextBox $txtCount.Location = New-Object System.Drawing.Point(150, 50) $txtCount.Size = New-Object System.Drawing.Size(100, 20) $txtCount.Text = "10" # 默认值 $form.Controls.Add($txtCount)
# 开始按钮 $btnStart = New-Object System.Windows.Forms.Button $btnStart.Location = New-Object System.Drawing.Point(20, 80) $btnStart.Text = "开始测试" $form.Controls.Add($btnStart)
# 结果显示 RichTextBox $outputBox = New-Object System.Windows.Forms.RichTextBox $outputBox.Location = New-Object System.Drawing.Point(20, 120) $outputBox.Size = New-Object System.Drawing.Size(540, 200) $outputBox.ReadOnly = $true $form.Controls.Add($outputBox)
# 执行逻辑 $btnStart.Add_Click({ $target = $txtTarget.Text.Trim() $countStr = $txtCount.Text.Trim()
if (-not $target) { [System.Windows.Forms.MessageBox]::Show("请输入目标地址!", "提示") return }
if (-not ($countStr -match '^\d+$')) { [System.Windows.Forms.MessageBox]::Show("请输入有效的数字作为测试次数!", "提示") return }
$count = [int]$countStr
if ($count -le 0 -or $count -gt 65535) { [System.Windows.Forms.MessageBox]::Show("请输入 1 到 65535 之间的测试次数!", "提示") return }
$outputBox.Clear() $outputBox.AppendText("正在执行 ICMP Ping 测试...`n")
# 初始化结果集合 $results = @()
for ($i = 1; $i -le $count; $i++) { try { $ping = New-Object System.Net.NetworkInformation.Ping $reply = $ping.Send($target, 1000) # 超时1秒 $status = $reply.Status $rtt = if ($reply.RoundtripTime) { $reply.RoundtripTime } else { "N/A" }
$outputBox.AppendText("`n第 $i 次测试: 地址=$target, 状态=$status, RTT=$rtt ms")
$results += [PSCustomObject]@{ 序号 = $i 地址 = $target 状态 = $status RTT_ms = $rtt 时间戳 = Get-Date -Format "yyyy-MM-dd HH:mm:ss" } } catch { $outputBox.AppendText("`n第 $i 次测试失败: $_") $results += [PSCustomObject]@{ 序号 = $i 地址 = $target 状态 = "Error" RTT_ms = "N/A" 时间戳 = Get-Date -Format "yyyy-MM-dd HH:mm:ss" } } }
# 显示在 GridView 中 $results | Out-GridView -Title "Ping 测试结果"
# 导出 CSV $csvPath = Join-Path $env:USERPROFILE "ICMP_Ping_$(Get-Date -Format yyyyMMdd_HHmmss).csv" $results | Export-Csv -Path $csvPath -NoTypeInformation -Encoding UTF8 $outputBox.AppendText("`n`n结果已导出到: $csvPath") })
# 启动窗体 [System.Windows.Forms.Application]::EnableVisualStyles() [System.Windows.Forms.Application]::Run($form)
|
第二轮调试 加中断功能
到这里脚本还是正常的,我又想要加一个中断功能,可以填写一个很大的测试值,但是我随时都可以停止脚本执行的按键
1
| 在开始测试的旁边可以加一个停止的选项,可以直接结束并展示结果
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
| Add-Type -AssemblyName System.Windows.Forms Add-Type -AssemblyName System.Drawing
# 全局变量用于控制循环和存储结果 $script:cancelPing = $false $script:results = @()
# 创建主窗体 $form = New-Object System.Windows.Forms.Form $form.Text = "PowerShell ICMP Ping 工具" $form.Size = New-Object System.Drawing.Size(600, 400) $form.StartPosition = 'CenterScreen'
# 标签和地址输入框 $labelTarget = New-Object System.Windows.Forms.Label $labelTarget.Location = New-Object System.Drawing.Point(20, 20) $labelTarget.Text = "请输入目标地址:" $form.Controls.Add($labelTarget)
$txtTarget = New-Object System.Windows.Forms.TextBox $txtTarget.Location = New-Object System.Drawing.Point(150, 20) $txtTarget.Size = New-Object System.Drawing.Size(300, 20) $form.Controls.Add($txtTarget)
# 自定义次数输入框 $labelCount = New-Object System.Windows.Forms.Label $labelCount.Location = New-Object System.Drawing.Point(20, 50) $labelCount.Text = "请输入测试次数 (最大 65535):" $form.Controls.Add($labelCount)
$txtCount = New-Object System.Windows.Forms.TextBox $txtCount.Location = New-Object System.Drawing.Point(150, 50) $txtCount.Size = New-Object System.Drawing.Size(100, 20) $txtCount.Text = "10" # 默认值 $form.Controls.Add($txtCount)
# 开始按钮 $btnStart = New-Object System.Windows.Forms.Button $btnStart.Location = New-Object System.Drawing.Point(20, 80) $btnStart.Text = "开始测试" $form.Controls.Add($btnStart)
# 停止按钮 $btnStop = New-Object System.Windows.Forms.Button $btnStop.Location = New-Object System.Drawing.Point(120, 80) $btnStop.Text = "停止测试" $btnStop.Enabled = $false $form.Controls.Add($btnStop)
# 结果显示 RichTextBox $outputBox = New-Object System.Windows.Forms.RichTextBox $outputBox.Location = New-Object System.Drawing.Point(20, 120) $outputBox.Size = New-Object System.Drawing.Size(540, 200) $outputBox.ReadOnly = $true $form.Controls.Add($outputBox)
# 执行 Ping 的函数(可在后台线程中运行) function Start-PingTest { param( [string]$target, [int]$count )
for ($i = 1; $i -le $count; $i++) { if ($script:cancelPing) { break }
try { $ping = New-Object System.Net.NetworkInformation.Ping $reply = $ping.Send($target, 1000) # 超时1秒 $status = $reply.Status $rtt = if ($reply.RoundtripTime) { $reply.RoundtripTime } else { "N/A" }
$line = "`n第 $i 次测试: 地址=$target, 状态=$status, RTT=$rtt ms" $script:resultQueue.Enqueue($line)
$script:results += [PSCustomObject]@{ 序号 = $i 地址 = $target 状态 = $status RTT_ms = $rtt 时间戳 = Get-Date -Format "yyyy-MM-dd HH:mm:ss" } } catch { $line = "`n第 $i 次测试失败: $_" $script:resultQueue.Enqueue($line) $script:results += [PSCustomObject]@{ 序号 = $i 地址 = $target 状态 = "Error" RTT_ms = "N/A" 时间戳 = Get-Date -Format "yyyy-MM-dd HH:mm:ss" } }
Start-Sleep -Milliseconds 100 # 可选:控制间隔时间 }
# 导出并提示 if ($script:results.Count -gt 0) { $csvPath = Join-Path $env:USERPROFILE "ICMP_Ping_$(Get-Date -Format yyyyMMdd_HHmmss).csv" $script:results | Export-Csv -Path $csvPath -NoTypeInformation -Encoding UTF8 $script:resultQueue.Enqueue("`n`n结果已导出到: $csvPath") }
$script:resultQueue.Enqueue("###TEST_FINISHED###") }
# 定时器用于更新 UI(防止阻塞主线程) $timer = New-Object System.Windows.Forms.Timer $timer.Interval = 200 $timer.Add_Tick({ while ($script:resultQueue.Count -gt 0) { $msg = $script:resultQueue.Dequeue() if ($msg -eq "###TEST_FINISHED###") { $btnStart.Enabled = $true $btnStop.Enabled = $false $script:cancelPing = $false return } $outputBox.AppendText($msg) } }) $timer.Start()
# 开始按钮点击事件 $btnStart.Add_Click({ $target = $txtTarget.Text.Trim() $countStr = $txtCount.Text.Trim()
if (-not $target) { [System.Windows.Forms.MessageBox]::Show("请输入目标地址!", "提示") return }
if (-not ($countStr -match '^\d+$')) { [System.Windows.Forms.MessageBox]::Show("请输入有效的数字作为测试次数!", "提示") return }
$count = [int]$countStr
if ($count -le 0 -or $count -gt 65535) { [System.Windows.Forms.MessageBox]::Show("请输入 1 到 65535 之间的测试次数!", "提示") return }
# 初始化变量 $script:results = @() $script:resultQueue = [System.Collections.Queue]::new() $script:cancelPing = $false
$outputBox.Clear() $outputBox.AppendText("正在执行 ICMP Ping 测试...`n")
$btnStart.Enabled = $false $btnStop.Enabled = $true
# 启动后台线程 $runspace = [RunspaceFactory]::CreateRunspace() $runspace.ApartmentState = "STA" $runspace.ThreadOptions = "ReuseThread" $runspace.Open()
$ps = [PowerShell]::Create() $ps.Runspace = $runspace $ps.AddScript(${function:Start-PingTest}) | Out-Null $ps.AddParameter("target", $target) | Out-Null $ps.AddParameter("count", $count) | Out-Null
$async = $ps.BeginInvoke() })
# 停止按钮点击事件 $btnStop.Add_Click({ $script:cancelPing = $true $btnStop.Enabled = $false $outputBox.AppendText("`n用户已手动停止测试。") })
# 启动窗体 [System.Windows.Forms.Application]::EnableVisualStyles() [System.Windows.Forms.Application]::Run($form)
|
放心,上面这个脚本已经挂了,执行了没结果的,感觉是执行了以后没有进入ping的逻辑,直接执行停止去了,接下来就是不断的调试,在这个过程中,我发现和AI调试,是有一些技巧的
因为对话的模型不是Agent的那种智能体,只能通过对话来了解我现在的界面情况,所以每次执行脚本后我就需要吧目前的结果情况反馈给AI,这样他就可以按照我的结果,去判断是不是脚本中的逻辑存在问题
经过多轮调试以后
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
| Add-Type -AssemblyName System.Windows.Forms Add-Type -AssemblyName System.Drawing
# 全局变量 $script:target = "" $script:count = 0 $script:index = 0 $script:canceled = $false $script:timer = New-Object System.Windows.Forms.Timer $script:timer.Interval = 200 # 每 200 毫秒执行一次 Ping
# 创建窗体 $form = New-Object System.Windows.Forms.Form $form.Text = "ICMP Ping 工具 (定时器版)" $form.Size = New-Object System.Drawing.Size(600, 400)
# 输入目标地址 $txtTarget = New-Object System.Windows.Forms.TextBox $txtTarget.Location = New-Object System.Drawing.Point(20, 20) $txtTarget.Width = 200 $txtTarget.Text = "www.baidu.com" $form.Controls.Add($txtTarget)
# 输入次数 $txtCount = New-Object System.Windows.Forms.TextBox $txtCount.Location = New-Object System.Drawing.Point(230, 20) $txtCount.Width = 50 $txtCount.Text = "10" $form.Controls.Add($txtCount)
# 开始按钮 $btnStart = New-Object System.Windows.Forms.Button $btnStart.Location = New-Object System.Drawing.Point(290, 20) $btnStart.Text = "开始测试" $form.Controls.Add($btnStart)
# 停止按钮 $btnStop = New-Object System.Windows.Forms.Button $btnStop.Location = New-Object System.Drawing.Point(370, 20) $btnStop.Text = "停止测试" $btnStop.Enabled = $false $form.Controls.Add($btnStop)
# 输出区域 $outputBox = New-Object System.Windows.Forms.RichTextBox $outputBox.Location = New-Object System.Drawing.Point(20, 60) $outputBox.Size = New-Object System.Drawing.Size(540, 280) $outputBox.ReadOnly = $true $form.Controls.Add($outputBox)
# Timer Tick 事件:每次执行一次 Ping $script:timer.Add_Tick({ if ($script:canceled) { $this.Stop() $btnStart.Enabled = $true $btnStop.Enabled = $false $outputBox.AppendText("`n🛑 测试已被用户中断。") return }
if ($script:index -ge $script:count) { $this.Stop() $btnStart.Enabled = $true $btnStop.Enabled = $false $outputBox.AppendText("`n✅ 测试已完成。") return }
$script:index++ try { $ping = New-Object System.Net.NetworkInformation.Ping $reply = $ping.Send($script:target, 1000) $status = $reply.Status $rtt = if ($reply.RoundtripTime) { $reply.RoundtripTime } else { "N/A" }
$outputBox.AppendText("`n第 $($script:index) 次测试: 地址=$($script:target), 状态=$status, RTT=$rtt ms") } catch { $outputBox.AppendText("`n第 $($script:index) 次测试失败: $_") } })
# 开始按钮点击事件 $btnStart.Add_Click({ $target = $txtTarget.Text.Trim() $countStr = $txtCount.Text.Trim()
if ([string]::IsNullOrWhiteSpace($target)) { [System.Windows.Forms.MessageBox]::Show("请输入目标地址!", "提示") return }
if (-not ($countStr -match '^\d+$') -or [int]$countStr -le 0 -or [int]$countStr -gt 65535) { [System.Windows.Forms.MessageBox]::Show("请输入有效的次数(1-65535)", "提示") return }
$script:target = $target $script:count = [int]$countStr $script:index = 0 $script:canceled = $false
$outputBox.Clear() $outputBox.AppendText("正在执行 ICMP 测试...")
$btnStart.Enabled = $false $btnStop.Enabled = $true
$script:timer.Start() })
# 停止按钮点击事件 $btnStop.Add_Click({ $script:canceled = $true $outputBox.AppendText("`n🛑 正在请求中断...") })
# 启动窗体 [System.Windows.Forms.Application]::EnableVisualStyles() [System.Windows.Forms.Application]::Run($form)
|
这个时间用时一个小时,圆满实现我的需求
第三轮调试 加报表查看功能
我还是不满足,因为第一版它给我弹出了一个窗口,我这个能停止了但是没有弹出窗口了,本着既要又要的逻辑,我就想要一个查看RTT延迟的报表功能
1
| #我想要RTT折线图,和第一版的脚本一样,可以在另一个窗口弹出来结果
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
| Add-Type -AssemblyName System.Windows.Forms Add-Type -AssemblyName System.Drawing Add-Type -AssemblyName System.Windows.Forms.DataVisualization
# 全局变量 $script:target = "" $script:count = 0 $script:index = 0 $script:canceled = $false $script:rttData = @() $script:timer = New-Object System.Windows.Forms.Timer $script:timer.Interval = 200 # 每 200 毫秒执行一次 Ping
# 创建主窗体 $form = New-Object System.Windows.Forms.Form $form.Text = "ICMP Ping 工具 (含图表)" $form.Size = New-Object System.Drawing.Size(600, 400)
# 输入目标地址 $txtTarget = New-Object System.Windows.Forms.TextBox $txtTarget.Location = New-Object System.Drawing.Point(20, 20) $txtTarget.Width = 200 $txtTarget.Text = "www.baidu.com" $form.Controls.Add($txtTarget)
# 输入次数 $txtCount = New-Object System.Windows.Forms.TextBox $txtCount.Location = New-Object System.Drawing.Point(230, 20) $txtCount.Width = 50 $txtCount.Text = "10" $form.Controls.Add($txtCount)
# 开始按钮 $btnStart = New-Object System.Windows.Forms.Button $btnStart.Location = New-Object System.Drawing.Point(290, 20) $btnStart.Text = "开始测试" $form.Controls.Add($btnStart)
# 停止按钮 $btnStop = New-Object System.Windows.Forms.Button $btnStop.Location = New-Object System.Drawing.Point(370, 20) $btnStop.Text = "停止测试" $btnStop.Enabled = $false $form.Controls.Add($btnStop)
# 查看图表按钮 $btnChart = New-Object System.Windows.Forms.Button $btnChart.Location = New-Object System.Drawing.Point(450, 20) $btnChart.Text = "查看图表" $btnChart.Enabled = $false $form.Controls.Add($btnChart)
# 输出区域 $outputBox = New-Object System.Windows.Forms.RichTextBox $outputBox.Location = New-Object System.Drawing.Point(20, 60) $outputBox.Size = New-Object System.Drawing.Size(540, 280) $outputBox.ReadOnly = $true $form.Controls.Add($outputBox)
# Timer Tick 事件:每次执行一次 Ping $script:timer.Add_Tick({ if ($script:canceled) { $this.Stop() $btnStart.Enabled = $true $btnStop.Enabled = $false $btnChart.Enabled = $true $outputBox.AppendText("`n🛑 测试已被用户中断。") return }
if ($script:index -ge $script:count) { $this.Stop() $btnStart.Enabled = $true $btnStop.Enabled = $false $btnChart.Enabled = $true $outputBox.AppendText("`n✅ 测试已完成。") return }
$script:index++ try { $ping = New-Object System.Net.NetworkInformation.Ping $reply = $ping.Send($script:target, 1000) $status = $reply.Status $rtt = if ($reply.RoundtripTime) { $reply.RoundtripTime } else { 0 }
if ($status -eq 'Success') { $script:rttData += [PSCustomObject]@{ Index = $script:index RTT = $rtt } }
$outputBox.AppendText("`n第 $($script:index) 次测试: 地址=$($script:target), 状态=$status, RTT=$rtt ms") } catch { $outputBox.AppendText("`n第 $($script:index) 次测试失败: $_") } })
# 开始按钮点击事件 $btnStart.Add_Click({ $target = $txtTarget.Text.Trim() $countStr = $txtCount.Text.Trim()
if ([string]::IsNullOrWhiteSpace($target)) { [System.Windows.Forms.MessageBox]::Show("请输入目标地址!", "提示") return }
if (-not ($countStr -match '^\d+$') -or [int]$countStr -le 0 -or [int]$countStr -gt 65535) { [System.Windows.Forms.MessageBox]::Show("请输入有效的次数(1-65535)", "提示") return }
$script:target = $target $script:count = [int]$countStr $script:index = 0 $script:canceled = $false $script:rttData = @()
$outputBox.Clear() $outputBox.AppendText("正在执行 ICMP 测试...")
$btnStart.Enabled = $false $btnStop.Enabled = $true $btnChart.Enabled = $false
$script:timer.Start() })
# 停止按钮点击事件 $btnStop.Add_Click({ $script:canceled = $true $outputBox.AppendText("`n🛑 正在请求中断...") })
# 查看图表按钮点击事件 $btnChart.Add_Click({ if ($script:rttData.Count -eq 0) { [System.Windows.Forms.MessageBox]::Show("没有可用数据,请先执行至少一次 Ping 测试。", "提示") return }
# 创建图表窗口 $chartForm = New-Object System.Windows.Forms.Form $chartForm.Text = "RTT 折线图" $chartForm.Size = New-Object System.Drawing.Size(800, 600)
# 创建 Chart 控件 $chart = New-Object System.Windows.Forms.DataVisualization.Charting.Chart $chart.Size = New-Object System.Drawing.Size(780, 540) $chartArea = New-Object System.Windows.Forms.DataVisualization.Charting.ChartArea $chart.ChartAreas.Add($chartArea)
# 设置系列 $series = New-Object System.Windows.Forms.DataVisualization.Charting.Series $series.ChartType = [System.Windows.Forms.DataVisualization.Charting.SeriesChartType]::Line $series.BorderWidth = 2 $series.Color = [System.Drawing.Color]::Blue
foreach ($item in $script:rttData) { $series.Points.AddXY($item.Index, $item.RTT) }
$chart.Series.Add($series)
# 添加标题和轴标签 $chart.Titles.Add("RTT 变化趋势") | Out-Null $chart.ChartAreas[0].AxisX.Title = "Ping 序号" $chart.ChartAreas[0].AxisY.Title = "RTT (ms)"
$chartForm.Controls.Add($chart) $chartForm.ShowDialog() })
# 启动主窗体 [System.Windows.Forms.Application]::EnableVisualStyles() [System.Windows.Forms.Application]::Run($form)
|
OK这个功能也能实现了
第四轮调试 加导出功能
在实际使用中,我们往往要通过邮件发送日志文件,所以我还想要一个log导出的功能,这个就需要每次写一个csv文件导出来
1
| #我想要在图标界面增加一个导出的功能,可以导出为csv文件
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
| Add-Type -AssemblyName System.Windows.Forms Add-Type -AssemblyName System.Drawing Add-Type -AssemblyName System.Windows.Forms.DataVisualization
# 全局变量 $script:target = "" $script:count = 0 $script:index = 0 $script:canceled = $false $script:rttData = @() $script:timer = New-Object System.Windows.Forms.Timer $script:timer.Interval = 200 # 每 200 毫秒执行一次 Ping
# 创建主窗体 $form = New-Object System.Windows.Forms.Form $form.Text = "ICMP Ping 工具 (含时间戳)" $form.Size = New-Object System.Drawing.Size(650, 400)
# 输入目标地址 $txtTarget = New-Object System.Windows.Forms.TextBox $txtTarget.Location = New-Object System.Drawing.Point(20, 20) $txtTarget.Width = 200 $txtTarget.Text = "www.baidu.com" $form.Controls.Add($txtTarget)
# 输入次数 $txtCount = New-Object System.Windows.Forms.TextBox $txtCount.Location = New-Object System.Drawing.Point(230, 20) $txtCount.Width = 50 $txtCount.Text = "10" $form.Controls.Add($txtCount)
# 开始按钮 $btnStart = New-Object System.Windows.Forms.Button $btnStart.Location = New-Object System.Drawing.Point(290, 20) $btnStart.Text = "开始测试" $form.Controls.Add($btnStart)
# 停止按钮 $btnStop = New-Object System.Windows.Forms.Button $btnStop.Location = New-Object System.Drawing.Point(370, 20) $btnStop.Text = "停止测试" $btnStop.Enabled = $false $form.Controls.Add($btnStop)
# 查看图表按钮 $btnChart = New-Object System.Windows.Forms.Button $btnChart.Location = New-Object System.Drawing.Point(450, 20) $btnChart.Text = "查看图表" $btnChart.Enabled = $false $form.Controls.Add($btnChart)
# 导出按钮 $btnExport = New-Object System.Windows.Forms.Button $btnExport.Location = New-Object System.Drawing.Point(530, 20) $btnExport.Text = "导出结果" $btnExport.Enabled = $false $form.Controls.Add($btnExport)
# 输出区域 $outputBox = New-Object System.Windows.Forms.RichTextBox $outputBox.Location = New-Object System.Drawing.Point(20, 60) $outputBox.Size = New-Object System.Drawing.Size(590, 280) $outputBox.ReadOnly = $true $form.Controls.Add($outputBox)
# Timer Tick 事件:每次执行一次 Ping $script:timer.Add_Tick({ if ($script:canceled) { $this.Stop() $btnStart.Enabled = $true $btnStop.Enabled = $false $btnChart.Enabled = $true $btnExport.Enabled = $true $outputBox.AppendText("`n🛑 测试已被用户中断。") return }
if ($script:index -ge $script:count) { $this.Stop() $btnStart.Enabled = $true $btnStop.Enabled = $false $btnChart.Enabled = $true $btnExport.Enabled = $true $outputBox.AppendText("`n✅ 测试已完成。") return }
$script:index++ try { $timestamp = Get-Date -Format "HH:mm:ss"
$ping = New-Object System.Net.NetworkInformation.Ping $reply = $ping.Send($script:target, 1000) $status = $reply.Status $rtt = if ($reply.RoundtripTime) { $reply.RoundtripTime } else { "N/A" }
if ($status -eq 'Success') { $script:rttData += [PSCustomObject]@{ Index = $script:index Timestamp = $timestamp Target = $script:target Status = $status RTT = $rtt } } else { $script:rttData += [PSCustomObject]@{ Index = $script:index Timestamp = $timestamp Target = $script:target Status = $status RTT = "N/A" } }
$outputBox.AppendText("`n[$timestamp] 第 $($script:index) 次测试: 地址=$($script:target), 状态=$status, RTT=$rtt ms")
} catch { $timestamp = Get-Date -Format "HH:mm:ss" $outputBox.AppendText("`n[$timestamp] 第 $($script:index) 次测试失败: $_") } })
# 开始按钮点击事件 $btnStart.Add_Click({ $target = $txtTarget.Text.Trim() $countStr = $txtCount.Text.Trim()
if ([string]::IsNullOrWhiteSpace($target)) { [System.Windows.Forms.MessageBox]::Show("请输入目标地址!", "提示") return }
if (-not ($countStr -match '^\d+$') -or [int]$countStr -le 0 -or [int]$countStr -gt 65535) { [System.Windows.Forms.MessageBox]::Show("请输入有效的次数(1-65535)", "提示") return }
$script:target = $target $script:count = [int]$countStr $script:index = 0 $script:canceled = $false $script:rttData = @()
$outputBox.Clear() $outputBox.AppendText("正在执行 ICMP 测试...")
$btnStart.Enabled = $false $btnStop.Enabled = $true $btnChart.Enabled = $false $btnExport.Enabled = $false
$script:timer.Start() })
# 停止按钮点击事件 $btnStop.Add_Click({ $script:canceled = $true $outputBox.AppendText("`n🛑 正在请求中断...") })
# 查看图表按钮点击事件 $btnChart.Add_Click({ if ($script:rttData.Count -eq 0) { [System.Windows.Forms.MessageBox]::Show("没有可用数据,请先执行至少一次 Ping 测试。", "提示") return }
# 创建图表窗口 $chartForm = New-Object System.Windows.Forms.Form $chartForm.Text = "RTT 折线图" $chartForm.Size = New-Object System.Drawing.Size(800, 600)
# 创建 Chart 控件 $chart = New-Object System.Windows.Forms.DataVisualization.Charting.Chart $chart.Dock = 'Fill' $chartArea = New-Object System.Windows.Forms.DataVisualization.Charting.ChartArea $chart.ChartAreas.Add($chartArea)
# 设置系列 $series = New-Object System.Windows.Forms.DataVisualization.Charting.Series $series.ChartType = [System.Windows.Forms.DataVisualization.Charting.SeriesChartType]::Line $series.BorderWidth = 2 $series.Color = [System.Drawing.Color]::Blue
foreach ($item in $script:rttData | Where-Object { $_.RTT -ne "N/A" }) { $series.Points.AddXY($item.Index, $item.RTT) }
$chart.Series.Add($series)
# 添加标题和轴标签 $chart.Titles.Add("RTT 变化趋势") | Out-Null $chart.ChartAreas[0].AxisX.Title = "Ping 序号" $chart.ChartAreas[0].AxisY.Title = "RTT (ms)"
$chartForm.Controls.Add($chart) $chartForm.ShowDialog() })
# 导出按钮点击事件 $btnExport.Add_Click({ if ($script:rttData.Count -eq 0) { [System.Windows.Forms.MessageBox]::Show("没有可用数据,请先执行至少一次 Ping 测试。", "提示") return }
$saveDialog = New-Object System.Windows.Forms.SaveFileDialog $saveDialog.Filter = "CSV 文件 (*.csv)|*.csv" $saveDialog.Title = "保存 Ping 测试结果"
if ($saveDialog.ShowDialog() -eq "OK") { $filePath = $saveDialog.FileName $script:rttData | Export-Csv -Path $filePath -NoTypeInformation -Encoding UTF8 [System.Windows.Forms.MessageBox]::Show("数据已成功导出到:`n$filePath", "导出完成") } })
# 启动窗体 [System.Windows.Forms.Application]::EnableVisualStyles() [System.Windows.Forms.Application]::Run($form)
|
最后可以了
整个下来,我没写一行代码,实现了这个功能,后面再研究它的运行逻辑吧