PowerShell串口命令发送JSON字符串时语法解析错误求助
PowerShell COM口配置设备JSON字符串解析报错解决办法
问题描述
编写PowerShell脚本通过COM连接执行设备基础配置,收集用户输入后拼接压缩JSON字符串通过USB发送。不含JSON的命令(如重启)可正常执行,但JSON字符串因PowerShell语法规则导致脚本报错。
报错信息
At line:146 char:22 + $port.Write("3,{"bankName":"$bankName","bankId":"0","footswitches ... + ~ Missing ')' in method call. At line:146 char:22 + ... .Write("3,{"bankName":"$bankName","bankId":"0","footswitches":[{"name ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Unexpected token 'bankName":"$bankName","bankId":"0","footswitches":[{"name":"$FS1 "},{"name":"$FS2"},{"name":"$FS3"},{"name":"$FS4"},{"name":"$FS5"},{"name":"$FS6"} ]}~"' in expression or statement. At line:126 char:1 + { + ~ Missing closing '}' in statement block or type definition. At line:146 char:172 + ... ,{"name":"$FS3"},{"name":"$FS4"},{"name":"$FS5"},{"name":"$FS6"}]}~") + ~ Unexpected token ')' in expression or statement. At line:149 char:1 + } + ~ Unexpected token '}' in expression or statement. + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordExcep tion + FullyQualifiedErrorId : MissingEndParenthesisInMethodCall
完整脚本
Add-Type -AssemblyName System.Windows.Forms Add-Type -AssemblyName System.Drawing $form = New-Object System.Windows.Forms.Form $form.Text = 'Bridge Namer' $form.Size = New-Object System.Drawing.Size(300,400) $form.StartPosition = 'CenterScreen' $okButton = New-Object System.Windows.Forms.Button $okButton.Location = New-Object System.Drawing.Point(75,320) $okButton.Size = New-Object System.Drawing.Size(75,23) $okButton.Text = 'OK' $okButton.DialogResult = [System.Windows.Forms.DialogResult]::OK $form.AcceptButton = $okButton $form.Controls.Add($okButton) $cancelButton = New-Object System.Windows.Forms.Button $cancelButton.Location = New-Object System.Drawing.Point(150,320) $cancelButton.Size = New-Object System.Drawing.Size(75,23) $cancelButton.Text = 'Cancel' $cancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel $form.CancelButton = $cancelButton $form.Controls.Add($cancelButton) $label = New-Object System.Windows.Forms.Label $label.Location = New-Object System.Drawing.Point(10,20) $label.Size = New-Object System.Drawing.Size(280,20) $label.Text = 'What Bank Number do you want to Re-Name?' $form.Controls.Add($label) $textBoxbankNumber = New-Object System.Windows.Forms.TextBox $textBoxbankNumber.Location = New-Object System.Drawing.Point(10,40) $textBoxbankNumber.Size = New-Object System.Drawing.Size(260,20) $form.Controls.Add($textBoxbankNumber) $label = New-Object System.Windows.Forms.Label $label.Location = New-Object System.Drawing.Point(10,70) $label.Size = New-Object System.Drawing.Size(280,20) $label.Text = 'New Bank Name:' $form.Controls.Add($label) $textBoxbankName = New-Object System.Windows.Forms.TextBox $textBoxbankName.Location = New-Object System.Drawing.Point(10,90) $textBoxbankName.Size = New-Object System.Drawing.Size(260,20) $form.Controls.Add($textBoxbankName) $label = New-Object System.Windows.Forms.Label $label.Location = New-Object System.Drawing.Point(10,120) $label.Size = New-Object System.Drawing.Size(120,20) $label.Text = 'Footswitch 1 Name:' $form.Controls.Add($label) $textBoxFS1 = New-Object System.Windows.Forms.TextBox $textBoxFS1.Location = New-Object System.Drawing.Point(10,140) $textBoxFS1.Size = New-Object System.Drawing.Size(120,20) $form.Controls.Add($textBoxFS1) $label = New-Object System.Windows.Forms.Label $label.Location = New-Object System.Drawing.Point(150,120) $label.Size = New-Object System.Drawing.Size(120,20) $label.Text = 'Footswitch 2 Name:' $form.Controls.Add($label) $textBoxFS2 = New-Object System.Windows.Forms.TextBox $textBoxFS2.Location = New-Object System.Drawing.Point(150,140) $textBoxFS2.Size = New-Object System.Drawing.Size(120,20) $form.Controls.Add($textBoxFS2) $label = New-Object System.Windows.Forms.Label $label.Location = New-Object System.Drawing.Point(10,170) $label.Size = New-Object System.Drawing.Size(120,20) $label.Text = 'Footswitch 3 Name:' $form.Controls.Add($label) $textBoxFS3 = New-Object System.Windows.Forms.TextBox $textBoxFS3.Location = New-Object System.Drawing.Point(10,190) $textBoxFS3.Size = New-Object System.Drawing.Size(120,20) $form.Controls.Add($textBoxFS3) $label = New-Object System.Windows.Forms.Label $label.Location = New-Object System.Drawing.Point(150,170) $label.Size = New-Object System.Drawing.Size(120,20) $label.Text = 'Footswitch 4 Name:' $form.Controls.Add($label) $textBoxFS4 = New-Object System.Windows.Forms.TextBox $textBoxFS4.Location = New-Object System.Drawing.Point(150,190) $textBoxFS4.Size = New-Object System.Drawing.Size(120,20) $form.Controls.Add($textBoxFS4) $label = New-Object System.Windows.Forms.Label $label.Location = New-Object System.Drawing.Point(10,220) $label.Size = New-Object System.Drawing.Size(120,20) $label.Text = 'Footswitch 5 Name:' $form.Controls.Add($label) $textBoxFS5 = New-Object System.Windows.Forms.TextBox $textBoxFS5.Location = New-Object System.Drawing.Point(10,240) $textBoxFS5.Size = New-Object System.Drawing.Size(120,20) $form.Controls.Add($textBoxFS5) $label = New-Object System.Windows.Forms.Label $label.Location = New-Object System.Drawing.Point(150,220) $label.Size = New-Object System.Drawing.Size(120,20) $label.Text = 'Footswitch 6 Name:' $form.Controls.Add($label) $textBoxFS6 = New-Object System.Windows.Forms.TextBox $textBoxFS6.Location = New-Object System.Drawing.Point(150,240) $textBoxFS6.Size = New-Object System.Drawing.Size(120,20) $form.Controls.Add($textBoxFS6) $form.Topmost = $true $form.Add_Shown({$textBoxbankNumber.Select()}) $form.Add_Shown({$textBoxbankName.Select()}) $form.Add_Shown({$textBoxFS1.Select()}) $form.Add_Shown({$textBoxFS2.Select()}) $form.Add_Shown({$textBoxFS3.Select()}) $form.Add_Shown({$textBoxFS4.Select()}) $form.Add_Shown({$textBoxFS5.Select()}) $form.Add_Shown({$textBoxFS6.Select()}) $result = $form.ShowDialog() if ($result -eq [System.Windows.Forms.DialogResult]::OK) { $bankNumber = $textBoxbankNumber.Text $bankName = $textBoxbankName.Text $FS1 = $textBoxFS1.Text $FS2 = $textBoxFS2.Text $FS3 = $textBoxFS3.Text $FS4 = $textBoxFS4.Text $FS5 = $textBoxFS5.Text $FS6 = $textBoxFS6.Text $port= new-Object System.IO.Ports.SerialPort COM6,9600,None,8,one $port.DtrEnable = "true" $port.open() Start-Sleep -Milliseconds 50 $port.Write("0,RSET~") Start-Sleep -Milliseconds 50 $port.Write("1,DTXR~") Start-Sleep -Milliseconds 50 $port.Write("2,bankSettings,$bankNumber~") Start-Sleep -Milliseconds 50 $port.Write("3,{"bankName":"$bankName","bankId":"0","footswitches":[{"name":"$FS1"},{"name":"$FS2"},{"name":"$FS3"},{"name":"$FS4"},{"name":"$FS5"},{"name":"$FS6"}]}~") Start-Sleep -Milliseconds 50 $port.close() }
解决办法
报错核心原因是PowerShell双引号字符串内的JSON双引号未转义,导致解析混淆。以下三种简单方式可解决:
方式1:转义JSON中的双引号
在JSON的每个双引号前添加反引号(`),让PowerShell将其视为普通字符:
$port.Write("3,{`"bankName`":`"$bankName`",`"bankId`":`"0`",`"footswitches`":[{`"name`":`"$FS1`"},{`"name`":`"$FS2`"},{`"name`":`"$FS3`"},{`"name`":`"$FS4`"},{`"name`":`"$FS5`"},{`"name`":`"$FS6`"}]}~")
方式2:使用Here-String
Here-String可保留字符串原样,无需手动转义双引号,适合复杂JSON场景:
$jsonPayload = @" 3,{"bankName":"$bankName","bankId":"0","footswitches":[{"name":"$FS1"},{"name":"$FS2"},{"name":"$FS3"},{"name":"$FS4"},{"name":"$FS5"},{"name":"$FS6"}]}~ "@ $port.Write($jsonPayload)
方式3:用ConvertTo-JSON生成规范JSON(推荐)
先创建PowerShell对象,再转换为压缩JSON,彻底避免手动拼接的语法错误:
$bankConfig = [PSCustomObject]@{ bankName = $bankName bankId = "0" footswitches = @( @{ name = $FS1 }, @{ name = $FS2 }, @{ name = $FS3 }, @{ name = $FS4 }, @{ name = $FS5 }, @{ name = $FS6 } ) } $jsonString = $bankConfig | ConvertTo-Json -Compress $port.Write("3,$jsonString~")
内容的提问来源于stack exchange,提问作者grelbatron
相关产品推荐
相关产品推荐

