Playing voice over modem from a Windows service

大憨熊 提交于 2019-12-11 02:10:56

问题


I'm developing a VB.NET Windows service which is costantly checking a BMS database for new alarms and making phone calls to warn operators remotely. I'm currently using a .NET TAPI wrapper and the SAPI 5.3 interop assembly, and the steps I'm taking to speak over the phone are:

  1. Initialize TAPI interface;
  2. Make the call to the operator's number;
  3. Take the voice modem waveOut device id
  4. Set the voice output to that device id;
  5. Let SAPI do the magic.

This is all working fine if I compile the code as a Windows console or forms application, but as soon as I compile and run it as a Windows Service, step 5 never occurs - voice modem calls but stays silent; everything else works, even digit monitoring. Now I know windows services are not supposed to interact with the desktop, so things like UI elements and playing sounds are a no-no, but I'm struggling to find an alternative which doesn't involve using the wave API and can be developed in a reasonable timeframe. Any ideas?


回答1:


SAPI typically needs some sort of message pump and a window handle, which Windows services typically don't have. You could create a message-only window to handle the messages in a slightly safer manner (note that any hwnd in a service will open you up to a shatter attack, so make sure you're running your service as a user, and not as SYSTEM or LocalMachine to reduce the attack surface). You'll also need to pump the messages (via Application.Run or Application.DoEvents or the like) as well.




回答2:


I ended up referencing the windows forms project in my Windows Service project, and creating the form in the OnStart sub:

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

The form isn't showing up of course (but I don't need it to), and SAPI is working as expected. I reckon this is not the cleanest way to accomplish that, but I'm kinda running out of time :)



来源:https://stackoverflow.com/questions/3071160/playing-voice-over-modem-from-a-windows-service

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!