在 PowerShell 7 中,当长时间运行的命令完成时获取通知
I’m happy to translate the article for you, but I need the text you’d like translated. Could you please paste the content (or the portion you want translated) here? I’ll keep the source link, formatting, and any code blocks exactly as they are while translating the rest into Simplified Chinese.
工作原理
当您按下 Enter 键时,会记录时间戳。命令完成后,下一个提示符会将当前时间与存储的时间戳进行比较。如果经过的时间超过阈值,则使用 BurntToast 模块触发 toast 通知。
Source: …
步骤
第 1 步 – 安装 BurntToast 模块
Install-Module BurntToast
第 2 步 – 查找 PowerShell 7 配置文件路径
$PROFILE
典型输出:
C:\Users\<UserName>\Documents\PowerShell\Microsoft.PowerShell_profile.ps1
第 3 步 – 在编辑器中打开配置文件
code $PROFILE
(使用您喜欢的任何编辑器。)
第 4 步 – 导入模块
Import-Module BurntToast
注意: 此导入语句应放在配置文件的顶部;否则后面的代码将无法工作。
第 5 步 – 添加通知逻辑
将以下内容粘贴到 Import-Module 行之后、配置文件的顶部:
$OriginalPrompt = (Get-Command prompt).ScriptBlock # capture original prompt
# Notification needs a logo; we’ll use PowerShell’s icon
$applogo = "C:\Program Files\PowerShell\7\assets\Powershell_av_colors.png"
$ExecutionNotifyThreshold = 3 # seconds
$global:__commandStart = $null
function Format-Elapsed([TimeSpan]$timestamp) {
if ($timestamp.TotalSeconds -lt 60) {
return ('{0:0.0}s' -f $timestamp.TotalSeconds)
}
$parts = New-Object System.Collections.Generic.List[string]
if ($timestamp.Days -gt 0) { $parts.Add("{0}d" -f $timestamp.Days) }
if ($timestamp.Hours -gt 0) { $parts.Add("{0}h" -f $timestamp.Hours) }
if ($timestamp.Minutes -gt 0) { $parts.Add("{0}m" -f $timestamp.Minutes) }
$parts.Add("{0}s" -f $timestamp.Seconds)
return ($parts -join ' ')
}
function global:prompt {
if ($global:__commandStart) {
$elapsed = (Get-Date) - $global:__commandStart
if ($elapsed.TotalSeconds -ge $ExecutionNotifyThreshold) {
$lastCmd = (Get-History -Count 1).CommandLine
$text = @(
'PS7 Finished:'
"`$ $lastCmd"
("Took {0}" -f (Format-Elapsed $elapsed))
)
New-BurntToastNotification -Text $text -AppLogo $applogo
}
$global:__commandStart = $null
}
& $OriginalPrompt
}
根据需要调整 $ExecutionNotifyThreshold(单位:秒)。
第 6 步 – 在 Enter 键时记录开始时间
在配置文件的 末尾 添加以下内容,以免被其他代码覆盖:
Set-PSReadLineKeyHandler -Key Enter -ScriptBlock {
$global:__commandStart = Get-Date
[Microsoft.PowerShell.PSConsoleReadLine]::AcceptLine()
}
保存文件后,重新启动终端或运行:
. $PROFILE
现在执行一个耗时超过阈值的命令;您应该会看到类似下图的 toast 通知:
注意事项与警告
- 只要在框架配置提示符之后 加载上述代码,此方法在 oh‑my‑posh、starship 或其他提示符框架中均可正常工作。
- 它会覆盖全局
prompt函数。如果你有其他自定义提示符,请相应合并逻辑。 Enter键通过 PSReadLine 进行挂钩。如果你已经有自定义的Enter处理程序,请将脚本合并。
移除此行为
如果你决定不再需要通知,请运行:
Remove-PSReadLineKeyHandler -Key Enter
就这样!现在你可以运行长时间运行的命令,而无需一直盯着控制台。 🎉
