![]() |
![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() |
| Welcome to Windows Vista Forums. Our forum is dedicated to helping you find solutions with any problems, errors or issues you are experiencing with Windows Vista. The Vista forum also covers news and updates and has an extensive Windows Vista tutorial section that covers a wide range of tips and tricks. |
| |||||||
![]() |
| |
| | #1 (permalink) |
| | Events, events Is it possible to bind PowerShell code to events generated by a Com object? I'll have a follow-up message with example of what I mean if this is not clear. Thanks, Greg |
My System Specs![]() |
| | #2 (permalink) |
| | COM Events I'll answer myself that question as best as I can, for the benefit of others having to deal with the same issue. Even if you generate an Interop (or already have a PIA) there is no straightforward way to have a Powershell scriptblock act as event sink for a COM event (at least at the time). One reason: PowerShell as it seems, can cast your ScriptBlock only to EventHandler type. But your COM wrappers for events are not of EventHandler type. Example: >$btn = New-Object System.Windows.Forms.Button >($btn | get-member | where {$_.Name -eq "add_Click"}).Definition System.Void add_Click(EventHandler value) > $a=New-Object -COM Word.Application # with Office PIA installed > ($a | get-member | where {$_.Name -eq "add_Quit"}).Definition System.Void add_Quit(ApplicationEvents4_QuitEventHandler ) > $btn.add_Click({"scriptblock"}) # No error > $a.add_Quit({"scriptblock"}) Cannot convert argument "0", with value: ""scriptblock"", for "add_Quit" to type "Microsoft.Office.Interop.Word.ApplicationEvents4_QuitEven tHandler": "Cannot convert value ""scriptblock"" to type "Microsoft.Office.Interop.Word.ApplicationEvents4_QuitEventHandler". Error: "Error binding to target method."" It seems like there is no vanilla PowerShell solution for this at the time being. Greg Greg Borota wrote: > Is it possible to bind PowerShell code to events generated by a Com object? > > I'll have a follow-up message with example of what I mean if this is not > clear. > > Thanks, > Greg > > |
My System Specs![]() |
| | #3 (permalink) |
| | Re: COM Events The one _possible_ solution I see is native use of the script control. "Greg Borota" <borota@gmail.com> wrote in message news:uQe2e4TnGHA.2432@TK2MSFTNGP03.phx.gbl... > I'll answer myself that question as best as I can, for the benefit of > others having to deal with the same issue. A brief coda to this. ![]() There are some "not-quite-native" ways to use COM event handlers, but I don't yet have an easy way to return the data to PS since I can't effectively add PS object refs to a script control. What I _can_ do is load the Script Control into PS, insert some VBScript into it with event handlers hooked up via GetRef(). See the Add-ActiveScript function for PowerShell below, and the following GetIeData.txt script following it. To use it, you do something like this: Add-ActiveScript <somepath>\GetIeData.txt Here are the limitations in this current implementation. + It's not asynchronous - you cannot load the VBScript into PS and continue on your way. Window use is effectively blocked until the script exits. + This does not return data to the PS session directly. It would be possible to do on a per-event basis if I can add a reference to the pipeline to the script, but without that, you either have to raise events directly _or_ capture all events and return them as the result of an invoked function after the script exits. ============================== #Add-ActiveScript function function Add-ActiveScript { Param([string]$Path, [string]$Language = 'VBScript') $sc = New-Object -ComObject ScriptControl $sc.Language = 'VBScript'; # use FSO to avoid Get-Content's linefeed-eatin' behavior $fso = New-Object -ComObject Scripting.FileSystemObject $f = $fso.OpenTextFile($Path, 1, $false, -2) [void]$sc.AddCode($f.ReadAll()) } ============================== 'Get-IeData.txt Const READYSTATE_COMPLETE = 4 set ie = CreateObject _ ("InternetExplorer.Application") ' Begin Callout A ie.navigate "about:blank" Do While ie.ReadyState <> _ READYSTATE_COMPLETE ' Cannot use WScript.* methods w/out WSH as host. 'WScript.Sleep 50 Loop ' End Callout A ' Begin Callout B dim text Set text = ie.document. _ createElement("textarea") text.Value = "type text here" ie.document.body.AppendChild text Dim okButton Set okButton = ie.document. _ createElement("input") okButton.type = "button" okButton.value = "OK" ie.document.body.AppendChild okButton ' End Callout B ' Begin Callout C Dim Finished: Finished = False Set okButton.onclick = _ GetRef("OK_Clicked") ' End Callout C ie.visible = true ' Begin Callout D Do While Not Finished MsgBox "This window keeps the script running until IE closed." Loop ' End Callout D ' Begin Callout E Sub OK_Clicked() MsgBox "Text value returned:" & VbCrLf & text.value _ ' & vbCrLf & "(IE will exit when this box is closed.)" Finished = True ie.Quit End Sub ' End Callout E |
My System Specs![]() |
![]() |
| Thread Tools | |
| |
Similar Threads | ||||
| Thread | Forum | |||
| COM events? | PowerShell | |||
| Wmi events | PowerShell | |||
| Events | PowerShell | |||