如何在 PowerShell 7 中为 TTS 使用 Windows System.Speech(或者是否有替代方法)

How to use Windows System.Speech for TTS in PowerShell 7 (or is there an alternative)

我在 WindowsPowerShell 和 PowerShell 中都有相同的配置文件。ps1。 它包括调用 Windows Text-To-Speech 的命令 但是,在 PowerShell 7 中 运行 时,这些命令会失败。

当我尝试使用通过以下代码创建的 $PomrptTTS 对象时出现错误:

Add-Type -AssemblyName System.speech
$PromptTTS = New-Object System.Speech.Synthesis.SpeechSynthesizer

在 PowerShell 7 中,任何访问或使用我的 $PormptTTS 对象的尝试都会产生以下内容:

SetValueInvocationException: ....\profile.ps1:82
Line |
  82 |  $PromptTTS.Rate = 0 ; $PromptTTS.Speak("Time for the $((Get-Date).DayofWeek) shuffle")
     |  ~~~~~~~~~~~~~~~~~~~
     | Exception setting "Rate": "Object reference not set to an instance of an object."

MethodInvocationException: ....\profile.ps1:82
Line |
  82 |  … e = 0 ; $PromptTTS.Speak("Time for the $((Get-Date).DayofWeek) shuffle")
     |                                             ~~~~~~~~~~~~~~~~~~~~
     | Exception calling "Speak" with "1" argument(s): "Object reference not set to an instance of an object."

从 PowerShell 7.0/.NET Core 3.1 开始,System.Speech.Synthesis.SpeechSynthesizer is considered a .NET Framework-only API因此在 .NET Core 中不受支持。

  • this GitHub issue 中正在进行关于此的讨论;由于底层 API 是 特定于 Windows,问题是它是否值得通过 跨平台 公开。 NET 核心框架。

解决方法 是使用 SAPI.SpVoice COM 对象(我认为 .NET Framework API 最终基于该对象):

$sp = New-Object -ComObject SAPI.SpVoice
$sp.Speak("Time for the $((Get-Date).DayOfWeek) shuffle")

一个related question asks about changing the speaking voice, which, unfortunately doesn't seem to be supported in PowerShell Core as of PowerShell 7.0, due to limited COM support - see this answer.

mklement0 的答案更好,但如果你想要一个稍微有点老套的 Windows 10+ 选项,它适用于版本 7(但不是版本 5),你可以使用 Windows Media Foundation speech api 代替。

Here's a gist that uses this option.

使用 Windows 媒体基础的好处是您可以使用 Windows 讲述人支持的 all of the "OneCore" voices,而 SAPI 仅支持三种默认语音