Windows平台用PlaySound播放系统提示音最简单:调用PlaySound(L"SystemExclamation", NULL, SND_ASYNC | SND_SYSTEM)即可,需宽字符字符串,支持SystemAsterisk等预设声名;播WAV文件则用SND_FILENAME标志加绝对路径;Linux/macOS需用aplay/afplay命令或miniaudio等跨平台库。

Windows平台用PlaySound播放系统提示音最简单
直接调用PlaySound API 就能触发系统预设音效,比如“默认提示音”“错误”“询问”,不需要额外文件或资源。它底层走的是 Windows 的声音子系统,兼容性好,连 Win10/Win11 都没问题。
关键点在于第二个参数传NULL,第三个参数加SND_ASYNC | SND_SYSTEM标志:
#include <windows.h> PlaySound(L"SystemExclamation", NULL, SND_ASYNC | SND_SYSTEM);
常见系统声名有:SystemAsterisk、SystemExclamation、SystemHand、SystemQuestion、SystemDefault。注意必须是宽字符字符串(L""),否则静音。
- 如果传错名字(比如
L"SystemBeep"不存在),函数返回FALSE但不报错,容易误以为播成功了 -
SND_SYNC会阻塞主线程,UI 程序慎用;SND_ASYNC推荐,但别在函数栈退出后立即销毁相关资源(虽然系统提示音不依赖外部数据) - 系统音效是否启用取决于控制面板「声音」设置里的「播放 Windows 声音」开关,关了就真没声——这点常被忽略
播放本地WAV文件要用PlaySound但参数不同
播 WAV 文件时,第一个参数不再是声名,而是文件路径;第二个参数必须为NULL(不能传模块句柄);标志位要换成SND_FILENAME | SND_ASYNC。
立即学习“C++免费学习笔记(深入)”;
PlaySound(L"C:\path\to\sound.wav", NULL, SND_FILENAME | SND_ASYNC);
路径必须是绝对路径或当前工作目录下的相对路径,且只支持 PCM 编码的 WAV(即无压缩)。如果 WAV 是 24bit、IEEE float 或含 ADPCM 等编码,PlaySound会静默失败(返回FALSE,无错误码提示)。
- 相对路径容易因工作目录变化失效,建议用
GetModuleFileName+PathRemoveFileSpec拼出 exe 同级路径 - 不要用
SND_RESOURCE试图从可执行文件里读资源——那是给 RC 资源用的,需配合模块句柄和资源 ID,和文件播放无关 - WAV 文件若含元数据(如 cue、list chunk),某些旧版 Windows 可能跳过播放,建议用 Audacity 导出为「WAV (Microsoft) signed 16-bit PCM」再测试
Linux/macOS 没有PlaySound,得换方案
C++ 标准库不提供跨平台音频播放,Linux/macOS 必须依赖外部命令或库。最轻量的是调用系统命令:Linux 用aplay,macOS 用afplay。
// Linux 示例
system("aplay -q /path/to/sound.wav &");
// macOS 示例
system("afplay /path/to/sound.wav &");
注意system()是阻塞的,加&后台运行;-q让aplay静默输出。但这种方式不可靠:用户可能没装aplay,或路径含空格导致命令解析失败。
- 更稳妥的做法是检查命令是否存在:
which aplay或command -v afplay,再决定 fallback 行为 - 不要用
std::system直接拼接用户输入的路径,有 shell 注入风险;路径应先用shellescape类逻辑处理(哪怕只是双引号包裹) - 如果项目允许引入依赖,
libao(Linux)或CoreAudio(macOS)API 更可控,但复杂度陡增——小工具没必要
为什么不用std::filesystem或fopen自己解码播放
因为 WAV 解码只是第一步,后面还要把 PCM 数据喂给声卡驱动。C++ 标准库完全不碰音频设备层,所有跨平台音频库(如 SDL2、PortAudio、miniaudio)本质都是封装了 ALSA/PulseAudio/CoreAudio/WASAPI 这些系统 API。
除非你在写音频编辑器或需要实时处理(如变调、混音),否则没必要自己读 WAV 头、校验格式、再调用底层音频接口。那相当于重造PlaySound,且更容易出兼容性问题。
-
PlaySound在 Windows 上已足够健壮,它甚至支持网络路径(SND_NODEFAULT除外),但企业环境常禁用网络音效,实测不如本地文件可靠 - 真正容易被忽略的是权限和沙盒:MSIX/UWP 应用、WSL 中的程序、某些安全策略锁定的终端,
PlaySound或system()都可能静默失败,得提前查GetLastError()或命令退出码 - 如果必须跨平台且不想依赖命令行,
miniaudio是目前最轻量的选择(单头文件、无构建依赖),但它仍需你手动加载 WAV 并提交缓冲区——对“播个提示音”而言,属于杀鸡用牛刀


















