PowerShell中的事件处理与Tab补全增强
立即解锁
发布时间: 2025-08-26 01:44:54 阅读量: 10 订阅数: 13 


Windows PowerShell深度解析与实战指南
# PowerShell 中的事件处理与 Tab 补全增强
## 1. PowerShell 中的事件处理
### 1.1 WMI 事件脚本的风险
WMI 事件脚本非常实用,但也存在危险。如果不调用事件监视器的 Stop 方法,系统会不断执行查询。多次运行脚本会使事件监视器累积,导致系统性能显著下降,因为大部分 CPU 时间会用于执行泄漏的查询。所以,在使用完事件监视器后,要记得停止它们并断开与事件的连接。
### 1.2 检测用户是否终止脚本
以监控文件夹文件删除操作的脚本为例,当脚本监听事件时,如果用户按下 Ctrl+C,脚本会被终止,甚至整个命令都会被终止。在 PowerShell 1.0 中,处理 Ctrl+C 是一个薄弱环节。PSEventing 管理单元提供了两个 cmdlet 来帮助解决这个问题:Start-KeyHandler 和 Stop-KeyHandler,它们可以捕获各种按键操作,我们主要关注处理 Ctrl+C。
支持 Ctrl+C 的关键步骤如下:
1. 使用 Start-KeyHandler -CaptureCtrlC 注册一个处理程序。
2. 区分 Ctrl+C 事件和其他事件。
3. 完成操作后,调用 Stop-KeyHandler 取消注册处理程序。
其中,区分事件不是很直观。我们可以利用 Get-Event 返回的 Ctrl+C 事件的 Name 为 “CtrlC” 这一特性。以下是修改后的文件夹监控脚本 WatchDeletedFilesCtrlC.ps1,它可以正确处理 Ctrl+C:
```powershell
Add-PSSnapin PSEventing -ErrorAction SilentlyContinue
$fsw = New-Object System.IO.FileSystemWatcher
$fsw.Path = "c:\powershell"
$fsw.EnableRaisingEvents = $true
Start-KeyHandler -CaptureCtrlC
Connect-EventListener fsw deleted
do
{
$events = Get-Event -wait
}
while(!$events)
foreach ($event in $events)
{
if ($event.Name -eq "CtrlC")
{
Write-Host "Ctrl+C detected"
break;
}
else
{
Write-Host -foreground Yellow `
"Warning!!! Somebody just deleted $($event.Args.FullPath)"
}
}
Stop-KeyHandler
Disconnect-EventListener fsw deleted
$fsw.EnableRaisingEvents = $false
```
这个脚本使用 foreach 循环遍历事件,并使用 if 语句进行判断,语义上等同于之前使用的 where cmdlet。使用 do-while 循环是因为有时 Get-Event 在 Ctrl+C 事件后会返回 $null 值,该循环会忽略这个值并重新开始事件监听操作。运行这个脚本时,即使按下 Ctrl+C,脚本也不会被终止,并且会继续执行同一行上的命令。
### 1.3 使用脚本块作为事件处理程序
处理不同事件并区分它们比较困难。最好的方法是使用 PSEventing 附带的 helper eventhandler.ps1 脚本及其实用函数:
- Add-EventHandler($variable, $eventName, $script):将脚本块作为给定事件的处理程序附加。
- Remove-EventHandler($variable, $eventName):分离之前附加的事件处理程序。
- Do-Events($onlyOnce):等待事件并多次或一次处理其事件处理程序。
以下是扩展后的文件系统监控脚本 WatchDeletedCreatedFiles.ps1,它可以处理文件的删除和创建事件:
```powershell
Add-PSSnapin PSEventing -ErrorAct
```
0
0
复制全文
相关推荐










