Array
(
)

Detecção de retirada/inseção de fones usb

Rafael Iriya
   - 29 mar 2011

Estou tentando fazer com que meu codigo detecte quando um fone de ouvido usb é retirado ou inserido na maquina. Estou sobrecarregando o metodo WndProc do form e tratando as mensagens do tipo WM_DEVICECHANGE com wparam = DBT_DEVICEARRIVAL e DBT_DEVICEREMOVECOMPLETE e lparam = DBT_DEVTYP_DEVICEINTERFACE. Essa notificação está funcionando OK. O problema é que o tipo DBT_DEVTYP_DEVICEINTERFACE não faz distinção se o dispositivo é um fone de ouvido ou um mouse, teclado etc. Portanto, estou tentando ir na classe System.Management para detectar as placas de som disponiveis. Criei um metodo para verificar se existe pelo menos uma placa disponivel, e este método está funcionando normalmente quando chamado diretamente. Entretanto, quando o método é chamado por dentro do metodo WndProc, como resposta a uma mensagem do windows, aparece a seguinte mensagem:

O conteúdo 0x136790 está desconectado. Nenhum proxy será usado para atender à solicitação no componente COM. Isso poderá causar danos ou perda de dados. Para evitar esse problema, certifique-se de que todos os contexts/apartments estejam ativos até que o aplicativo conclua totalmente o RuntimeCallableWrappers que representa os componentes COM que estão dentro deles.

E em seguida a exceção: ManagementException was unhandled: O aplicativo chamou uma interface empacotada para um outro thread.

Seguem os techos do código:

 
#Código

  public void WndProc(ref Message m)

        {
            int devType;
                  
            if (m.Msg == Win32.WM_DEVICECHANGE)
            {           
                int wparam = m.WParam.ToInt32();
                switch (wparam)

                {

                    case Win32.DBT_DEVICEARRIVAL:

                        devType = Marshal.ReadInt32(m.LParam, 4);
                        if (devType == Win32.DBT_DEVTYP_DEVICEINTERFACE)

                        {                            
                            if (verifyAudioDevices())
                            {
                                //ToDo
                            }

                        }
                        break;

                      case Win32.DBT_DEVICEREMOVECOMPLETE:

                        devType = Marshal.ReadInt32(m.LParam, 4);
                        if (devType == Win32.DBT_DEVTYP_DEVICEINTERFACE)

                        {
                            if (verifyAudioDevices())
                            {
                                //ToDo
                            }
                        }

                        break;
                }
            }
        }

     private bool verifyAudioDevices()
        {
            ManagementObjectSearcher mo = new ManagementObjectSearcher("select * from Win32_SoundDevice");


            int audioDevices = mo.Get().Count;

            foreach (ManagementObject soundDevice in mo.Get())
            {
                string deviceId = soundDevice.GetPropertyValue("DeviceId").ToString();

                string name = soundDevice.GetPropertyValue("Name").ToString();
            }

            if (audioDevices > 0)
            {
                return true;
            }


            return false;
        }



 O erro acontece na chamada do metodo mo.Get(). Alguem saberia resolver esta questão ou em outro extremo, uma outra solução para a detecção de dispositivos de áudio usb?

Obrigado!