You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VB .Net 2015实现系统音频检测遇COM互操作错误求助

解决VB.NET音频检测的COM封送错误

你的代码出现"无效VARIANT"转换错误,根源是两处COM互操作的定义错误,以下是修正后的完整代码:

Imports System.Runtime.InteropServices

Namespace Foo
    Public Class Bar
        <ComImport, Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")>
        Private Class MMDeviceEnumerator
        End Class

        Public Shared Function IsWindowsPlayingSound() As Boolean
            Dim enumerator As IMMDeviceEnumerator = DirectCast(New MMDeviceEnumerator(), IMMDeviceEnumerator)
            Dim speakers As IMMDevice = enumerator.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia)
            Dim meter As IAudioMeterInformation = DirectCast(speakers.Activate(GetType(IAudioMeterInformation).GUID, 0, IntPtr.Zero), IAudioMeterInformation)
            Dim value As Single = meter.GetPeakValue()

            ' 阈值可根据实际场景调整,1E-08对应0.00000001
            Return value > 0.00000001
        End Function

        Private Enum EDataFlow
            eRender
            eCapture
            eAll
        End Enum

        Private Enum ERole
            eConsole
            eMultimedia
            eCommunications
        End Enum

        <InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("A95664D2-9614-4F35-A746-DE8DB63617E6")>
        Private Interface IMMDeviceEnumerator
            Sub NotNeeded()
            Function GetDefaultAudioEndpoint(dataFlow As EDataFlow, role As ERole) As IMMDevice
        End Interface

        <InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("D666063F-1587-4E43-81F1-B948E807363F")>
        Private Interface IMMDevice
            <return: MarshalAs(UnmanagedType.IUnknown)>
            Function Activate(<MarshalAs(UnmanagedType.LPStruct)> iid As Guid, dwClsCtx As Integer, pActivationParams As IntPtr) As Object
        End Interface

        <InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("C02216F6-8C67-4B5B-9D00-D008E73E0064")>
        Private Interface IAudioMeterInformation
            Function GetPeakValue() As Single
        End Interface
    End Class
End Namespace

Public Class Form1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim isPlaying As Boolean = Foo.Bar.IsWindowsPlayingSound()
        MessageBox.Show(If(isPlaying, "系统正在播放音频", "系统未播放音频"))
    End Sub
End Class

关键修改说明:

  1. 修复IMMDevice.Activate的封送特性:
    为Activate方法的返回值添加<return: MarshalAs(UnmanagedType.IUnknown)>,告诉CLR将COM返回的IUnknown接口正确转换为托管对象,解决VARIANT转换错误。

  2. 修正IAudioMeterInformation.GetPeakValue的返回类型:
    将返回类型从String改为Single,与C#代码中的float对应,确保音频峰值的数值类型正确匹配。

  3. 优化调用示例:
    在按钮点击事件中添加了结果提示,方便测试功能是否正常工作。

内容的提问来源于stack exchange,提问作者Satrap

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 01:50:57