2010-06-18 66 views
2

我正在開發一個VB.NET Windows服務,它正在審覈BMS數據庫中的新警報,並打電話遠程警告操作員。我目前使用的是.NET TAPI封裝和SAPI 5.3互操作程序集,並且我正在通過電話說話的步驟如下:通過調制解調器從Windows服務播放語音

  1. 初始化TAPI接口;
  2. 撥打運營商號碼;
  3. 取語音調制解調器波形輸出設備編號
  4. 將語音輸出設置爲該設備編號;
  5. 讓SAPI發揮神奇功效。

如果我將代碼編譯爲Windows控制檯或表單應用程序,但只要將它編譯並作爲Windows服務運行,第5步就不會發生 - 語音調制解調器調用但保持靜音;一切工作,甚至數字監控。 現在我知道windows服務不應該與桌面交互,所以諸如UI元素和播放聲音之類的東西是否定的,但我正在努力尋找一種不涉及使用wave API的替代方案,並且可以在合理的時間內開發。有任何想法嗎?

回答

0

SAPI通常需要某種類型的消息泵和窗口句柄,而這些Windows服務通常不具有。您可以創建一個message-only window以稍微安全的方式處理這些消息(請注意,服務中的任何hwnd都會爲您打開一個shatter attack,因此請確保您以用戶的身份運行服務,而不是SYSTEM或LocalMachine減少攻擊面)。您還需要抽取消息(通過Application.Run或Application.DoEvents等)。

+0

該服務現在在啓動時創建一個消息窗口,如你所建議的。現在我該怎麼做?我如何告訴SAPI使用該窗口的句柄?一旦窗口創建或稍後再啓動消息循環?謝謝你的幫助。 – Samuele 2010-06-23 10:49:24

+0

通常情況下,您需要啓動一個線程,該線程除了泵送消息外(並且知道何時關閉)。 SAPI是自由線程的,因此您可以跨線程傳遞SAPI接口指針而不會出現任何問題。 – 2010-06-23 16:52:46

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按預期工作。我認爲這不是最簡單的方法來完成,但我有點時間:)