2

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

  1. 初始化TAPI接口;
  2. 拨打接线员号码;
  3. 取语音调制解调器 waveOut 设备 id
  4. 将语音输出设置为该设备 ID;
  5. 让 SAPI 发挥作用。

如果我将代码编译为 Windows 控制台或表单应用程序,这一切都可以正常工作,但是一旦我将其编译并作为 Windows 服务运行,步骤 5 就永远不会发生 - 语音调制解调器调用但保持沉默;其他一切正常,甚至数字监控。现在我知道 Windows 服务不应该与桌面交互,所以 UI 元素和播放声音之类的东西是不可以的,但我正在努力寻找不涉及使用 wave API 并且可以开发的替代方案在合理的时间范围内。有任何想法吗?

4

2 回答 2

0

SAPI 通常需要某种消息泵和窗口句柄,而 Windows 服务通常没有这些。您可以创建一个仅消息窗口以稍微更安全的方式处理消息(请注意,服务中的任何 hwnd 都会使您面临 shatter attack,因此请确保您以用户身份运行服务,而不是作为SYSTEM 或 LocalMachine 以减少攻击面)。您还需要泵送消息(通过Application .Run 或 Application.DoEvents 等)。

于 2010-06-21T16:11:48.747 回答
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 正在按预期工作。我认为这不是实现这一目标的最干净的方法,但我有点没时间了:)

于 2010-06-25T10:36:23.427 回答