Search code examples
c#windows-runtimewindows-store-appssapi

AccessViolationException in Windows.Media.SpeechSynthesis.SpeechSynthesizer constructor


My app is getting an AccessViolationException when calling the default constructor of the Windows.Media.SpeechSynthesis.SpeechSynthesizer class. This only happens on one particular machine (so far at least), which is a Surface Pro 3 running Windows 8.1. All other machines with the app installed do not experience this issue.

My code is something like this:

class Speech
{
    private Windows.Media.SpeechSynthesis.SpeechSynthesizer _Synthesizer;
    public Speech()
    {
        SetVoice();
    }

    private void SetVoice()
    {
        try
        {
            // Exception is raised here
            _Synthesizer = new Windows.Media.SpeechSynthesis.SpeechSynthesizer();
        }
        catch (Exception e)
        {

        }
    }
}

The stack trace that shows up in the Event Logs looks like this:

Description: The process was terminated due to an unhandled exception
Exception Info: System.AccessViolationException
Stack:
    at Windows.Media.SpeechSynthesis.SpeechSynthesizer..ctor()
    at ... Speech.SetVoice()
    at ... Speech..ctor()

I captured a dump file using ProcDump and can see this in the stacktrace (it doesn't show "my code" just the code after it):

sapi.dll!CSpObjectTokenEnumBuilder::CheckTokenSignature(struct ISpDataKey *) Unknown
sapi.dll!CSpObjectTokenEnumBuilder::AddTokensFromDataKey(struct ISpDataKey *,unsigned short const *,unsigned short const *) Unknown
sapi.dll!CSpObjectTokenCategory::InternalEnumTokens(unsigned short const *,unsigned short const *,struct IEnumSpObjectTokens * *,int) Unknown
sapi.dll!CSpObjectTokenCategory::EnumTokens(unsigned short const *,unsigned short const *,struct IEnumSpObjectTokens * *) Unknown
Windows.Media.SpeechSynthesis.dll!SpEnumTokens(unsigned short const *,unsigned short const *,unsigned short const *,struct IEnumSpObjectTokens * *) Unknown
Windows.Media.SpeechSynthesis.dll!Windows::Media::SpeechSynthesis::InstalledVoicesStatic::get_AllVoices(struct Windows::Foundation::Collections::IVectorView<class Windows::Media::SpeechSynthesis::VoiceInformation *> * *) Unknown
Windows.Media.SpeechSynthesis.dll!Windows::Media::SpeechSynthesis::InstalledVoicesStatic::get_DefaultVoiceWithRank(struct Windows::Media::SpeechSynthesis::IVoiceInformation * *,unsigned int *) Unknown
Windows.Media.SpeechSynthesis.dll!Windows::Media::SpeechSynthesis::CSpeechSynthesizer::GetDefaultVoice(struct Windows::Media::SpeechSynthesis::IVoiceInformation * *,unsigned int *) Unknown
Windows.Media.SpeechSynthesis.dll!Windows::Media::SpeechSynthesis::CSpeechSynthesizer::CreateSynthesizerObject(void) Unknown
Windows.Media.SpeechSynthesis.dll!Windows::Media::SpeechSynthesis::CSpeechSynthesizer::RuntimeClassInitialize(void) Unknown
Windows.Media.SpeechSynthesis.dll!Microsoft::WRL::Details::MakeAndInitialize<class Windows::Media::SpeechSynthesis::CSpeechSynthesizer,class Windows::Media::SpeechSynthesis::CSpeechSynthesizer>(class Windows::Media::SpeechSynthesis::CSpeechSynthesizer * *) Unknown
Windows.Media.SpeechSynthesis.dll!Windows::Media::SpeechSynthesis::InstalledVoicesStatic::ActivateInstance(struct IInspectable * *) Unknown

Its really weird that the error seems to be escaping the try/catch block. This is only on one customer's machine

Any ideas what is happening?


Solution

  • I believe that your customer has bad data in the registry key HKEY_LOCAL_MACHINE\SOFTWARE\MICROSOFT\Speech\Voices\Tokens, which is where SAPI stores the information about what voices are installed on the system.

    Clearly, some keys are present (given that the code is trying to add a token from the registry key), but the values are corrupt, causing the AV in the native code.

    Other areas to check (if applicable to your system) would be:

    • HKEY_CURRENT_USER\SOFTWARE\MICROSOFT\Speech\Voices\Tokens
    • HKEY_LOCAL_MACHINE\WOW6432Node\SOFTWARE\MICROSOFT\Speech\Voices\Tokens
    • HKEY_CURRENT_USER\WOW6432Node\SOFTWARE\MICROSOFT\Speech\Voices\Tokens