从Windows服务播放调制解调器语音

时间:2010-06-18 15:53:46

标签: vb.net windows-services sapi tapi

我正在开发一个VB.NET Windows服务,该服务常常检查BMS数据库是否有新的警报并拨打电话以远程警告操作员。我目前正在使用.NET TAPI包装器和SAPI 5.3互操作程序集,我通过电话讲的步骤是:

  1. 初始化TAPI接口;
  2. 拨打运营商号码;
  3. 使用语音调制解调器waveOut设备ID
  4. 将语音输出设置为该设备ID;
  5. 让SAPI发挥魔力。
  6. 如果我将代码编译为Windows控制台或表单应用程序,这一切都正常工作,但是一旦我编译并将其作为Windows服务运行,第5步就不会发生 - 语音调制解调器调用但保持沉默;其他一切工作,甚至数字监控。 现在我知道Windows服务不应该与桌面交互,所以像UI元素和播放声音之类的东西是禁止的,但是我很难找到一个不涉及使用wave API并且可以开发的替代方案在合理的时间范围内。有任何想法吗?

2 个答案:

答案 0 :(得分:0)

SAPI通常需要某种消息泵和窗口句柄,Windows服务通常没有。您可以创建message-only window以稍微更安全的方式处理邮件(请注意,服务中的任何hwnd都会向您开放shatter attack,因此请确保您以用户身份运行服务,而不是作为SYSTEM或LocalMachine来减少攻击面)。您还需要提取消息(通过Application。运行或Application.DoEvents等)。

答案 1 :(得分:0)

我最终在Windows服务项目中引用了Windows窗体项目,并在OnStart子窗口中创建了窗体:

Protected Overrides Sub OnStart(ByVal args() As String)
        HelperThread = New Threading.Thread(AddressOf CreateMOWindow)
        HelperThread.TrySetApartmentState(Threading.ApartmentState.STA)
        HelperThread.Start()
End Sub 

Private Sub CreateMOWindow()
        Dim frm As New AlarmVoiceTest.AlarmVoiceTest
        Windows.Forms.Application.Run(frm)
End Sub

表单当然没有显示(但我不需要它),并且SAPI按预期工作。我认为这不是实现这一目标的最简洁的方法,但我有点没时间了:))