zoukankan      html  css  js  c++  java
  • PowerShell处理Excel事件

      1 <#
      2 以下是PowerShell 5.0的Get-Event命令的部分帮助信息,可借此了解事件发生时默认情况传递给事件处理程序的参数:
      3        
      4 The Get-Event cmdlet returns a PSEventArgs object ( System.Management.Automation.PSEventArgs ) with the following properties:
      5         
      6 - ComputerName. The name of the computer on which the event occurred. This property value is populated only when the event is forw
      7 arded from a remote computer.
      8         
      9 - RunspaceId. A GUID that uniquely identifies the session in which the event occurred. This property value is populated only when 
     10 the event is forwarded from a remote computer.
     11         
     12 - EventIdentifier. An integer (Int32) that uniquely identifies the event notification in the current session.
     13         
     14 - Sender. The object that generated the event. In the value of the Action parameter, the $Sender automatic variable contains the s
     15 ender object.
     16         
     17 - SourceEventArgs. The first parameter that derives from EventArgs, if it exists. For example, in a timer elapsed event in which t
     18 he signature has the form Object sender, Timers.ElapsedEventArgs e, the SourceEventArgs property would contain the Timers.ElapsedE
     19 ventArgs. In the value of the Action parameter, the $EventArgs automatic variable contains this value.
     20         
     21 - SourceArgs. All parameters of the original event signature. For a standard event signature, $Args[0] represents the sender, and 
     22 $Args[1] represents the SourceEventArgs. In the value of the Action parameter, the $Args automatic variable contains this value.
     23         
     24 - SourceIdentifier. A string that identifies the event subscription. In the value of the Action parameter, the SourceIdentifier pr
     25 operty of the $Event automatic variable contains this value.
     26         
     27 - TimeGenerated. A DateTime object that represents the time at which the event was generated. In the value of the Action parameter
     28 , the TimeGenerated property of the $Event automatic variable contains this value.
     29         
     30 - MessageData. Data associated with the event subscription. Users specify this data when they register an event. In the value of t
     31 he Action parameter, the MessageData property of the $Event automatic variable contains this value.
     32 
     33 以下是摘自PowerShell 2.0的Get-Event命令的部分帮助信息:
     34         
     35 Get-Event cmdlet 返回具有以下属性的 PSEventArgs 对象 (System.Management.Automation.PSEventArgs)。
     36 
     37 -- ComputerName:发生该事件的计算机的名称。只有在从远程计算机转发该事件时,才填充此属性值。
     38 
     39 -- RunspaceId:一个 GUID,用于唯一标识该事件发生时所在的会话。只有在从远程计算机转发该事件时,才填充此属性值。
     40 
     41 -- EventIdentifier:一个整数 (Int32),用于唯一标识当前会话中的事件通知。
     42 
     43 -- Sender:生成事件的对象。在 Action 参数的值中,$Sender 自动变量包含发送方对象。
     44 
     45 -- SourceEventArgs:从 EventArgs 派生的第一个参数(如果存在)。例如,在签名形式为“Object sender, Timers.ElapsedEventArgs e”的 
     46 
     47    Timer Elapsed 事件中,SourceEventArgs 属性包含 Timers.ElapsedEventArgs。在 Action 参数的值中,$SourceEventArgs 自动变量包含此值。
     48 
     49    【在5.0中是$EventArgs 50 
     51 -- SourceArgs:原始事件签名的所有参数。对于标准事件签名,$args[0] 表示发送方,$args[1] 表示 SourceEventArgs。
     52 
     53    在 Action 参数的值中,$SourceArgs 自动变量包含此值。【在5.0中是$Args]
     54 
     55 -- SourceIdentifier:用于标识事件订阅的字符串。在 Action 参数的值中,$Event 自动变量的 SourceIdentifier 属性包含此值。
     56 
     57 -- TimeGenerated:一个 DateTime 对象,表示事件的生成时间。在 Action 参数的值中,$Event 自动变量的 TimeGenerated 属性包含此值。
     58 
     59 -- MessageData:与事件订阅关联的数据。用户在注册事件时指定此数据。在 Action 参数的值中,$Event 自动变量的 MessageData 属性包含此值。
     60 
     61 
     62 总结如下【试验平台是PowerShell 5.0】:
     63 [1]Action中可用自动变量为:$Event/$Sender/$EventArgs/$Args
     64 [2]由$Event自动变量,可获取ComputerName/RunspaceId/EventIdentifier/Sender/SourceEventArgs/SourceIdentifier/TimeGenerated/MessageData 
     65 [3]虽然$Event自动变量对象拥有SourceArgs属性,但是无法通过$Event.SourceArgs来访问,请使用$Args自动变量来访问该属性
     66 [4]$Sender和$Event.Sender都是可用的访问途径
     67 
     68 关于事件:
     69 [1]SourceIdentifier参数总是区分大小写的,且同一个名称的SourceIdentifier只能定义一个订阅者
     70 [2]对于通过Action参数指定了事件处理程序的订阅,请将代码以Try{...}Catch{...}括起来,否则如果其中有一个语句执行出错,都会导致事件处理程序所在的PSEventJob
     71    终止,永远不会在处理它所订阅的事件了
     72 [3]通过Register-*Event命令的返回值(Action所在的PSEventJob),可以获取事件处理程序的执行信息,包括最关键的返回值(Output)信息和错误(Error)信息,当然
     73    如果你只是订阅事件,而不指定Action事件处理程序,那么订阅命令返回的将是$null,只有指定了Action参数的订阅命令才会返回对应的PSEventJob
     74 [4]如果事件处理程序提供了返回值,请注意在每次触发事件之前,清空上次触发事件时由事件处理程序返回的值,$PSEventJob.Output.Clear();
     75 [5]同4,如果你也关注事件处理程序的错误信息,也请记得每次触发事件之前,清空上次触发事件处理程序时执行后产生的错误信息,$PSEventJob.Error.Clear()
     76 [6]通过Get-EventSubscriber可获得PSEventSubscriber对象,该对象有一个Action参数,它是指向上述PSEventJob对象的属性,你也可以由此来访问事件处理程序的执行
     77    信息,当然如果对应的订阅者没有指定Action,那么此时的该属性是$null;因为这是一个只读
     78 [7]对于外部对象(非Engine)触发的事件,请保证事件未被处理过,否则你定义的事件处理程序是不会执行的,比如你的Excel文件本身定义了Worksheet_Change VBA事件处理
     79    程序,你又在PowerShell中定义了一个针对这个事件的事件处理程序,那么PowerShell中定义的这个事件处理程序,将接收不到事件,因为事件已经被内置的VBA处理过了
     80 [8]PSEventJob对象中,除了Output/Error这两个关键性的属性之外,还有其它如Command/HasMoreData/State/Progress/Verbose/Debug/Warning/Information等
     81 #>
     82 Clear-Host
     83 $excel = New-Object -ComObject Excel.Application
     84 $wb = $excel.Workbooks.Add()
     85 $sht = $wb.Worksheets[1]
     86 $ej = Register-ObjectEvent -InputObject $excel -EventName SheetChange -SourceIdentifier Excel.SheetChange -Action { 
     87         Write-Host “[0]`$Event($($Event.GetType().FullName))自动变量拥有的属性:”
     88         $Event | format-list | Out-Host
     89         Write-Host [1] ('ComputerName: {0}' -f $Event.ComputerName)
     90         Write-Host [2] $Event.RunspaceId
     91         Write-Host [3] $Event.EventIdentifier
     92         Write-Host [4] $Event.Sender
     93         Write-Host [5] ($Event.SourceEventArgs -eq $null)
     94         #无任何输出,可见该成员虽然存在于$Event的属性中,却是无法访问的,请使用$Args替代
     95         Write-Host [6] ($Event.SourceArgs -eq $null)
     96         Write-Host [7] $Event.SourceIdentifier
     97         Write-Host [8] $Event.TimeGenerated
     98         Write-Host [9] $Event.MessageData
     99         Write-Host ('-' * 10)
    100         $Target = $Args[1]
    101         Write-Host [1] $Target.Address()
    102         #读取单元格的值时,请务必使用Value2,原来的Value属性是一个对象,不知为何
    103         write-host [2] $Target.Value2
    104         Write-Host [3] $Args.Count
    105         Write-Host [4] $Args[0].Name
    106         #竟然为$false,不知为何
    107         Write-Host [5] ($Args[0] -eq $sht)
    108         #按理本该返回$true,竟然无输出,不知为何
    109         Write-Host [6] ($Target -eq $sht.Range('A1'))
    110         Write-Host [7] $Sender.Name
    111         Write-Host [8] ($Sender -eq $excel)
    112         #下面的语句返回两个值
    113         $Target.Address()
    114         $Target.Value2
    115         #以下选择性的引发一个错误,试试看订阅者对象会有什么变化
    116         if($Target.Address() -eq '$B$1'){ 1 / 0 }
    117         #以下的语句都不会执行,因为上面出错了,处理程序被中断执行
    118         #比如下面再返回一个值,它不被执行,所以返回的值不会出现在返回值属性中,但之前返回的值是会出现的
    119         $Args[0].Name
    120 } -MessageData "SheetChange Event Happened!" 
    121 Write-Host 第一次执行
    122 $sht.Cells(1, 1).Value = 'hello'
    123 #等待事件响应
    124 Start-Sleep 2
    125 Write-Host ('-' * 10)
    126 Write-Host '[0]PSEventJob对象包含的信息如下:'
    127 $ej | Format-List | Out-Host
    128 Write-Host '[1]本次事件处理程序的返回值:' $ej.Output
    129 Write-Host '[2]本次事件处理程序的错误信息:' $ej.Error
    130 
    131 Write-Host ('=' * 80)
    132 write-host 第二次触发事件
    133 #注意PSEventJob对象是一以贯之的,后续的再次触发事件,相关的返回值与错误信息都会追加到对应的属性中
    134 #为了不影响后续响应事件后的对该对象的读取,请在再次触发事件之前,清空对应属性的历史值
    135 $ej.Output.Clear()
    136 $ej.Error.Clear()
    137 #再触发一次事件,并禁止会引发错误的语句的执行
    138 $sht.Cells(1, 2).Value = 123
    139 #等待事件响应
    140 Start-Sleep 2
    141 Write-Host ('-' * 10)
    142 Write-Host '[0]PSEventJob对象包含的信息如下:'
    143 $ej | Format-List | Out-Host
    144 Write-Host '[1]本次事件处理程序的返回值:' $ej.Output
    145 Write-Host '[2]本次事件处理程序的错误信息:' $ej.Error
    146 
    147 Write-Host ('=' * 80)
    148 write-host 第三次触发事件:因为上次事件处理程序的执行引发了错误,所以本次事件处理程序不会被执行,你不会得到任何有用的信息
    149 #注意PSEventJob对象是一以贯之的,后续的再次触发事件,相关的返回值与错误信息都会追加到对应的属性中
    150 #为了不影响续响应事件后的对该对象的读取,请在再次触发事件之前,清空对应属性的历史值
    151 $ej.Output.Clear()
    152 $ej.Error.Clear()
    153 #再触发一次事件,并禁止会引发错误的语句的执行
    154 $sht.Cells(1, 3).Value = $true
    155 #等待事件响应
    156 Start-Sleep 2
    157 Write-Host ('-' * 10)
    158 Write-Host '[0]PSEventJob对象包含的信息如下:'
    159 $ej | Format-List | Out-Host
    160 Write-Host '[1]本次事件处理程序的返回值:' $ej.Output
    161 Write-Host '[2]本次事件处理程序的错误信息:' $ej.Error
    162 $wb.Close($false)
    163 $excel.Quit()
    164 Unregister-Event Excel.SheetChange

    其执行结果如下:

    第一次执行
    [0]$Event(System.Management.Automation.PSEventArgs)自动变量拥有的属性:
    
    
    ComputerName     : 
    RunspaceId       : 9f5bacb7-9cfe-4de8-9519-a0a229015b4a
    EventIdentifier  : 95
    Sender           : Microsoft.Office.Interop.Excel.ApplicationClass
    SourceEventArgs  : 
    SourceArgs       : {System.__ComObject, System.__ComObject}
    SourceIdentifier : Excel.SheetChange
    TimeGenerated    : 2018/5/3 22:58:39
    MessageData      : SheetChange Event Happened!
    
    
    
    [1] ComputerName: 
    [2] 9f5bacb7-9cfe-4de8-9519-a0a229015b4a
    [3] 95
    [4] Microsoft.Office.Interop.Excel.ApplicationClass
    [5] True
    [6] 
    [7] Excel.SheetChange
    [8] 2018/5/3 22:58:39
    [9] SheetChange Event Happened!
    ----------
    [1] $A$1
    [2] hello
    [3] 2
    [4] Sheet1
    [5] False
    [6] 
    [7] Microsoft Excel
    [8] True
    ----------
    [0]PSEventJob对象包含的信息如下:
    
    
    Module        : __DynamicModule_02abd41c-55a4-4b10-a18b-487c09278af2
    StatusMessage : 
    HasMoreData   : True
    Location      : 
    Command       :  
                            Write-Host “[0]`$Event($($Event.GetType().FullName))自动变量拥有的属性:”
                            $Event | format-list | Out-Host
                            Write-Host [1] ('ComputerName: {0}' -f $Event.ComputerName)
                            Write-Host [2] $Event.RunspaceId
                            Write-Host [3] $Event.EventIdentifier
                            Write-Host [4] $Event.Sender
                            Write-Host [5] ($Event.SourceEventArgs -eq $null)
                            #无任何输出,可见该成员虽然存在于$Event的属性中,却是无法访问的,请使用$Args替代
                            Write-Host [6] ($Event.SourceArgs -eq $null)
                            Write-Host [7] $Event.SourceIdentifier
                            Write-Host [8] $Event.TimeGenerated
                            Write-Host [9] $Event.MessageData
                            Write-Host ('-' * 10)
                            $Target = $Args[1]
                            Write-Host [1] $Target.Address()
                            #读取单元格的值时,请务必使用Value2,原来的Value属性是一个对象,不知为何
                            write-host [2] $Target.Value2
                            Write-Host [3] $Args.Count
                            Write-Host [4] $Args[0].Name
                            #竟然为$false,不知为何
                            Write-Host [5] ($Args[0] -eq $sht)
                            #按理本该返回$true,竟然无输出,不知为何
                            Write-Host [6] ($Target -eq $sht.Range('A1'))
                            Write-Host [7] $Sender.Name
                            Write-Host [8] ($Sender -eq $excel)
                            #下面的语句返回两个值
                            $Target.Address()
                            $Target.Value2
                            #以下选择性的引发一个错误,试试看订阅者对象会有什么变化
                            if($Target.Address() -eq '$B$1'){ 1 / 0 }
                            #以下的语句都不会执行,因为上面出错了,处理程序被中断执行
                            #比如下面再返回一个值,它不被执行,所以返回的值不会出现在返回值属性中,但之前返回的值是会出现的
                            $Args[0].Name
                    
    JobStateInfo  : Running
    Finished      : System.Threading.ManualResetEvent
    InstanceId    : 554ab3e2-08ae-4a60-a078-8dd99bc07841
    Id            : 38
    Name          : Excel.SheetChange
    ChildJobs     : {}
    PSBeginTime   : 2018/5/3 22:58:39
    PSEndTime     : 
    PSJobTypeName : 
    Output        : {$A$1, hello, Sheet1}
    Error         : {}
    Progress      : {}
    Verbose       : {}
    Debug         : {}
    Warning       : {}
    Information   : {}
    State         : Running
    
    
    
    [1]本次事件处理程序的返回值: $A$1 hello Sheet1
    [2]本次事件处理程序的错误信息: 
    ================================================================================
    第二次触发事件
    [0]$Event(System.Management.Automation.PSEventArgs)自动变量拥有的属性:
    
    
    ComputerName     : 
    RunspaceId       : 9f5bacb7-9cfe-4de8-9519-a0a229015b4a
    EventIdentifier  : 96
    Sender           : Microsoft.Office.Interop.Excel.ApplicationClass
    SourceEventArgs  : 
    SourceArgs       : {System.__ComObject, System.__ComObject}
    SourceIdentifier : Excel.SheetChange
    TimeGenerated    : 2018/5/3 22:58:41
    MessageData      : SheetChange Event Happened!
    
    
    
    [1] ComputerName: 
    [2] 9f5bacb7-9cfe-4de8-9519-a0a229015b4a
    [3] 96
    [4] Microsoft.Office.Interop.Excel.ApplicationClass
    [5] True
    [6] 
    [7] Excel.SheetChange
    [8] 2018/5/3 22:58:41
    [9] SheetChange Event Happened!
    ----------
    [1] $B$1
    [2] 123
    [3] 2
    [4] Sheet1
    [5] False
    [6] 
    [7] Microsoft Excel
    [8] True
    ----------
    [0]PSEventJob对象包含的信息如下:
    
    
    Module        : __DynamicModule_02abd41c-55a4-4b10-a18b-487c09278af2
    StatusMessage : 
    HasMoreData   : True
    Location      : 
    Command       :  
                            Write-Host “[0]`$Event($($Event.GetType().FullName))自动变量拥有的属性:”
                            $Event | format-list | Out-Host
                            Write-Host [1] ('ComputerName: {0}' -f $Event.ComputerName)
                            Write-Host [2] $Event.RunspaceId
                            Write-Host [3] $Event.EventIdentifier
                            Write-Host [4] $Event.Sender
                            Write-Host [5] ($Event.SourceEventArgs -eq $null)
                            #无任何输出,可见该成员虽然存在于$Event的属性中,却是无法访问的,请使用$Args替代
                            Write-Host [6] ($Event.SourceArgs -eq $null)
                            Write-Host [7] $Event.SourceIdentifier
                            Write-Host [8] $Event.TimeGenerated
                            Write-Host [9] $Event.MessageData
                            Write-Host ('-' * 10)
                            $Target = $Args[1]
                            Write-Host [1] $Target.Address()
                            #读取单元格的值时,请务必使用Value2,原来的Value属性是一个对象,不知为何
                            write-host [2] $Target.Value2
                            Write-Host [3] $Args.Count
                            Write-Host [4] $Args[0].Name
                            #竟然为$false,不知为何
                            Write-Host [5] ($Args[0] -eq $sht)
                            #按理本该返回$true,竟然无输出,不知为何
                            Write-Host [6] ($Target -eq $sht.Range('A1'))
                            Write-Host [7] $Sender.Name
                            Write-Host [8] ($Sender -eq $excel)
                            #下面的语句返回两个值
                            $Target.Address()
                            $Target.Value2
                            #以下选择性的引发一个错误,试试看订阅者对象会有什么变化
                            if($Target.Address() -eq '$B$1'){ 1 / 0 }
                            #以下的语句都不会执行,因为上面出错了,处理程序被中断执行
                            #比如下面再返回一个值,它不被执行,所以返回的值不会出现在返回值属性中,但之前返回的值是会出现的
                            $Args[0].Name
                    
    JobStateInfo  : Failed
    Finished      : System.Threading.ManualResetEvent
    InstanceId    : 554ab3e2-08ae-4a60-a078-8dd99bc07841
    Id            : 38
    Name          : Excel.SheetChange
    ChildJobs     : {}
    PSBeginTime   : 2018/5/3 22:58:39
    PSEndTime     : 2018/5/3 22:58:41
    PSJobTypeName : 
    Output        : {$B$1, 123}
    Error         : {Attempted to divide by zero.}
    Progress      : {}
    Verbose       : {}
    Debug         : {}
    Warning       : {}
    Information   : {}
    State         : Failed
    
    
    
    [1]本次事件处理程序的返回值: $B$1 123
    [2]本次事件处理程序的错误信息: Attempted to divide by zero.
    ================================================================================
    第三次触发事件:因为上次事件处理程序的执行引发了错误,所以本次事件处理程序不会被执行,你不会得到任何有用的信息
    ----------
    [0]PSEventJob对象包含的信息如下:
    
    
    Module        : __DynamicModule_02abd41c-55a4-4b10-a18b-487c09278af2
    StatusMessage : 
    HasMoreData   : True
    Location      : 
    Command       :  
                            Write-Host “[0]`$Event($($Event.GetType().FullName))自动变量拥有的属性:”
                            $Event | format-list | Out-Host
                            Write-Host [1] ('ComputerName: {0}' -f $Event.ComputerName)
                            Write-Host [2] $Event.RunspaceId
                            Write-Host [3] $Event.EventIdentifier
                            Write-Host [4] $Event.Sender
                            Write-Host [5] ($Event.SourceEventArgs -eq $null)
                            #无任何输出,可见该成员虽然存在于$Event的属性中,却是无法访问的,请使用$Args替代
                            Write-Host [6] ($Event.SourceArgs -eq $null)
                            Write-Host [7] $Event.SourceIdentifier
                            Write-Host [8] $Event.TimeGenerated
                            Write-Host [9] $Event.MessageData
                            Write-Host ('-' * 10)
                            $Target = $Args[1]
                            Write-Host [1] $Target.Address()
                            #读取单元格的值时,请务必使用Value2,原来的Value属性是一个对象,不知为何
                            write-host [2] $Target.Value2
                            Write-Host [3] $Args.Count
                            Write-Host [4] $Args[0].Name
                            #竟然为$false,不知为何
                            Write-Host [5] ($Args[0] -eq $sht)
                            #按理本该返回$true,竟然无输出,不知为何
                            Write-Host [6] ($Target -eq $sht.Range('A1'))
                            Write-Host [7] $Sender.Name
                            Write-Host [8] ($Sender -eq $excel)
                            #下面的语句返回两个值
                            $Target.Address()
                            $Target.Value2
                            #以下选择性的引发一个错误,试试看订阅者对象会有什么变化
                            if($Target.Address() -eq '$B$1'){ 1 / 0 }
                            #以下的语句都不会执行,因为上面出错了,处理程序被中断执行
                            #比如下面再返回一个值,它不被执行,所以返回的值不会出现在返回值属性中,但之前返回的值是会出现的
                            $Args[0].Name
                    
    JobStateInfo  : Failed
    Finished      : System.Threading.ManualResetEvent
    InstanceId    : 554ab3e2-08ae-4a60-a078-8dd99bc07841
    Id            : 38
    Name          : Excel.SheetChange
    ChildJobs     : {}
    PSBeginTime   : 2018/5/3 22:58:39
    PSEndTime     : 2018/5/3 22:58:41
    PSJobTypeName : 
    Output        : {}
    Error         : {}
    Progress      : {}
    Verbose       : {}
    Debug         : {}
    Warning       : {}
    Information   : {}
    State         : Failed
    
    
    
    [1]本次事件处理程序的返回值: 
    [2]本次事件处理程序的错误信息: 
  • 相关阅读:
    4.Docker Compose 部署 Nexus
    3.Docker Compose 部署 GitLab
    2.Docker Compose 部署应用程序
    1.Docker Compose
    6.Dockerfile 指令
    5.Dockerfile 定制镜像
    4.Docker 操作容器
    3.Docker 操作镜像
    2.Ubuntu安装 Docker
    windows快捷键
  • 原文地址:https://www.cnblogs.com/nutix/p/8988055.html
Copyright © 2011-2022 走看看