每日摘要
- 来源:Claude Code 提示音设置
- 一句话:记录了在 Windows 上通过 PowerShell、VBS 和 Claude Code hooks 更换提示音的尝试。
- 我的判断:这是一个小而实用的环境改造:提示音能让长时间运行的工具更可感知,但 Windows 下路径、隐藏窗口和音频播放方式都要仔细处理。
- 关键词:Claude Code、Windows、提示音、hooks、PowerShell
原始记录
有个提示音让 coding agent 在背景里工作,任务结束、需要人类注意、批准和 review 的时候播放音效,能让人更放心地去摸鱼。
看到了这篇教程
里用的是 「帝国时代」,甚合我意。
既然刷到了,且刚好最近开始用 CC,立马也打算换一个。下面是在工位的 win 10 上改的。
先下载几个喜欢的音频(.mp3)
接着在 C:\Users\你的用户名\.claude 中创建 sounds 文件夹,将音频文件并放入
在该路径下新建 play_sound.ps1 ,并粘贴下面的代码
1
2
3
4
5
6
|
param([string]$SoundPath)
Add-Type -AssemblyName presentationCore
$player = New-Object System.Windows.Media.MediaPlayer
$player.Open($SoundPath)
$player.Play()
Start-Sleep -Seconds 3
|
最后在 Claude Code 配置文件 C:\Users\你的用户名\.claude\settings.json 下追加(这个部分让 G 老师改了好几遍,涉及一些转义的错误)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
"hooks": {
"SessionStart": [
{
"matcher": "startup|clear",
"hooks": [
{
"type": "command",
"command": "powershell.exe -NoProfile -WindowStyle Hidden -Command \"Start-Process powershell.exe -WindowStyle Hidden -ArgumentList '-NoProfile -STA -ExecutionPolicy Bypass -File C:/Users/用户名/.claude/play_sound.ps1 C:/Users/23947/.claude/sounds/drum.mp3'\""
}
]
}
],
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "powershell.exe -NoProfile -WindowStyle Hidden -Command \"Start-Process powershell.exe -WindowStyle Hidden -ArgumentList '-NoProfile -STA -ExecutionPolicy Bypass -File C:/Users/23947/.claude/play_sound.ps1 C:/Users/用户名/.claude/sounds/horn.mp3'\""
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "powershell.exe -NoProfile -WindowStyle Hidden -Command \"Start-Process powershell.exe -WindowStyle Hidden -ArgumentList '-NoProfile -STA -ExecutionPolicy Bypass -File C:/Users/23947/.claude/play_sound.ps1 C:/Users/用户名/.claude/sounds/relic.mp3'\""
}
]
}
],
"PreCompact": [
{
"hooks": [
{
"type": "command",
"command": "powershell.exe -NoProfile -WindowStyle Hidden -Command \"Start-Process powershell.exe -WindowStyle Hidden -ArgumentList '-NoProfile -STA -ExecutionPolicy Bypass -File C:/Users/用户名/.claude/play_sound.ps1 C:/Users/23947/.claude/sounds/workshop.mp3'\""
}
]
}
]
}
|
路径中的 用户名 替换为实际的 Windows 登录用户名。
音频文件名替换为对应文件。
win 11
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
param([string]$SoundPath)
Add-Type -TypeDefinition @"
using System;
using System.Runtime.InteropServices;
using System.Text;
public class MCI {
[DllImport("winmm.dll", CharSet = CharSet.Auto)]
public static extern int mciSendString(string command, StringBuilder returnValue, int returnLength, IntPtr callback);
}
"@
$alias = "media_" + [System.Diagnostics.Process]::GetCurrentProcess().Id
[MCI]::mciSendString("open `"$SoundPath`" type mpegvideo alias $alias", $null, 0, [IntPtr]::Zero) | Out-Null
[MCI]::mciSendString("play $alias wait", $null, 0, [IntPtr]::Zero) | Out-Null
[MCI]::mciSendString("close $alias", $null, 0, [IntPtr]::Zero) | Out-Null
|
1
2
3
4
5
6
|
Set args = WScript.Arguments
If args.Count < 1 Then WScript.Quit
soundPath = args(0)
cmd = "powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -File """ & _
"C:\Users\l\.claude\play_sound.ps1"" """ & soundPath & """"
CreateObject("WScript.Shell").Run cmd, 0, False
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "wscript.exe \"C:\\Users\\l\\.claude\\play_sound.vbs\" \"C:\\Users\\l\\.claude\\sounds\\drum.mp3\""
}
]
}
],
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "wscript.exe \"C:\\Users\\l\\.claude\\play_sound.vbs\" \"C:\\Users\\l\\.claude\\sounds\\horn.mp3\""
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "wscript.exe \"C:\\Users\\l\\.claude\\play_sound.vbs\" \"C:\\Users\\l\\.claude\\sounds\\relic.mp3\""
}
]
}
],
"PreCompact": [
{
"hooks": [
{
"type": "command",
"command": "wscript.exe \"C:\\Users\\l\\.claude\\play_sound.vbs\" \"C:\\Users\\l\\.claude\\sounds\\workshop.mp3\""
}
]
}
]
},
|