投稿者 あせたけ  (社会人) 投稿日時 2020/10/21 20:35:37
お世話になります。
VSコミュニティ2019、Windows10の環境です。
VB.NETにてソフト開発を行っていますが、
元々音が鳴っているクラスをそのまま使用しようと思い、
実績のあるクラスを流用しています。

今回、マルチスレッドで処理させようと思い、
その部分から来た問題点だとは思っているのですが、どう解決して良いのかわかりません^^;

★元々音がなっていた作成済のアプリケーション
  ・ソフト全体がシングルスレッド

★今回音が鳴らない作成中のアプリケーション
 ・イベント処理からのマルチスレッド処理

参考ソース

呼出元
--------------------------------------------------------------------
Public Class Main
 Inhertits Sound

   Public Sub New()
   sound.sound(snd.Aleart)   '...←これは音が鳴る
 End Sub

  (~中略~)

 Private Sub OutputEventsCatch(ByVal sender As Object, ByVal e As LCEventArgs) Handles Snr.AleartEvent
     sound.sound(snd.Aleart)   '...←これが音が鳴らない…
 End Sub
End Class
--------------------------------------------------------------------

呼出先(ベースクラス:Sound)
--------------------------------------------------------------------
Public Class Sound
    Inherits File

    Private Const className As String = "Sound"

    <System.Runtime.InteropServices.DllImport("winmm.dll", CharSet:=System.Runtime.InteropServices.CharSet.Auto)>
    Private Shared Function mciSendString(ByVal command As String, ByVal buffer As System.Text.StringBuilder, ByVal bufferSize As Integer, ByVal hwndCallback As IntPtr) As Integer

    End Function

    Public Declare Function mciGetErrorString Lib "winmm.dll" Alias "mciGetErrorStringA" (ByVal fdwError As Integer, ByVal lpszErrorText As String, ByVal cchErrorText As Integer) As Integer

    ''' <summary>
    ''' 音声ファイル操作用
    ''' </summary>
    Private sound_Alert_Name As String = "Alert"
    Private sound_Warning_Name As String = "Warning"

   (~中略~)

    ''' <summary>
    ''' 音声鳴動処理
    ''' </summary>
    ''' <param name="s">音声の種類 [Enum]snd</param>
    Public Sub Sound(ByVal s As snd)
        Dim FileName As String = ""
        Dim aliasName As String = ""

        Dim Result As Integer

        If s = snd.None Then
            AleartSoundOff()
        ElseIf s = snd.Aleart Then
            FileName = sound_Alert
            aliasName = sound_Alert_Name
        ElseIf s = snd.Warning Then
            FileName = sound_Warning
            aliasName = sound_Warning_Name
        End If

        Dim cmd As String
        'ファイルを開く
        cmd = "open """ + FileName + """ type mpegvideo alias " + aliasName
        Result = mciSendString(cmd, Nothing, 0, IntPtr.Zero)
        If Result <> 0 Then
            'エラーメッセージを取得して表示します。
            Dim ErrorMessage As String = GetErrorString(Result)
            MsgBox(ErrorMessage, MsgBoxStyle.Exclamation, "Error1 " & Result)
        End If
        '再生する
        cmd = "play " + aliasName + " repeat"
        Result = mciSendString(cmd, Nothing, 0, IntPtr.Zero)
        If Result <> 0 Then
            'エラーメッセージを取得して表示します。
            Dim ErrorMessage As String = GetErrorString(Result)
            MsgBox(ErrorMessage, MsgBoxStyle.Exclamation, "Error2 " & Result)
        End If
    End Sub

    Private Sub AleartSoundOff()

        Dim cmd As String

        '停止する
        cmd = "stop all"
        mciSendString(cmd, Nothing, 0, IntPtr.Zero)
        '閉じる
        cmd = "close all"
        mciSendString(cmd, Nothing, 0, IntPtr.Zero)
    End Sub
End Class
--------------------------------------------------------------------

解決方法のヒントだけでも頂ければと思い、投稿させて頂きます。


※ 実現させたい事
 外部の(多数の)接点入力装置の情報をLCEventAugsにてイベントで入手している。
   (ここまでは正常に情報入手出来ている)
 上記の入手イベントで異常があった際(入力があった際)に音を鳴らしたい。
   (ここで音が鳴らない。上記参照)

※ mciSendString関数のエラーメッセージを確認する
https://www.umayadia.com/vbsample/dotnet-Samples151/Sample188GetErrorString.htm?pos=5900
による情報
ErrNo.266
 指定されたデバイス ドライバーの読み込み中に不明な問題が発生しました。
ErrNo.263
 指定されたデバイスが開かれていないか、または MCI で認識されません。