我正在编写一个应用程序来修改另一个应用程序的音量,并使用 CoreAudioApi
dll 来执行此操作。以下代码块在主线程上运行良好,但在单独的线程中调用时,会引发 InvalidCastException
。我加入了一个 Mutex,以防这只是两个线程试图访问同一资源的问题,但事实并非如此。关于问题可能是什么的任何想法?作为一名新的 C# 程序员,我感到很困惑。我阅读了其他问题,其中建议只有主线程才能访问 COM 对象,例如 CoreAudioApi,因此我需要向主线程发送某种消息。如果这是正确的,那么最好的方法是什么?
异常(发生在第一个 Math.abs if 语句上):
无法将类型为“System.__ComObject”的 COM 对象转换为接口(interface)类型“CoreAudioApi.Interfaces.IMMDevice”。此操作失败,因为 IID 为“{D666063F-1587-4E43-81F1-B948E807363F}”的接口(interface)的 COM 组件上的 QueryInterface 调用因以下错误而失败:不支持此类接口(interface)(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.
最佳答案
您的错误消息告诉您在使用 IMMDevice
进行某些操作时发生了转换错误。
根据this规范,IMMDevice
只有 4 个方法:
激活
OpenPropertyStore
GetId
获取状态
您提供的代码没有提及这些方法,因此您可能误解了错误发生的位置,或者这是您的应用程序引发的内部错误。
我认为这是从您的设备获取 Volume 时的内部错误。
如果此错误发生在 sASC.SimpleAudioVolume.MasterVolume
或 defaultDevice.AudioEndpointVolume.MasterVolumeLevelScalar
中,则此错误是因为代码正在运行进入后台模式。否则,请为您的异常添加一些代码和堆栈跟踪。
错误代码为 E_NOINTERFACE
的错误可能会在 Activate
期间发生设备的方法。所以你需要在你的主线程中调用这个方法来激活设备,然后尝试在你的后台模式中使用它。无法提供任何示例代码,抱歉。
关于c# - 带线程的 CoreAudioApi - InvalidCastException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14020232/