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" );
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.
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:
User contributions licensed under CC BY-SA 3.0