如何在C#中设置Windows10/11默认麦克风设备(非PowerShell方案)
在C#中设置Windows默认麦克风设备(无需PowerShell)
winmm.dll中不存在waveInSetDefault API,要设置默认音频输入设备,需借助Windows Core Audio API(MMDeviceAPI),通过COM互操作实现,无需依赖PowerShell。以下是完整的C#实现方案:
核心COM接口与枚举定义
这些定义对应Windows Core Audio的原生接口,用于设备枚举和默认设置操作:
using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Linq; // Core Audio API 相关COM类与接口 [ComImport] [Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")] internal class MMDeviceEnumerator { } [Guid("A95664D2-9614-4F35-A746-DE8DB63617E6")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] internal interface IMMDeviceEnumerator { void NotImpl1(); int GetDefaultAudioEndpoint(EDataFlow dataFlow, ERole role, out IMMDevice ppDevice); int EnumAudioEndpoints(EDataFlow dataFlow, EDeviceState stateMask, out IMMDeviceCollection ppDevices); } [Guid("0BD7A1BE-7A1A-44DB-8397-CC5392387B5E")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] internal interface IMMDeviceCollection { int GetCount(out uint pcDevices); int Item(uint nDevice, out IMMDevice ppDevice); } [Guid("D666063F-1587-4E43-81F1-B948E807363F")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] internal interface IMMDevice { int Activate(ref Guid iid, int dwClsCtx, IntPtr pActivationParams, out IntPtr ppInterface); int OpenPropertyStore(int stgmAccess, out IPropertyStore ppProperties); int GetId(out IntPtr ppstrId); int GetState(out uint pdwState); } [Guid("886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] internal interface IPropertyStore { int GetCount(out uint cProps); int GetAt(uint iProp, out PropertyKey pkey); int GetValue(ref PropertyKey key, out PropVariant pv); int SetValue(ref PropertyKey key, ref PropVariant pv); int Commit(); } // 设置默认设备的核心接口 [Guid("1BE09788-6894-4089-8586-9A2A6C265AC5")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] internal interface IPolicyConfig { int NotImpl1(); int NotImpl2(); int SetDefaultEndpoint(string pszDeviceId, ERole role); } [ComImport] [Guid("870AF99C-171D-4F9E-AF0D-E63DF40C2BC9")] internal class PolicyConfigClient { } // 枚举定义 internal enum EDataFlow { eRender, eCapture, eAll, } internal enum ERole { eConsole, eMultimedia, eCommunications, } internal enum EDeviceState { Active = 0x00000001, Disabled = 0x00000002, NotPresent = 0x00000004, Unplugged = 0x00000008, All = 0x0000000F, } // 辅助结构体 [StructLayout(LayoutKind.Sequential)] internal struct PropertyKey { public Guid fmtid; public uint pid; } [StructLayout(LayoutKind.Explicit)] internal struct PropVariant { [FieldOffset(0)] private ushort vt; [FieldOffset(8)] private IntPtr pwszVal; public string StringValue => Marshal.PtrToStringUni(pwszVal); }
设备管理工具类
封装设备枚举和默认设置的方法:
public static class AudioDeviceManager { // 获取所有活跃的麦克风设备 public static List<(string Id, string Name)> GetAllActiveMicrophones() { var devices = new List<(string, string)>(); var enumerator = (IMMDeviceEnumerator)new MMDeviceEnumerator(); try { enumerator.EnumAudioEndpoints(EDataFlow.eCapture, EDeviceState.Active, out var deviceCollection); deviceCollection.GetCount(out uint count); for (uint i = 0; i < count; i++) { deviceCollection.Item(i, out var device); device.GetId(out IntPtr idPtr); string deviceId = Marshal.PtrToStringUni(idPtr); Marshal.FreeCoTaskMem(idPtr); device.OpenPropertyStore(0, out var props); var nameKey = new PropertyKey { fmtid = new Guid("A45C254E-DF1C-4EFD-8020-67D146A850E0"), // PKEY_Device_FriendlyName pid = 14 }; props.GetValue(ref nameKey, out var nameVar); string deviceName = nameVar.StringValue; devices.Add((deviceId, deviceName)); Marshal.ReleaseComObject(props); Marshal.ReleaseComObject(device); } Marshal.ReleaseComObject(deviceCollection); } finally { Marshal.ReleaseComObject(enumerator); } return devices; } // 根据设备名称模糊匹配设置默认麦克风 public static bool SetDefaultMicrophone(string deviceNameMatch) { var microphones = GetAllActiveMicrophones(); var targetMic = microphones.FirstOrDefault(m => m.Name.Contains(deviceNameMatch, StringComparison.OrdinalIgnoreCase)); if (targetMic.Equals(default)) return false; var policyConfig = (IPolicyConfig)new PolicyConfigClient(); try { // 同时设置多媒体默认和通信默认设备 policyConfig.SetDefaultEndpoint(targetMic.Id, ERole.eMultimedia); policyConfig.SetDefaultEndpoint(targetMic.Id, ERole.eCommunications); return true; } finally { Marshal.ReleaseComObject(policyConfig); } } }
调用示例
// 设置名称包含"Mic"的设备为默认麦克风 bool success = AudioDeviceManager.SetDefaultMicrophone("Mic"); if (success) { Console.WriteLine("默认麦克风设置成功"); } else { Console.WriteLine("未找到匹配的麦克风设备"); }
关键说明
ERole.eMultimedia对应系统"默认设备",ERole.eCommunications对应"默认通信设备",通常需要同时设置两者- 设备名称匹配采用模糊匹配,可根据需求调整为精确匹配
- 所有COM对象使用后需调用
Marshal.ReleaseComObject释放,避免内存泄漏 - 项目需设置为x64或x86平台,AnyCPU模式可能出现COM互操作异常
内容的提问来源于stack exchange,提问作者Kevin
相关产品推荐
相关产品推荐

