PowerShell中Sapi.spvoice的.speak()方法返回多余输出1如何解决
问题背景
近期了解到spvoice接口,计划编写一个小型PowerShell程序,实现将输入的文本内容转为语音播报的功能,初始实现代码如下:
$Voice = New-Object -ComObject Sapi.spvoice for(;;){ Clear-Host $UserInput = Read-Host if($UserInput -eq "Voice.Rate"){ $VoiceRate = Read-Host "Set new voice rate"} else{ $Voice.rate = $VoiceRate $Voice.speak("$UserInput")}}
目前程序可以正常实现预期的语音播报功能,但调用.speak()方法时会额外返回数值1,需要阻止这种不必要的输出出现。
原因说明
Sapi.spvoice的Speak()方法本身会返回一个长整型数值,代表当前语音播放流的标识。PowerShell默认会将所有未被显式处理的方法返回值直接输出到控制台,这就是多余数字1的来源。
解决方法
只需要将Speak()方法的返回值显式丢弃即可,有三种常用写法,任选其一替换原来的$Voice.speak("$UserInput")行即可:
- 强制转换为空类型:
[void]$Voice.speak("$UserInput") - 重定向输出到空变量:
$Voice.speak("$UserInput") | Out-Null - 直接赋值给$null:
$null = $Voice.speak("$UserInput")
另外原代码存在一个小隐患:首次运行未手动设置语速时,$VoiceRate变量为空,赋值给$Voice.rate可能触发异常,建议初始化时添加默认语速配置(语速合法范围为-10到10,0为默认正常语速)。修正后的完整可运行代码如下:
$Voice = New-Object -ComObject Sapi.spvoice # 初始化默认语速 $VoiceRate = 0 for(;;){ Clear-Host $UserInput = Read-Host if($UserInput -eq "Voice.Rate"){ $VoiceRate = Read-Host "Set new voice rate (valid range: -10 ~ 10)" } else{ $Voice.rate = $VoiceRate [void]$Voice.speak("$UserInput") } }
内容的提问来源于stack exchange,提问作者PlatoHero
相关产品推荐
相关产品推荐

