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

如何在C#中阻止应用音频被录制?因版权要求需完成该功能

Hey there, let's tackle this audio recording restriction for your C# app—since you're dealing with copyright concerns, I get how critical this is to implement properly. While there's no 100% foolproof way to stop all recording (like someone holding a mic up to the speaker), we can block software-level capture (think OBS, Audacity, or screen recorders) which covers most real-world cases. Here are the practical, actionable methods:

1. Use Windows Audio Session API to Disable Capture

Starting with Windows 10 1607+, Microsoft added a flag to mark an audio session as "uncapturable." This tells the OS to prevent other apps from recording your app's audio stream directly. You'll need to use P/Invoke to access the native Windows APIs from C#.

Here's a complete example to implement this:

First, define the necessary COM interfaces and constants:

using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;

[ComImport]
[Guid("77AA99A0-1BD6-484F-8BC7-2C654C9A9B6F")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IAudioSessionControl2
{
    // Inherited from IAudioSessionControl
    int GetState(out AudioSessionState state);
    int GetDisplayName(out string displayName);
    int SetDisplayName(string displayName, ref Guid eventContext);
    int GetIconPath(out string iconPath);
    int SetIconPath(string iconPath, ref Guid eventContext);
    int GetGroupingParam(out Guid groupingParam);
    int SetGroupingParam(ref Guid groupingParam, ref Guid eventContext);
    int RegisterAudioSessionNotification(IAudioSessionNotification notification);
    int UnregisterAudioSessionNotification(IAudioSessionNotification notification);

    // IAudioSessionControl2 methods
    int GetSessionIdentifier(out string sessionId);
    int GetSessionInstanceIdentifier(out string instanceId);
    int GetProcessId(out uint processId);
    int IsSystemSoundsSession();
    int SetDuckingPreference(bool enableDucking);
    int SetSessionOptions(uint options, ref Guid eventContext);
}

[ComImport]
[Guid("F4B1A599-7266-4319-A8CA-E70ACB11E8CD")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IAudioSessionManager2
{
    int GetAudioSessionEnumerator(out IAudioSessionEnumerator sessionEnumerator);
    int RegisterSessionNotification(IAudioSessionNotification notification);
    int UnregisterSessionNotification(IAudioSessionNotification notification);
    int GetSessionEnumerator(out IAudioSessionEnumerator enumerator);
    int CreateSessionEnumerator(out IAudioSessionEnumerator enumerator);
    int GetSessionControl(ref Guid sessionId, int streamFlags, out IAudioSessionControl2 sessionControl);
}

[ComImport]
[Guid("E2F5BB11-0570-40CA-ACDD-3AA01277DEE8")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IAudioSessionEnumerator
{
    int GetCount(out int count);
    int GetSession(int index, out IAudioSessionControl2 session);
}

[ComImport]
[Guid("D666063F-1587-4E43-81F1-B948E807363F")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IMMDeviceEnumerator
{
    int EnumAudioEndpoints(EDataFlow dataFlow, DEVICE_STATE stateMask, out IMMDeviceCollection devices);
    int GetDefaultAudioEndpoint(EDataFlow dataFlow, ERole role, out IMMDevice device);
}

[ComImport]
[Guid("A95664D2-9614-4F35-A746-DE8DB63617E6")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IMMDevice
{
    int Activate(ref Guid iid, int dwClsCtx, IntPtr pActivationParams, out object ppInterface);
}

internal enum AudioSessionState
{
    AudioSessionStateInactive = 0,
    AudioSessionStateActive = 1,
    AudioSessionStateExpired = 2
}

internal enum EDataFlow
{
    eRender = 0,
    eCapture = 1,
    eAll = 2
}

internal enum ERole
{
    eConsole = 0,
    eMultimedia = 1,
    eCommunications = 2
}

[Flags]
internal enum DEVICE_STATE
{
    DEVICE_STATE_ACTIVE = 0x00000001,
    DEVICE_STATE_DISABLED = 0x00000002,
    DEVICE_STATE_NOTPRESENT = 0x00000004,
    DEVICE_STATE_UNPLUGGED = 0x00000008,
    DEVICE_STATEMASK_ALL = 0x0000000F
}

internal const uint AUDIOSESSIONOPTIONS_DISABLE_CAPTURE = 0x00000001;

// Dummy interface for notification (not used here)
[ComImport]
[Guid("641DD20B-4D41-49CC-ABA3-174B9477BB08")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IAudioSessionNotification
{
    int OnSessionCreated(IAudioSessionControl2 newSession);
}

[ComImport]
[Guid("0BD7A1BE-7A1A-44DB-8397-CC5392387B5E")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IMMDeviceCollection
{
    int GetCount(out int count);
    int Item(int index, out IMMDevice device);
}

Then, add a helper method to configure your app's audio session:

public static void DisableAudioCaptureForCurrentApp()
{
    try
    {
        // Create device enumerator
        var enumeratorType = Type.GetTypeFromCLSID(new Guid("BCDE0395-E52F-467C-8E3D-C4579291692E"));
        IMMDeviceEnumerator deviceEnumerator = (IMMDeviceEnumerator)Activator.CreateInstance(enumeratorType);

        // Get default render endpoint (speakers/headphones)
        deviceEnumerator.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia, out IMMDevice device);

        // Activate audio session manager
        Guid sessionManagerIID = typeof(IAudioSessionManager2).GUID;
        device.Activate(ref sessionManagerIID, 0x17, IntPtr.Zero, out object obj);
        IAudioSessionManager2 sessionManager = (IAudioSessionManager2)obj;

        // Get session enumerator to find our app's session
        sessionManager.GetSessionEnumerator(out IAudioSessionEnumerator enumerator);
        enumerator.GetCount(out int count);

        uint currentProcessId = (uint)System.Diagnostics.Process.GetCurrentProcess().Id;

        // Loop through sessions to find our app's
        for (int i = 0; i < count; i++)
        {
            enumerator.GetSession(i, out IAudioSessionControl2 sessionControl);
            sessionControl.GetProcessId(out uint processId);

            if (processId == currentProcessId)
            {
                // Disable capture for this session
                Guid emptyGuid = Guid.Empty;
                sessionControl.SetSessionOptions(AUDIOSESSIONOPTIONS_DISABLE_CAPTURE, ref emptyGuid);
                Marshal.ReleaseComObject(sessionControl);
                break;
            }

            Marshal.ReleaseComObject(sessionControl);
        }

        // Clean up COM objects to avoid leaks
        Marshal.ReleaseComObject(enumerator);
        Marshal.ReleaseComObject(sessionManager);
        Marshal.ReleaseComObject(device);
        Marshal.ReleaseComObject(deviceEnumerator);
    }
    catch (Exception ex)
    {
        // Handle exceptions (e.g., older Windows versions)
        Console.WriteLine($"Failed to disable audio capture: {ex.Message}");
    }
}

Call this method early in your app's lifecycle (like in Main or OnStartup):

static void Main(string[] args)
{
    DisableAudioCaptureForCurrentApp();
    // Rest of your app initialization code
}

Note: This method only works on Windows 10 1607 or later. For older Windows versions, you'll need to use alternative approaches.

2. Use Exclusive Mode for Audio Playback

If you're using WASAPI directly for audio playback, you can open the audio device in exclusive mode. This locks the device to your app, preventing other apps (including recorders) from accessing it. However, this has tradeoffs:

  • Your app will take full control of the audio device, so no other apps can play sound while yours is running.
  • It's more complex to implement than the session flag method.

3. Encrypt Audio Content & Play In-Memory

For an extra layer of protection, store your audio files in an encrypted format. Decrypt the audio data in memory and play it directly without writing unencrypted data to disk or exposing it to the system audio stack in raw form. This makes it significantly harder for attackers to intercept the original copyrighted content before it's played.

While this doesn't block capture entirely, it adds a strong barrier to unauthorized access.

Important Limitations

  • Hardware-level recording: None of these methods can stop someone from recording your app's audio using a physical microphone or audio cable. They only block software-level capture.
  • Elevated recorders: Some screen recorders run with admin privileges, which might bypass certain restrictions. Be sure to test with common tools (OBS, Snagit) to verify your implementation works as expected.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:27:03