Toast通知触发程序后台启动,如何设置为前台激活?
问题:Toast通知按钮启动程序无法前台激活
编写了带自定义按钮和协议的PowerShell Toast通知脚本,点击按钮后目标BAT程序在后台启动,无法获取前台焦点,如何调整实现前台启动?
自定义协议注册表配置
$1 = @( [pscustomobject]@{name = 'Time'; Link = 'C:\Users\XXX\Desktop\Personal\Scripts\Time_sleep.BAT'}, [pscustomobject]@{name = 'Zenek'; Link = 'C:\Users\XXX\Desktop\Personal\Scripts\email.bat'}, [pscustomobject]@{name = 'NetEx'; Link = 'C:\Users\XXX\Desktop\Personal\Scripts\ne.bat'}, [pscustomobject]@{name = 'Busy'; Link = 'C:\Users\XXX\Desktop\Personal\Scripts\busy.bat'}, [pscustomobject]@{name = 'Shorts'; Link = 'C:\Users\XXX\Desktop\Personal\Scripts\Shortcuts.bat'} ) $1 | % { $RegPath = "HKCU:\Software\Classes\$($_.name)\" New-Item -Path "$RegPath" -Force |Out-Null New-ItemProperty -Path "$RegPath" -Name "(Default)" -Value "URL:$($_.name) Protocol" -PropertyType "String"|Out-Null New-ItemProperty -Path "$RegPath" -Name "URL Protocol" -Value "" -PropertyType "String"|Out-Null New-Item -Path "$RegPath\shell\open\command" -Force|Out-Null New-ItemProperty -Path "$RegPath\shell\open\command" -Name "(Default)" -Value $_.Link -PropertyType "String"|Out-Null }
示例BAT文件内容(SHORTCUTS.BAT)
@echo off color b echo List of shortcuts echo BUSY CTRL + ALT + C echo MAIL CTRL + ALT + L echo NETEXT CTRL + ALT + N echo HIBERNATE CTRL + ALT + H echo TIME CTRL + ALT + T echo ASSOC CTRL + ALT + P echo DRIVES CTRL + ALT + D pause
Toast通知脚本
function Show-Toast{ [cmdletbinding()] param( [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position = 0)] [string]$Title, [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position = 1)] [string]$message ) [Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime]|Out-Null [Windows.UI.Notifications.ToastNotification, Windows.UI.Notifications, ContentType = WindowsRuntime]|Out-Null [Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom.XmlDocument, ContentType = WindowsRuntime]|out-null $guid = '{1AC14E77-02E7-4E5D-B744-2EB1AE5198B7}\WindowsPowerShell\v1.0\powershell.exe' $ToastTitle = "" $Signature = "" $CustomHello = "Hello {0}.{1}" -f ($env:USERNAME[0].ToString()).ToUpper(), (($env:USERNAME.ToString()).Substring(1)).ToUpper() $BannerImage = 'C:\Users\XXX\Desktop\Personal\Scripts\Toast\lake.jpg' $template = @" <toast scenario="reminder"> <visual> <binding template = "ToastGeneric"> <text>$CustomHello</text> <text>$ToastTitle</text> <text placement="attribution">$Signature</text> <group> <subgroup> <text hint-style="title" hint-wrap="true" >$Title</text> </subgroup> </group> <group> <subgroup> <text hint-style="base" hint-wrap="true" >$message</text> </subgroup> </group> <group> <subgroup> <text hint-style="captionSubtle" hint-wrap="true" >$Title</text> </subgroup> </group> <group> <subgroup> <text hint-style="body" hint-wrap="true" >$message</text> </subgroup> </group> <image placement="hero" src="$BannerImage"/> </binding> </visual> <actions> <action arguments="Zenek:" content="Zenek" activationType="protocol" /> <action arguments="NetEx:" content="NetEx" activationType="protocol"/> <action arguments="Busy:" content="Busy" activationType="protocol"/> <action arguments="Time:" content="Time" activationType="protocol"/> <action arguments="shorts:" content="Shorts" activationType="protocol"/> </actions> </toast> "@ $xml = [Windows.Data.Xml.Dom.XmlDocument]::new() $xml.LoadXml($template) $toast = [Windows.UI.Notifications.ToastNotification]::new($xml) [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($guid).Show($toast) } [pscustomobject]@{ Title = "Test" message = "Another" }| Show-Toast
注:原脚本中Toast XML模板的<toast scenario="reminder">>多了一个右尖括号,已修正为<toast scenario="reminder">,避免XML解析错误。
当前与期望状态
- 当前启动状态(后台运行):

- 期望启动状态(前台激活):

解决方案
方法1:修改注册表协议命令,强制前台启动CMD窗口
直接调用BAT时系统默认后台启动cmd.exe,修改注册表命令,用start参数强制打开前台窗口:
$1 = @( [pscustomobject]@{name = 'Time'; Link = 'C:\Users\XXX\Desktop\Personal\Scripts\Time_sleep.BAT'}, [pscustomobject]@{name = 'Zenek'; Link = 'C:\Users\XXX\Desktop\Personal\Scripts\email.bat'}, [pscustomobject]@{name = 'NetEx'; Link = 'C:\Users\XXX\Desktop\Personal\Scripts\ne.bat'}, [pscustomobject]@{name = 'Busy'; Link = 'C:\Users\XXX\Desktop\Personal\Scripts\busy.bat'}, [pscustomobject]@{name = 'Shorts'; Link = 'C:\Users\XXX\Desktop\Personal\Scripts\Shortcuts.bat'} ) $1 | % { $RegPath = "HKCU:\Software\Classes\$($_.name)\" New-Item -Path "$RegPath" -Force |Out-Null New-ItemProperty -Path "$RegPath" -Name "(Default)" -Value "URL:$($_.name) Protocol" -PropertyType "String"|Out-Null New-ItemProperty -Path "$RegPath" -Name "URL Protocol" -Value "" -PropertyType "String"|Out-Null New-Item -Path "$RegPath\shell\open\command" -Force|Out-Null # 修改启动命令,用start强制前台窗口 $launchCommand = "cmd.exe /c start """" /max `"$($_.Link)`"""" New-ItemProperty -Path "$RegPath\shell\open\command" -Name "(Default)" -Value $launchCommand -PropertyType "String"|Out-Null }
参数说明:
start "":start命令需要标题参数,空字符串避免路径含空格时出错/max:可选,最大化窗口启动,不需要可改为/normal
方法2:用PowerShell脚本封装,强制激活窗口
若需要更灵活的窗口控制,可写辅助脚本调用BAT并激活窗口:
- 创建
Launch-BatForeground.ps1脚本:
param([string]$BatPath) # 启动BAT文件 $process = Start-Process -FilePath "cmd.exe" -ArgumentList "/c `"$BatPath`"" -PassThru # 等待窗口创建 Start-Sleep -Milliseconds 500 # 调用Win32API激活窗口 Add-Type @" using System; using System.Runtime.InteropServices; public class Win32 { [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SetForegroundWindow(IntPtr hWnd); } "@ [Win32]::SetForegroundWindow($process.MainWindowHandle)
- 修改注册表配置,让协议调用该脚本:
$1 = @( [pscustomobject]@{name = 'Time'; Link = 'C:\Users\XXX\Desktop\Personal\Scripts\Time_sleep.BAT'}, [pscustomobject]@{name = 'Zenek'; Link = 'C:\Users\XXX\Desktop\Personal\Scripts\email.bat'}, [pscustomobject]@{name = 'NetEx'; Link = 'C:\Users\XXX\Desktop\Personal\Scripts\ne.bat'}, [pscustomobject]@{name = 'Busy'; Link = 'C:\Users\XXX\Desktop\Personal\Scripts\busy.bat'}, [pscustomobject]@{name = 'Shorts'; Link = 'C:\Users\XXX\Desktop\Personal\Scripts\Shortcuts.bat'} ) $1 | % { $RegPath = "HKCU:\Software\Classes\$($_.name)\" New-Item -Path "$RegPath" -Force |Out-Null New-ItemProperty -Path "$RegPath" -Name "(Default)" -Value "URL:$($_.name) Protocol" -PropertyType "String"|Out-Null New-ItemProperty -Path "$RegPath" -Name "URL Protocol" -Value "" -PropertyType "String"|Out-Null New-Item -Path "$RegPath\shell\open\command" -Force|Out-Null $launchCommand = "powershell.exe -WindowStyle Hidden -ExecutionPolicy Bypass -File `"C:\Users\XXX\Desktop\Personal\Scripts\Launch-BatForeground.ps1`" -BatPath `"$($_.Link)`"" New-ItemProperty -Path "$RegPath\shell\open\command" -Name "(Default)" -Value $launchCommand -PropertyType "String"|Out-Null }
内容的提问来源于stack exchange,提问作者Nawad-sama
相关产品推荐
相关产品推荐

