Windows Vista Forums
Vista Forums Home Join Vista Forums Windows 7 Forum Vista Tutorials Tags
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.

Go Back   Vista Forums > Misc Newsgroups > PowerShell

Vista - Events, events

Reply
 
Old 06-29-2006   #1 (permalink)
Greg Borota


 
 

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 SpecsSystem Spec
Old 07-01-2006   #2 (permalink)
Greg Borota


 
 

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 SpecsSystem Spec
Old 07-01-2006   #3 (permalink)
Alex K. Angelopoulos [MVP]


 
 

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 SpecsSystem Spec
Reply

Thread Tools


Similar Threads
Thread Forum
COM events? PowerShell
Wmi events PowerShell
Events PowerShell


Vista Forums is an independent web site and has not been authorized,
sponsored, or otherwise approved by Microsoft Corporation.
"Windows Vista", the Start Orb, and related materials are trademarks of Microsoft Corp.
© Designer Media Ltd

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46