About Sytem.Speech
System.Speech is a native .NET Framework 4.x, 3.x assembly that implements speech related functionality including text to speech and speech to text. This post is not about System.Speech, but how to use it with .NET Core 3.0. You can download the code of this blog and start using it. More information about System.Speech you can get at Microsoft Documentation.
How it is implemented
You cannot call directly NET Framework from NET Core.
See code bellow:
- using System;
- using System.Text;
- using System.Windows.Forms;
- namespace SytemSpeechNETCore3
- {
- public partial class Form1 : Form
- {
- public Form1()
- {
- InitializeComponent();
- Speak("Hello World!");
- }
- private static void Speak(string textToSpeech, bool wait = false)
- {
- // Command to execute PS
- Execute($@"Add-Type -AssemblyName System.speech;
- $speak = New-Object System.Speech.Synthesis.SpeechSynthesizer;
- $speak.Speak(""{textToSpeech}"");"); // Embedd text
- void Execute(string command)
- {
- // create a temp file with .ps1 extension
- var cFile = System.IO.Path.GetTempPath() + Guid.NewGuid() + ".ps1";
- //Write the .ps1
- using var tw = new System.IO.StreamWriter(cFile, false, Encoding.UTF8);
- tw.Write(command);
- // Setup the PS
- var start =
- new System.Diagnostics.ProcessStartInfo()
- {
- FileName = "C:\\windows\\system32\\windowspowershell\\v1.0\\powershell.exe", // CHUPA MICROSOFT 02-10-2019 23:45
- LoadUserProfile = false,
- UseShellExecute = false,
- CreateNoWindow = true,
- Arguments = $"-executionpolicy bypass -File {cFile}",
- WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden
- };
- //Init the Process
- var p = System.Diagnostics.Process.Start(start);
- // The wait may not work! :(
- if (wait) p.WaitForExit();
- }
- }
- }
- }
With this code, your Windows based App can speech. It works on Windows 7, 8.1 and 10.
Happy coding.

Y KPosted Aug 5, 2022, 11:44 AM
Note that System.Speech was ported by Microsoft to .NET Standard 2.0/.NET (Core) 3.1/5/6, so there's no longer any need for this approach (the port did not exist at the time the article was written). One could just get the package from NuGet and use it.
Thomas ThomasPosted Oct 1, 2020, 9:16 AM
Is it possible to write the output into a stream?
C.A. TuckerPosted Sep 11, 2020, 1:53 AM
Excellent. Works like a charm. Thank you!
Jefferson S. MottaPosted May 1, 2020, 2:18 PM
Sorry, what is wrong?
Leo HunterPosted May 1, 2020, 2:50 AM
Public static void Speak(string textToSpeech, int speakTimeMs = 0) { try { // Command to execute PS Execute($@"Add-Type -AssemblyName System.speech; $speak = New-Object System.Speech.Synthesis.SpeechSynthesizer; $speak.Speak(""{textToSpeech}"");"); // Embedd text void Execute(string command) { // create a temp file with .ps1 extension var cFile = System.IO.Path.GetTempPath() + Guid.NewGuid() + ".ps1"; //Write the .ps1 using var tw = new System.IO.StreamWriter(cFile, false, Encoding.UTF8); tw.Write(command); // Setup the PS var start = new System.Diagnostics.ProcessStartInfo() { FileName = "C:\\windows\\system32\\windowspowershell\\v1.0\\powershell.exe", // CHUPA MICROSOFT 02-10-2019 23:45 LoadUserProfile = false, UseShellExecute = false, CreateNoWindow = true, Arguments = $"-executionpolicy bypass -File {cFile}", WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden }; //Init the Process var p = System.Diagnostics.Process.Start(start); } Task.Delay(speakTimeMs).Wait(); Log.WriteLine("Speaker: " + textToSpeech); } catch (Exception ex) { Log.WriteLine($"Speaker Error: e={ex.Message} _ {textToSpeech}"); } }