PowerShell,当“Register-ObjectEvent -Action”触发时从“Wait-Event”返回?

时间:2011-09-08 15:45:29

标签: powershell event-handling powershell-v2.0 notifyicon

我已经在这个问题上摸不着头几个小时......下面的代码会触发一个动作,无论是点击还是关闭通知气球。我也是PowerShell的新手。

考虑以下代码:

####### Launch as : ##########################
## powershell.exe -sta -file .\balloon.ps1  ##
##############################################

Write-Host -ForeGround Yellow " ###### START OF SCRIPT ! ######"
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")

$Title = "This is the title"
$Text = "This is the text"
$EventTimeOut = 5

$balloon = New-Object System.Windows.Forms.NotifyIcon
$balloon.Icon = [System.Drawing.SystemIcons]::Information
$balloon.BalloonTipTitle = $Title
$balloon.BalloonTipText = $Text
$balloon.Visible = $True

$balloon.ShowBalloonTip(1)

Register-ObjectEvent $balloon BalloonTipClicked -SourceIdentifier event_BalloonTipClicked `
    -Action {
        # explorer.exe; `
        Write-Host  -ForeGround Green "event_BalloonTipClicked occured !"; `
        # Gets rid of icon
        $balloon.Dispose(); `
    }|Out-Null

Register-ObjectEvent $balloon BalloonTipClosed -SourceIdentifier event_BalloonTipClosed `
    -Action {
        Write-Host -ForeGround Green "event_BalloonTipClosed occured !"; `
        $balloon.Dispose(); `
    }|Out-Null 

Wait-Event event_BalloonTipClicked -TimeOut $EventTimeOut
Wait-Event event_BalloonTipClosed -TimeOut $EventTimeOut

Unregister-Event -SourceIdentifier event_BalloonTipClicked
Unregister-Event -SourceIdentifier event_BalloonTipClosed

Write-Host -ForeGround Gray "Should be empty -- start --"
Get-EventSubscriber
Write-Host -ForeGround Gray "Should be empty -- end --"

#[System.Windows.Forms.MessageBox]::Show("Done !!")
Write-Host -ForeGround Yellow " ###### END OF SCRIPT ! ######"

我希望脚本在“Register-ObjectEvent”完成触发其动作后立即结束。

但是,返回仅在“Wait-Event”中指定的超时后发生,从而阻止进一步执行代码。此行为也阻止我将该代码转换为函数。

如果脚本仅侦听一个事件,则其行为方式相同。

非常感谢任何帮助!

2 个答案:

答案 0 :(得分:3)

坦克为你的时间Shay Levy。我没有设法正确使用您的解决方案。

我使用这个vbscript在后台启动文件。

Set objShell = CreateObject("Wscript.Shell")
objShell.Run "powershell.exe -NoExit -Sta -File .\balloon.ps1",0

不幸的是,例如5次启动脚本会让我运行5个无效的PowerShell实例。

我终于意识到混合“Register-ObjectEvent -Action”和“Wait-Event”是一个肯定的禁忌(http://social.technet.microsoft.com/Forums/en-US/winserverpowershell/thread/10983ec3-7aa6-4011-a87e-a30a25ab484a/

以下代码是我的目标。这是解决问题的同步方法。

###################################################
## Launch as :                                   ##
## cmd /k powershell -Sta [-File] .\balloon.ps1  ##
###################################################


# This post put me on the right track "http://social.technet.microsoft.com/Forums/en-US/winserverpowershell/thread/10983ec3-7aa6-4011-a87e-a30a25ab484a/"

Write-Host -ForeGround Yellow " ###### START OF SCRIPT ! ######"
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")

$Title = "This is the title"
$Text = "This is the text"
$EventTimeOut = 5

$balloon = New-Object System.Windows.Forms.NotifyIcon -Property @{
    Icon = [System.Drawing.SystemIcons]::Information
    BalloonTipTitle = $Title
    BalloonTipText = $Text
    Visible = $True
}

# Value "1" here is meaningless. $EventTimeOut will force bubble to close.
$balloon.ShowBalloonTip(1)

Register-ObjectEvent $balloon BalloonTipClicked -SourceIdentifier event_BalloonTipClicked
Register-ObjectEvent $balloon BalloonTipClosed -SourceIdentifier event_BalloonTipClosed

# "Wait-Event" pauses the script here until an event_BalloonTip* is triggered
# TimeOut is necessary or balloon and script hangs there forever. 
# This could be okay but event subscription gets messed up by following script instances generating the same event names1.
$retEvent = Wait-Event event_BalloonTip* -TimeOut $EventTimeOut

# Script resumes here.
$retSourceIdentifier = $retEvent.SourceIdentifier
If ($retSourceIdentifier -eq $null){
    Write-Host  -ForeGround Green "TimeOut occured !"
}Else{
    Write-Host  -ForeGround Green "$retSourceIdentifier occured !"
    }

If ($retSourceIdentifier -eq "event_BalloonTipClicked"){
    explorer.exe
    }

# Gets rid of icon. This is absolutely necessary, otherwise icon is stuck event if parent script/shell closes
$balloon.Dispose()

# Tidy up, This is needed if returning to parent shell.
Unregister-Event -SourceIdentifier event_BalloonTip*
Get-Event event_BalloonTip* | Remove-Event
Write-Host -ForeGround Gray "Should be empty -- start --"
Get-EventSubscriber
Write-Host -ForeGround Gray "Should be empty -- end --"

#[System.Windows.Forms.MessageBox]::Show("Done !!")
Write-Host -ForeGround Yellow " ###### END OF SCRIPT ! ######"

答案 1 :(得分:1)

该脚本注册了两个事件处理程序。一旦事件被触发它 在其action参数中执行代码,并取消注册事件处理程序及其生成的作业。 如果取消注册事件不是您想要的,您可以注释掉相关的行(请参阅内联注释)。

从批处理文件运行PowerShell时,您可能需要添加-NoExit开关,以便控制台不会关闭(并销毁任何事件和相关作业)。

####### Launch as : ##########################
## powershell.exe -sta -file .\balloon.ps1  ##
##############################################

Write-Host -ForeGround Yellow " ###### START OF SCRIPT ! ######"
Add-Type -Assembly System.Windows.Forms

$Title = "This is the title"
$Text = "This is the text"

$balloon = New-Object System.Windows.Forms.NotifyIcon -Property @{
    Icon = [System.Drawing.SystemIcons]::Information
    BalloonTipTitle = $Title
    BalloonTipText = $Text
    Visible = $True 
}

$balloon.ShowBalloonTip(1)


$null = Register-ObjectEvent $balloon BalloonTipClicked -SourceIdentifier event_BalloonTipClicked -Action {
        Write-Host  -ForeGround Green "event_BalloonTipClicked occured !"        
        Unregister-Event -SourceIdentifier $event.SourceIdentifier -Force
        Remove-Job $event.SourceIdentifier -Force

        # unregister event and remove job object
        Unregister-Event -SourceIdentifier event_BalloonTipClosed -Force
        Remove-Job event_BalloonTipClosed -Force

        $balloon.Dispose()
}

$null = Register-ObjectEvent $balloon BalloonTipClosed -SourceIdentifier event_BalloonTipClosed -Action {
        Write-Host -ForeGround Green "event_BalloonTipClosed occured !"
        Unregister-Event -SourceIdentifier $event.SourceIdentifier -Force
        Remove-Job $event.SourceIdentifier -Force

        # unregister event and remove job object
        Unregister-Event -SourceIdentifier event_BalloonTipClicked -Force
        Remove-Job event_BalloonTipClicked -Force

        $balloon.Dispose()
}