2

I am unable to get all the INSTALLED voices for a multi-lingual Text-to-Speech solution, although all installed languages are showing up. I know similar questions have been asked before but there don't seem to be any answers even yet except for some registry tweaks. The code is as under:

        foreach (InputLanguage lang in InputLanguage.InstalledInputLanguages)
        {
            txtText.AppendText(Environment.NewLine + Environment.NewLine + lang.Culture.EnglishName);

            using (SpeechSynthesizer synthesizer = new SpeechSynthesizer())
            {
                var voiceCollection = synthesizer.GetInstalledVoices(new CultureInfo(lang.Culture.Name));

                foreach (InstalledVoice voice in voiceCollection)
                {
                    VoiceInfo info = voice.VoiceInfo;
                    txtText.AppendText(Environment.NewLine + "Name: " + info.Name);
                    txtText.AppendText(Environment.NewLine + "Gender: " + info.Gender);
                    txtText.AppendText(Environment.NewLine + "Culture: " + info.Culture + Environment.NewLine);
                }
            }
        }
BIK
  • 31
  • 5
  • Based on my research, I find that you may not install the voices correctly. Please refer to the similar problem [SpeechSynthesizer doesn't get all installed voices 3](https://stackoverflow.com/questions/51811901/speechsynthesizer-doesnt-get-all-installed-voices-3) to see if it works for you. – Jack J Jun Apr 20 '20 at 02:56
  • I have tried it but it doesn't work. There is an explanation at https://www.ghacks.net/2018/08/11/unlock-all-windows-10-tts-voices-system-wide-to-get-more-of-them/ but it means modifying the registry, which is not a programming solution. – BIK Apr 20 '20 at 04:39

1 Answers1

3

I have found the solution. As you said, we have to modify the registry to get all the

voices successfully.

However, we don't need to modify it manually. You can run the following powershell code in

windows powershell.(Don't forget run as administrator for powershell)

$sourcePath = 'HKLM:\software\Microsoft\Speech_OneCore\Voices\Tokens' #Where the OneCore voices live
$destinationPath = 'HKLM:\SOFTWARE\Microsoft\Speech\Voices\Tokens' #For 64-bit apps
$destinationPath2 = 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\SPEECH\Voices\Tokens' #For 32-bit apps
cd $destinationPath
$listVoices = Get-ChildItem $sourcePath
foreach($voice in $listVoices)
{
$source = $voice.PSPath #Get the path of this voices key
copy -Path $source -Destination $destinationPath -Recurse
copy -Path $source -Destination $destinationPath2 -Recurse
}

After running this, you can run your current winform app again. You can see all the

installed voices.

Here is my tested result:

enter image description here

Jack J Jun
  • 5,633
  • 1
  • 9
  • 27
  • Manually or otherwise, it still is modifying the registry. Can we get our c# program to do it on a user's system? – BIK Apr 20 '20 at 07:22
  • If you still want to use c#, I suggest that you can try [Execute PowerShell Script from C# with Commandline Arguments](https://stackoverflow.com/questions/527513/execute-powershell-script-from-c-sharp-with-commandline-arguments). However, it still need to modify the registry. Until now, this is a simpler way I found. Therefore, I suggest that you have a try. – Jack J Jun Apr 20 '20 at 07:52