1

In PowerShell 5.1.18362.752, when I try to execute the following:

Add-Type -AssemblyName System.Speech; $x = New-Object System.Speech.Synthesis.SpeechSynthesizer; $x.Speak('Hello. This is a sentence.')

I cannot seem to interrupt it with Ctrl+C while it's speaking. The whole input is read out loud. Is there any way to stop this before it would finish by itself? I know I can close PowerShell which stops the speech immediately, but I am looking for something more graceful, especially since it takes one or more seconds for my PS to restart -- and for my usecase I need to be able to interrupt speech and rapidly start a different one without the user having to wait several seconds.

Wizek
  • 4,854
  • 2
  • 25
  • 52
  • As an aside: The inability to use Ctrl-C applies to any (long-running, synchronous) .NET method call in PowerShell, as of 7.0 - see [this answer](https://stackoverflow.com/a/60896491/45375). – mklement0 May 10 '20 at 08:14
  • Another aside: This is how you would do it via [`SAPI.SpVoice`](https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ms723602(v%3Dvs.85)) (which is what you'd have to use in PowerShell _Core_, where `System.Speech.Synthesis.SpeechSynthesizer` isn't supported): `$tts = New-Object -ComObject SAPI.SpVoice; $tts.speak('Hello. This is a sentence.', 1); Start-Sleep -Milliseconds 300; $tts.Speak('', 2)` – mklement0 May 10 '20 at 08:50

1 Answers1

3

You should call the SpeakAsync() asynchronous method instead of Speak() which is blocking.

Then you can stop the speech easily with SpeakAsyncCancelAll()

Add-Type -AssemblyName System.Speech;
$x = New-Object System.Speech.Synthesis.SpeechSynthesizer;
$x.SpeakAsync('Hello. This is a very very very very long sentence.')
Start-Sleep 1
$x.SpeakAsyncCancelAll()

Lots of useful information can be found in microsoft docs.

Bruno
  • 160
  • 6