在 PowerShell 7 中,当长时间运行的命令完成时获取通知

发布: (2026年1月7日 GMT+8 09:10)
4 min read
原文: Dev.to

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 通知:

PowerShell notification example

注意事项与警告

  • 只要在框架配置提示符之后 加载上述代码,此方法在 oh‑my‑poshstarship 或其他提示符框架中均可正常工作。
  • 它会覆盖全局 prompt 函数。如果你有其他自定义提示符,请相应合并逻辑。
  • Enter 键通过 PSReadLine 进行挂钩。如果你已经有自定义的 Enter 处理程序,请将脚本合并。

移除此行为

如果你决定不再需要通知,请运行:

Remove-PSReadLineKeyHandler -Key Enter

就这样!现在你可以运行长时间运行的命令,而无需一直盯着控制台。 🎉

Back to Blog

相关文章

阅读更多 »

什么是 cppsp?

cppsp – 基于 C++ 的转译脚本式语言 要求 - 已安装 C++ 编译器,并将其文件夹添加到系统 PATH 环境变量中。 - …