Simple text to speech with SAPI in a Windows Service

1

Why does the following code fail after Speak() with error code 0x80045063 (SPERR_NOT_ACTIVE_SESSION) only when the process is running as a service?

ISpVoicePtr pVoice;
CoCreateInstance(
    CLSID_SpVoice,
    0,
    CLSCTX_INPROC_SERVER,
    IID_ISpVoice, ( LPVOID * ) &pVoice
);

pVoice->SetOutput( 0, TRUE );
pVoice->Speak( L"Hello", 0, NULL );

The only resources I can come up with talk about security changes to services interacting with desktop sessions. The following in .NET will work within a service so I'm just curious as to how it would be accomplished using plain C++ with or without SAPI.

System::Speech::Synthesis::SpeechSynthesizer synth;
synth.SetOutputToDefaultAudioDevice();
synth.Speak( "Hello" );
c++
sapi
asked on Stack Overflow Jun 18, 2014 by hpl • edited Jun 18, 2014 by hpl

1 Answer

2

The SAPI documentation lists SPERR_NOT_ACTIVE_SESSION as

Neither audio output nor input is supported for non-active console sessions.

A service runs in a background session. Due to Session 0 Isolation introduced in Vista, a service does not have access to Interactive resources, which includes Text-To-Speech.

Googling around, I found a couple of comments to back up that claim:

http://www.ip-symcon.de/en/service/documentation/module-reference/text-to-speech/tts-speak/

This function does not work under Windows __ Vista/2003__ or newer. This is because services such as IP-Symcon, for security reasons, can not access interactive components in the system. The Text To Speech output is such an interactive component. The problem manifests itself with the error message: __ OLE error 80045063__ extract MSDN: SPERR_NOT_ACTIVE_SESSION.

http://www.tech-archive.net/Archive/Development/microsoft.public.win32.programmer.tapi/2009-06/msg00003.html

Note that they broke ( deliberately I think ) this stuff beginning on Vista (and later). If you try to use SAPI's ISpMMSysAudio interface in a service (as they sketch in their bullet points in your link above), sooner or later you'll see a SPERR_NOT_ACTIVE_SESSION error.

As for SpeechSynthesizer, my guess would be that it does not use SAPI internally. The source code for SpeechSynthesizer is available here:

SpeechSynthesizer.cs

VoiceSynthesis.cs

answered on Stack Overflow Jun 18, 2014 by Remy Lebeau • edited Jun 18, 2014 by Remy Lebeau

User contributions licensed under CC BY-SA 3.0