gpt4 book ai didi

powershell - 如何使用类在 PowerShell 中实现事件处理

转载 作者:行者123 更新时间:2023-12-01 03:07:18 28 4
gpt4 key购买 nike

我希望能够创建一个自定义事件,该事件通常会触发订阅该事件的函数或对象。我查看了一些函数,例如:New-EventRegister-ObjectEvent ,但我不完全确定如何有效地将它们组合在一起。

我想要的想法是让函数在引发某个事件时自动执行并自动执行操作。例如,我附上了一个小程序,它会根据想法向订阅者 ( TestEvent::SendMessage() ) 引发事件 ( TestSubscribeEvent::DisplayMessage() )。这只是想法,但我真的不确定如何在 PowerShell 中正确实现此功能。

我目前正在使用 PowerShell 6.2。如果需要任何其他信息,请告诉我。

class TestSubscribeEvent
{
# This function would be subscribed to SendMessage from the class TestEvent.
[void] DisplayMessage([string] $msg)
{
Write-Host "EVENT REPLIED WITH THIS MESSAGE:`r`n$($msg)";
} # DisplayMessage()
} # CLASS :: TestSubscribeEvent



class TestEvent
{
[void] SendMessage([string] $msg)
{
# SEND THIS MESSAGE VIA EVENTS
# Allow all subscribers to see the message
# Message can be any literal string, such as "Hello".
} # SendMessage()
} # CLASS :: TestEvent



function main()
{
# Create a new instance of these objects
[TestEvent] $testEvent = [TestEvent]::new();
[TestSubscribeEvent] $testSub = [TestSubscribeEvent]::new();

# Send the message; TestSubscribeEvent should already be subscribed to TestEvent.
$testEvent.SendMessage("All these squares make a circle.");
} # main()



# Jump to main, start the program.
main;

在这段代码中,虽然只是出于想法, $testSub.DisplayMessage()应该自动执行一次 $testEvent.SendMessage()引发一个新事件。 $testSub.DisplayMessage() 的输出将取决于从 $testEvent.SendMessage() 提供的消息通过事件消息。

希望这是有道理的;如果需要 - 如果需要,我可以进一步详细说明。

感谢您的时间,

最佳答案

首先我为文字墙道歉。您应该查看 New-Event , Register-EngineEvent , Unregister-Event , Get-Event , Get-EventSubscriber , 和 Remove-Event cmdlet。这是一个关于使用这些事件来触发和处理您自己的事件的快速示例。

首先我们将设置2个小功能。这会将一些自动变量写入控制台:

function Write-EventToConsole ($evt)
{
Write-Host "Write info to the console from a function"
Write-Host $Evt.MessageData
Write-Host $Evt.Sender
Write-Host $Evt.TimeGenerated
Write-Host $Evt.SourceArgs
}

这个只是将它们附加到一个文件中:
function Save-EventToFile ($evt, $filepath)
{
"Writing to file" | Out-File $filepath -Append
"Message Data : {0}" -f $Evt.MessageData | Out-File $filepath -Append
"Sender : {0}" -f $Evt.Sender | Out-File $filepath -Append
"Time Generated : {0}" -f $Evt.TimeGenerated | Out-File $filepath -Append
"Source Args : {0}" -f $Evt.SourceArgs | Out-File $filepath -Append
}

接下来我们将设置 3 个事件处理程序。我们将一次做这 1 件事,检查订阅者,并在每个订阅者之后触发一个事件。
Register-EngineEvent -SourceIdentifier "MyEventIdentifier" -Action {
Write-EventToConsole $Event
} -SupportEvent

接下来检查我们的事件订阅者是否在那里。
Get-EventSubscriber -Force

SubscriptionId : 1
SourceObject :
EventName :
SourceIdentifier : MyEventIdentifier
Action : System.Management.Automation.PSEventJob
HandlerDelegate :
SupportEvent : True
ForwardEvent : False

然后我们触发事件
$null = New-Event -SourceIdentifier "MyEventIdentifier" `
-Sender "MyObject" `
-EventArguments "Some arguments that I want to pass" `
-MessageData "This is some message data I want to pass"

并查看写入控制台的数据。
just write to console
This is some message data I want to pass
MyObject
MyObject
4/5/2019 1:54:27 PM
Some arguments that I want to pass
Some arguments that I want to pass

添加其他事件:
Register-EngineEvent -SourceIdentifier "MyEventIdentifier" -Action {
Write-EventToConsole $Event
} -SupportEvent

Register-EngineEvent -SourceIdentifier "MyEventIdentifier" -Action {
Save-EventToFile $Event C:\temp\event.txt
} -SupportEvent

检查事件订阅者:
Get-EventSubscriber -Force

SubscriptionId : 1
SourceObject :
EventName :
SourceIdentifier : MyEventIdentifier
Action : System.Management.Automation.PSEventJob
HandlerDelegate :
SupportEvent : True
ForwardEvent : False

SubscriptionId : 2
SourceObject :
EventName :
SourceIdentifier : MyEventIdentifier
Action : System.Management.Automation.PSEventJob
HandlerDelegate :
SupportEvent : True
ForwardEvent : False

SubscriptionId : 3
SourceObject :
EventName :
SourceIdentifier : MyEventIdentifier
Action : System.Management.Automation.PSEventJob
HandlerDelegate :
SupportEvent : True
ForwardEvent : False

现在,如果我们触发一个事件:
$null = New-Event -SourceIdentifier "MyEventIdentifier" `
-Sender "MyObject" `
-EventArguments "Some arguments that I want to pass" `
-MessageData "This is some message data I want to pass"

我们可以看到写入控制台的 2 个事件订阅者被触发:
just write to console
This is some message data I want to pass
MyObject
MyObject
4/5/2019 1:54:27 PM
Some arguments that I want to pass
Some arguments that I want to pass

Write info to the console from a function
This is some message data I want to pass
MyObject
4/5/2019 1:54:27 PM
Some arguments that I want to pass

写入文件的事件订阅者被触发:
Get-Content C:\temp\event.txt

Writing to file
Message Data : This is some message data I want to pass
Sender : MyObject
Time Generated : 4/5/2019 1:54:27 PM
Source Args : Some arguments that I want to pass

最后要删除您可以使用的事件订阅者:
Get-EventSubscriber -Force | `
Where-Object { $_.SourceIdentifier -eq 'MyEventIdentifier' } | `
Unregister-Event -Force

希望这有助于解释这一点。如果没有,请告诉我,我会更新答案以解决任何问题。

编辑:
这也适用于类。这是一个快速示例。请注意,如果您返回一个值,如果您使用 -SupportEvent,它可能无法使用。删除 SupportEvent 会将操作作为 PSEventJob 运行。这将允许您使用 Get-Job 和 Receive-Job 来检索值。
# Define a class
class TestSubscribeEvent
{
# Static method
static [void] DisplayMessage($evt)
{
Write-Host "Written from static handler"
Write-Host $Evt.MessageData
Write-Host $Evt.Sender
Write-Host $Evt.TimeGenerated
Write-Host $Evt.SourceArgs
Write-Host '----------------------------'
}

[string] DisplayMessage2($evt)
{
return "You wont see this if you use supportevent"
}

[void] SetSomeProperty($evt)
{
$this.SomeProperty ="Set from internal instance`n`t{0}`n`t{1}`n`t{2}`n`t{3}" -f $Evt.MessageData, $Evt.Sender, $Evt.TimeGenerated, $Evt.SourceArgs
}

[string] $SomeProperty
}

# Define a class
class TestEvent
{
# Static method
static [void] SendMessage($msg)
{
$null = New-Event -SourceIdentifier "MyEventIdentifier" `
-Sender "MyObject" `
-EventArguments "Sent from static" `
-MessageData $msg
}

[void] SendMessage2($msg)
{
$null = New-Event -SourceIdentifier "MyEventIdentifier" `
-Sender "MyObject" `
-EventArguments "Sent from instance" `
-MessageData $msg
}
}

制作一些对象:
$subObj = New-Object TestSubscribeEvent
$testEvent = New-Object TestEvent

注册一些事件处理程序
#register static handler
Register-EngineEvent -SourceIdentifier "MyEventIdentifier" -Action {
[TestSubscribeEvent]::DisplayMessage($event)
} -SupportEvent

#register instance handler
Register-EngineEvent -SourceIdentifier "MyEventIdentifier" -Action {
$subObj.DisplayMessage2($event)
} -SupportEvent

#register instance handler without Support Event
#this creates a PSEventJob which we swallow with $null, we check it later
$null = Register-EngineEvent -SourceIdentifier "MyEventIdentifier" -Action {
$subObj.DisplayMessage2($event)
}

#register instance handler that updates a property
Register-EngineEvent -SourceIdentifier "MyEventIdentifier" -Action {
$subObj.SetSomeProperty($event)
} -SupportEvent

现在我们将调用事件生成器:
#call static generator
[TestEvent]::SendMessage("Static called message")

这会向控制台生成以下内容:
Written from static handler
Static called message
MyObject
4/9/2019 8:51:20 AM
Sent from static
----------------------------

我们可以看到它是一个静态方法被调用,新事件是在静态方法中创建的,并且静态处理程序得到了它。

我们还可以使用 get-job 来查看 PSEventJob 的运行情况。
Id     Name            PSJobTypeName   State         HasMoreData     Location             Command                  
-- ---- ------------- ----- ----------- -------- -------
47 MyEventIdent... Running True ...

然后您可以使用 Get-Job 47 | Receive-Job -keep得到输出
You wont see this if you use supportevent

请注意,调用返回值并确实使用 SupportEvent 的相同方法的其他处理程序基本上丢失了所有输出。没有创建 PSEventJob,因此输出无处可去。

我们还可以看到在实例对象上设置了该属性。
$subObj.SomeProperty

Set from internal instance
Static called message
MyObject
4/9/2019 9:05:26 AM
System.Object[]

实例版本基本上做同样的事情,只是传递不同的值。
#call instance generator
$testEvent.SendMessage2("Instance called message")

这给出了以下内容:
Written from static handler
Instance called message
MyObject
4/9/2019 9:02:02 AM
Sent from instance
----------------------------

关于powershell - 如何使用类在 PowerShell 中实现事件处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55527673/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com