C# 本身不提供直接播放聲音的 managed API,需透過 P/Invoke 呼叫 Windows 核心 DLL。本文整理四種常見方式,適用場景各異。
| 方法 | DLL | 適用場景 | 特點 |
|---|---|---|---|
| Interaction.Beep() | Microsoft.VisualBasic.dll | 簡單提示音 | Managed 包裝,最簡單但僅能發出系統預設蜂鳴 |
| MessageBeep | user32.dll | 系統事件聲音 | 播放系統音效(驚嘆號、問號、錯誤等),非阻塞 |
| Beep | kernel32.dll | 精確頻率/持續時間 | 可控制頻率(Hz)與持續時間(ms),同步阻塞 |
| PlaySound | winmm.dll | 播放 .wav 檔案 | 支援檔案/資源/系統音效,非同步可選 |
// 需參考 Microsoft.VisualBasic.dll
using Microsoft.VisualBasic;
public void PlaySimpleBeep()
{
Interaction.Beep(); // 播放系統預設提示音
}
using System.Runtime.InteropServices;
public class SystemSounds
{
// 系統音效常數
public const uint MB_OK = 0x00000000;
public const uint MB_ICONHAND = 0x00000010; // 嚴重錯誤
public const uint MB_ICONQUESTION = 0x00000020; // 問號
public const uint MB_ICONEXCLAMATION = 0x00000030; // 驚嘆號/警告
public const uint MB_ICONASTERISK = 0x00000040; // 資訊/星號
[DllImport("user32.dll", SetLastError = true)]
public static extern bool MessageBeep(uint uType);
public static void PlayExclamation() => MessageBeep(MB_ICONEXCLAMATION);
public static void PlayError() => MessageBeep(MB_ICONHAND);
}
public class SpeakerBeep
{
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool Beep(uint dwFreq, uint dwDuration);
// 播放指定音調(頻率 Hz,持續毫秒)
public static void PlayTone(int frequencyHz, int durationMs)
{
if (frequencyHz < 37 || frequencyHz > 32767)
throw new ArgumentOutOfRangeException(nameof(frequencyHz), "Frequency must be 37-32767 Hz");
Beep((uint)frequencyHz, (uint)durationMs);
}
// 簡易音樂範例:Do-Re-Mi
public static void PlayScale()
{
int[] notes = { 262, 294, 330, 349, 392, 440, 494, 523 }; // C4-C5
foreach (int freq in notes)
{
PlayTone(freq, 300);
Thread.Sleep(50);
}
}
}
public class WavePlayer
{
[Flags]
public enum SoundFlags : uint
{
SND_SYNC = 0x0000, // 同步播放(預設)
SND_ASYNC = 0x0001, // 非同步播放
SND_NODEFAULT = 0x0002, // 找不到檔案時不播放預設音
SND_LOOP = 0x0008, // 循環播放(需搭配 SND_ASYNC)
SND_FILENAME = 0x00020000, // pszSound 是檔案路徑
SND_RESOURCE = 0x00040000, // pszSound 是資源名稱
}
[DllImport("winmm.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern bool PlaySound(string pszSound, IntPtr hmod, SoundFlags fdwSound);
// 播放檔案(非同步)
public static void PlayFile(string filePath)
{
if (!File.Exists(filePath))
throw new FileNotFoundException("Sound file not found", filePath);
PlaySound(filePath, IntPtr.Zero, SoundFlags.SND_ASYNC | SoundFlags.SND_FILENAME);
}
// 播放嵌入資源
public static void PlayEmbeddedResource(string resourceName)
{
PlaySound(resourceName, Marshal.GetHINSTANCE(typeof(WavePlayer).Module), SoundFlags.SND_ASYNC | SoundFlags.SND_RESOURCE);
}
// 停止所有播放
public static void Stop() => PlaySound(null, IntPtr.Zero, SoundFlags.SND_SYNC);
}
public class SoundDemo
{
public void RunDemo()
{
// 1. 簡單提示
SystemSounds.PlayExclamation();
// 2. 自訂頻率
SpeakerBeep.PlayTone(800, 300); // 800Hz 持續 300ms
// 3. 播放 WAV 檔案
WavePlayer.PlayFile(@"C:\Windows\Media\chord.wav");
// 4. 播放音階
SpeakerBeep.PlayScale();
}
}
System.Media.SoundPlayer;UWP/WinUI 使用 MediaPlayer;跨平台建議 NAudio 或 SkiaSharp 音訊擴充根據需求選擇:簡單提示用 MessageBeep;精確音調用 Beep;播放聲音檔用 PlaySound;生產級應用建議封裝為 ISoundService 介面,方便測試與替換實現。