2

我正在编写一个应用程序来修改另一个应用程序的音量并使用CoreAudioApidll 来执行此操作。以下代码块在主线程上完美运行,但在单独的线程中调用时,InvalidCastException会引发 an。如果这只是两个线程试图访问同一资源的问题,我投入了一个互斥锁,但情况似乎并非如此。关于问题可能是什么的任何想法?作为一个新的 C# 程序员,我很难过。我阅读了其他问题,其中建议只有主线程可以访问 COM 对象,例如 CoreAudioApi,所以我需要向主线程发送某种消息。如果这是正确的,那么最好的方法是什么?

异常(发生在第一个 Math.abs if 语句上):

Unable to cast COM object of type 'System.__ComObject' to interface type 'CoreAudioApi.Interfaces.IMMDevice'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{D666063F-1587-4E43-81F1-B948E807363F}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).

代码:

muteSoundMutex.WaitOne();
AudioSessionControl sASC = sInfo.getSAudioSession();
if (Math.Abs(sASC.SimpleAudioVolume.MasterVolume -
      (0.05f / defaultDevice.AudioEndpointVolume.MasterVolumeLevelScalar)) < 0.0001 
    && savedVol > 0)
{
   ... // other code here. all mutexes are released correctly.
4

2 回答 2

2

您的错误消息告诉您在使用IMMDevice.
根据这个规范,IMMDevice只有 4 种方法:

  • Activate
  • OpenPropertyStore
  • GetId
  • GetState

您提供的代码没有提及这些方法,因此您误解了错误发生在哪里,或者这是您的应用程序引发的内部错误。

我认为这是从您的设备获取卷期间的内部错误。

如果这个错误发生在sASC.SimpleAudioVolume.MasterVolumeordefaultDevice.AudioEndpointVolume.MasterVolumeLevelScalar中,那么这个错误是因为代码运行到后台模式。否则,请为您的异常添加一些代码和堆栈跟踪。

在设备的方法E_NOINTERFACE期间可能会出现错误代码错误。Activate所以你需要在你的主线程中调用这个方法来激活设备,然后尝试在你的后台模式中使用它。无法提供任何示例代码,抱歉。

于 2012-12-25T10:49:44.520 回答
0

我的应用程序抛出了这个异常。我已经收集了一些关于这个的见解。

  • COM 对象要求所有线程运行
  • 如果您尝试从另一个线程运行此对象,请确保该线程正在运行
  • 如果您的程序正在运行STAThread并且您正在将此 COM 对象用于一个Task或另一个Thread,那么它将抛出这样的异常。

所以请确保您的程序MTAThread在使用 COM 对象时Task正在运行Thread

希望这可以帮助。

谢谢你。

于 2020-06-07T18:59:12.510 回答