Custom Windows Service Accessing Audio Devices - Not working across users. RRS feed

  • Question

  • Hello, I have two users on my computer, and I want my custom service to run and play audio for each user. It basically listens for MQTT messages and processes them. I've verified that the service is processing messages when the second user signs in (visible in the event logs), however, the actual audio is not playing and there are no errors in the event log. I installed the service using the first account. It is the second account that is not working but when I installed it I installed the service on the local system - not on the local user so that should not be the issue, right?

    Imports System.Net
    Imports System.Text
    Imports uPLibrary.Networking.M2Mqtt
    Imports uPLibrary.Networking.M2Mqtt.Messages
    Imports Newtonsoft.Json
    Imports System.Runtime.InteropServices
    Public Enum ServiceState
        SERVICE_PAUSED = 7
    End Enum
    Public Structure ServiceStatus
        Public dwServiceType As Integer
        Public dwCurrentState As ServiceState
        Public dwControlsAccepted As Integer
        Public dwWin32ExitCode As Integer
        Public dwServiceSpecificExitCode As Integer
        Public dwCheckPoint As Integer
        Public dwWaitHint As Integer
    End Structure
    Public Class mqttListenService
        Private eventLog1 As System.Diagnostics.EventLog
        Private _Started As Boolean = False
        Public Property Started As Boolean
                Return _Started
            End Get
            Set(value As Boolean)
                _Started = value
            End Set
        End Property
        Private client As MqttClient
        Public Sub New()
            ' This call is required by the designer.
            ' Add any initialization after the InitializeComponent() call.
            Me.eventLog1 = New System.Diagnostics.EventLog()
            Dim sourceName As String = "MQTTListenService"
            Dim logName As String = "MQTTListenServiceLog"
            If Not (System.Diagnostics.EventLog.SourceExists(sourceName)) Then
                System.Diagnostics.EventLog.CreateEventSource(sourceName, logName)
            End If
            eventLog1.Source = sourceName
        End Sub
        <DllImport("advapi32.dll", SetLastError:=True)>
        Private Shared Function SetServiceStatus(ByVal handle As IntPtr, ByRef serviceStatus As ServiceStatus) As Boolean
        End Function
        Protected Overrides Sub OnStart(ByVal args() As String)
            ' Add code here to start your service. This method should set things
            ' in motion so your service can do its work.
            ' Update the service state to Start Pending.  
            Dim serviceStatus As New ServiceStatus()
            serviceStatus.dwCurrentState = ServiceState.SERVICE_START_PENDING
            ServiceStatus.dwWaitHint = 100000
            SetServiceStatus(Me.ServiceHandle, serviceStatus)
            Me.eventLog1.WriteEntry("MQTT Listen Service Started", EventLogEntryType.Information)
            ' the mqtt broker is the same as the node-red
            ' server.
            Dim mqqt_broker_address As String = ""
            Dim device_name As String = "COMPUTER-1"
            ' create client instance
            Me.client = New MqttClient(IPAddress.Parse(mqqt_broker_address))
            ' register to message received
            AddHandler client.MqttMsgPublishReceived, AddressOf client_MqttMsgPublishReceived
            Dim clientId As String = Guid.NewGuid().ToString()
            Me.eventLog1.WriteEntry("Connected and subcribing to topic <" & device_name & ">", EventLogEntryType.Information)
            ' subscribe to the topic "/home/temperature" with QoS 2
            client.Subscribe(New String() {device_name}, New Byte() {MqttMsgBase.QOS_LEVEL_EXACTLY_ONCE})
            Me.eventLog1.WriteEntry("Subscribed. Waiting for messages.", EventLogEntryType.Information)
            serviceStatus.dwCurrentState = ServiceState.SERVICE_RUNNING
            SetServiceStatus(Me.ServiceHandle, serviceStatus)
        End Sub
        Protected Overrides Sub OnStop()
            ' Add code here to perform any tear-down necessary to stop your service.
            ' disconnect the client
            ' get rid of the client in memory
            Me.client = Nothing
            ' log the event
            Me.eventLog1.WriteEntry("MQTT Listen Service Stopped", EventLogEntryType.Information)
        End Sub
        Private Sub client_MqttMsgPublishReceived(sender As Object, e As MqttMsgPublishEventArgs)
            ' handle message received
            ' this will have two things associated with it,
            ' command
            ' parameter
            Dim topic As String = e.Topic
            Dim message As String = Encoding.UTF8.GetString(e.Message)
            eventLog1.WriteEntry("message received topic <" & topic & "> message <" & message & ">", EventLogEntryType.Information)
            Dim msg_dict As Dictionary(Of String, String)
                msg_dict = JsonConvert.DeserializeObject(Of Dictionary(Of String, String))(message)
            Catch ex As Exception
                eventLog1.WriteEntry("message deserialization error <" & ex.Message & ">", EventLogEntryType.Error)
            End Try
        End Sub
        Private Sub ProcessCommand(ByVal theCommandMessage As Dictionary(Of String, String))
            Dim commandString As String = theCommandMessage("command")
            Dim commandParameter As String = theCommandMessage("parameter")
            Dim windows_file_path As String = commandParameter.Replace("//", "\")
            Select Case commandString
                Case "PLAY"
                    ' in this command the parameter should point to the location for the audio file
                    eventLog1.WriteEntry("processed command, playing audio file " & windows_file_path, EventLogEntryType.Information)
                    Catch ex As Exception
                        eventLog1.WriteEntry("audio play error " & ex.Message, EventLogEntryType.Error)
                    End Try
            End Select
        End Sub
    End Class


    • Edited by neech16 Sunday, January 7, 2018 9:33 PM
    • Moved by Hart Wang Friday, January 19, 2018 1:21 AM
    Sunday, January 7, 2018 9:32 PM

All replies

  • Hi,

    Thank you for posting here.

    Did you get other error message or exception? Did you try to debug your code?

    As far as i know that the MQTT belongs to the third product, you could consult their support website.  i will move the case to off-topic forum. 


    Best  Regards,


    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, January 8, 2018 7:40 AM
  • Hart,

    Thanks for your reply. In digging further on this, I think it may be a result of a third party software application locking down the audio system. Probably KODI, maybe even chrome. Is there any way to do the same in the .NET framework? I want to take control back to my service when the MQTT event fires then release it when the audio is done playing.

    I am not having problems with the MQTT objects, the line of code that is/was not working is the My.Computer.Audio.Play() call.



    Monday, January 8, 2018 2:44 PM
  • Hi neech16,

    Thank you for your feedback.

    i am not sure what the MQTT is, if you just use the library to fire and release event. inside .NET framework, you could use the delegate to do this.

    Events and Delegates - MSDN - Microsoft

    Best Regards,


    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, January 10, 2018 8:27 AM