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

C#修改自身进程音量遇访问权限问题,求可行替代方案

解决C#修改自身进程音量的问题

你遇到的ISimpleAudioVolume、IAudioSessionEnumerator等接口无法访问的问题,核心原因是这些Windows音频会话的COM接口没有在代码中显式定义为public,或者你没有包含完整的接口定义代码。下面提供两种可行的解决方案:


方案一:原生Windows API实现(无第三方依赖)

首先需要把所有用到的COM接口、枚举都显式定义为public,保证代码能正常访问:

using System;
using System.Runtime.InteropServices;
using System.Diagnostics;

// 音频设备流向枚举
public enum EDataFlow
{
    eRender,
    eCapture,
    eAll,
    EDataFlow_enum_count
}

// 音频角色枚举
public enum ERole
{
    eConsole,
    eMultimedia,
    eCommunications,
    ERole_enum_count
}

// 设备枚举器接口
[Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IMMDeviceEnumerator
{
    void NotImpl1();
    void GetDefaultAudioEndpoint(EDataFlow dataFlow, ERole role, out IMMDevice ppDevice);
}

// 音频设备接口
[Guid("D666063F-1587-4E43-81F1-B948E807363F")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IMMDevice
{
    void Activate(ref Guid iid, int dwClsCtx, IntPtr pActivationParams, out object ppInterface);
}

// 音频会话管理器接口
[Guid("77AA99A0-1BD6-484F-8BC7-2C654C9A9B6F")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IAudioSessionManager2
{
    void NotImpl1();
    void NotImpl2();
    void GetSessionEnumerator(out IAudioSessionEnumerator SessionEnum);
}

// 音频会话枚举器接口
[Guid("E2F5BB11-0570-40CA-ACDD-3AA01277DEE8")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IAudioSessionEnumerator
{
    void GetCount(out int SessionCount);
    void GetSession(int SessionCount, out IAudioSessionControl Session);
}

// 音频会话控制接口
[Guid("F4B1A599-7266-4319-A8CA-E70ACB11E8CD")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IAudioSessionControl
{
    void NotImpl1();
    void GetDisplayName(out string pRetVal);
}

// 扩展音频会话控制接口(用于获取进程ID)
[Guid("bfb7ff88-7239-4fc9-8fa2-07c950be9c6d")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IAudioSessionControl2 : IAudioSessionControl
{
    new void NotImpl1();
    new void GetDisplayName(out string pRetVal);
    void GetProcessId(out uint pRetVal);
}

// 音量控制接口
[Guid("87CE5498-68D6-44E5-9215-6DA47EF883D8")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ISimpleAudioVolume
{
    void SetMasterVolume(float fLevel, ref Guid EventContext);
    void GetMasterVolume(out float pfLevel);
    void SetMute(bool bMute, ref Guid EventContext);
    void GetMute(out bool pbMute);
}

// 设备枚举器COM类
[ComImport]
[Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")]
public class MMDeviceEnumerator
{
}

// 修改自身进程音量的核心方法
public static void SetSelfApplicationVolume(float level)
{
    int currentPid = Process.GetCurrentProcess().Id;
    ISimpleAudioVolume volume = GetVolumeObject(currentPid);
    if (volume == null)
        return;

    Guid guid = Guid.Empty;
    volume.SetMasterVolume(level / 100, ref guid);
}

private static ISimpleAudioVolume GetVolumeObject(int processId)
{
    IMMDeviceEnumerator deviceEnumerator = (IMMDeviceEnumerator)new MMDeviceEnumerator();
    IMMDevice speakers;
    deviceEnumerator.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia, out speakers);

    Guid IID_IAudioSessionManager2 = typeof(IAudioSessionManager2).GUID;
    object o;
    speakers.Activate(ref IID_IAudioSessionManager2, 0, IntPtr.Zero, out o);
    IAudioSessionManager2 mgr = (IAudioSessionManager2)o;

    IAudioSessionEnumerator sessionEnumerator;
    mgr.GetSessionEnumerator(out sessionEnumerator);
    int count;
    sessionEnumerator.GetCount(out count);

    ISimpleAudioVolume volumeControl = null;
    for (int i = 0; i < count; i++)
    {
        IAudioSessionControl ctl;
        sessionEnumerator.GetSession(i, out ctl);
        IAudioSessionControl2 ctl2 = ctl as IAudioSessionControl2;
        if (ctl2 != null)
        {
            uint pid;
            ctl2.GetProcessId(out pid);
            if (pid == processId)
            {
                volumeControl = ctl as ISimpleAudioVolume;
                break;
            }
        }
        Marshal.ReleaseComObject(ctl);
    }

    Marshal.ReleaseComObject(sessionEnumerator);
    Marshal.ReleaseComObject(mgr);
    Marshal.ReleaseComObject(speakers);
    Marshal.ReleaseComObject(deviceEnumerator);
    return volumeControl;
}

调用示例:

// 设置自身进程音量为50%
SetSelfApplicationVolume(50);

方案二:使用NAudio库(更简洁)

NAudio是封装了Windows音频API的开源库,能大幅简化代码:

  1. 先通过NuGet安装NAudio包;
  2. 使用以下代码修改自身进程音量:
using NAudio.CoreAudioApi;
using System.Diagnostics;

public static void SetSelfVolume(float level)
{
    using (var sessionManager = new AudioSessionManager2())
    {
        foreach (var session in sessionManager.Sessions)
        {
            if (session.ProcessID == Process.GetCurrentProcess().Id)
            {
                session.SimpleAudioVolume.Volume = level / 100;
                break;
            }
        }
    }
}

调用示例:

// 设置自身进程音量为30%
SetSelfVolume(30);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 04:10:27