admin管理员组文章数量:1246770
I've been working on a C# application that interfaces with the Windows Audio APIs to check the processes used by the primary render device. However, I keep encountering an issue where the call to sessionManager.GetSessionEnumerator
always fails with an AccessViolationException
. Here's the relevant part of my code:
using System;
using System.Runtime.InteropServices;
namespace SystemAudio
{
public static class AudioChecker
{
static void Main()
{
int sessionCount;
sessionCount = CheckPrimaryRenderDeviceProcesses();
Console.WriteLine(sessionCount);
}
public static int CheckPrimaryRenderDeviceProcesses()
{
IMMDeviceEnumerator enumerator = (IMMDeviceEnumerator)new MMDeviceEnumerator();
IMMDevice device;
enumerator.GetDefaultAudioEndpoint(0, 0, out device);
string id;
device.GetId(out id);
Console.WriteLine("Primary Render Device ID: " + id);
// Activate IAudioSessionManager2 on the device (also tested with IAudioSessionManager)
Guid IID_IAudioSessionManager2 = new Guid("77AA99A0-1BD6-484F-8BC7-2C654C9A9B6F");
int CLSCTX_ALL = 23;
device.Activate(ref IID_IAudioSessionManager2, CLSCTX_ALL, IntPtr.Zero, out object oSessionManager);
IAudioSessionManager2 sessionManager = (IAudioSessionManager2)oSessionManager;
// Attempt to get the session enumerator.
// This is ALWAYS failing with these error:
// System.AccessViolationException:
// 'Attempted to read or write protected memory. This is often an indication that other memory is corrupt.'
sessionManager.GetSessionEnumerator(out IAudioSessionEnumerator sessionEnumerator);
sessionEnumerator.GetCount(out int sessionCount);
return sessionCount;
}
}
}
And here are the COM interface definitions I'm using. For unused methods I was just listing the methods as defined in the vTable but without any parameters:
[ComImport, Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")]
public class MMDeviceEnumerator { }
[ComImport, Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IMMDeviceEnumerator
{
int EnumAudioEndpoints();
int GetDefaultAudioEndpoint(int dataFlow, int role, out IMMDevice endpoint);
int GetDevice();
int RegisterEndpointNotificationCallback();
int UnregisterEndpointNotificationCallback();
}
[ComImport, Guid("D666063F-1587-4E43-81F1-B948E807363F"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IMMDevice
{
int Activate(ref Guid iid, int dwClsCtx, IntPtr pActivationParams,
[MarshalAs(UnmanagedType.IUnknown)] out object ppInterface);
int OpenPropertyStore();
int GetId([MarshalAs(UnmanagedType.LPWStr)] out string ppstrId);
int GetState();
}
[ComImport, Guid("BFA971F1-4D5E-40BB-935E-967039BFBEE4"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IAudioSessionManager
{
int GetAudioSessionControl();
int GetSimpleAudioVolume();
}
[ComImport, Guid("77AA99A0-1BD6-484F-8BC7-2C654C9A9B6F"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IAudioSessionManager2 : IAudioSessionManager
{
int GetSessionEnumerator(out IAudioSessionEnumerator sessionEnum);
int RegisterSessionNotification();
int UnregisterSessionNotification();
int RegisterDuckNotification();
int UnregisterDuckNotification();
}
[ComImport, Guid("E2F5BB11-0570-40CA-ACDD-3AA01277DEE8"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IAudioSessionEnumerator
{
int GetCount(out int count);
int GetSession();
}
[ComImport, Guid("F4B1A599-7266-4319-A8CA-E70ACB11E8CD"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IAudioSessionControl
{
int GetState();
int GetDisplayName();
int SetDisplayName();
int GetIconPath();
int SetIconPath();
int GetGroupingParam();
int SetGroupingParam();
int RegisterAudioSessionNotification();
int UnregisterAudioSessionNotification();
}
[ComImport, Guid("bfb7ff88-7239-4fc9-8fa2-07c950be9c6d"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IAudioSessionControl2 : IAudioSessionControl
{
new int GetState();
new int GetDisplayName();
new int SetDisplayName();
new int GetIconPath();
new int SetIconPath();
new int GetGroupingParam();
new int SetGroupingParam();
new int RegisterAudioSessionNotification();
new int UnregisterAudioSessionNotification();
int GetSessionIdentifier();
int GetSessionInstanceIdentifier();
int GetProcessId();
int IsSystemSoundsSession();
int SetDuckingPreferences();
}
Despite following the documentation and the implementation details, the call to GetSessionEnumerator
fails every time with the exception:
System.AccessViolationException: 'Attempted to read or write protected memory. This is often an indication that other memory is corrupt.'
I'm not sure what's causing this issue, and it's been quite a blocker for my project. Any insights or suggestions on what might be going wrong or how to troubleshoot this further would be greatly appreciated! Thank you in advance for your help.
版权声明:本文标题:c# - Why is `sessionManager.GetSessionEnumerator` always failing with an AccessViolationException? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1740212904a2242333.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论