问题
I need some help implementing asynchronous events in Powershell.
As a testbed for a larger HID project I want to use Powershell to read the data from a usb panic button that I got off amazon. The perfect solution would implement the data callback as an event that could then be registered using Register-ObjectEvent.
My current approach is to use the Hidlibrary library. I am having difficulty invoking both the Read() or ReadReport() methods. They do not appear to be typical asynccallbacks and the standard solution of using New-ScriptBlockCallback does not work.
What I have so far that works and allows me to pull a readhandle.
Add-Type -Path .\Projects\UsbPanicButton\HidLibrary.dll
$device = [HidLibrary.HidDevices]::GetDevice('\\?\hid#vid_1130&pid_0202&mi_00#7&29add023&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}')
$device.OpenDevice()
This does not work. (Cannot find an overload)
$device.ReadReport((New-ScriptBlockCallback {Write-host "HI"}))
How can I convert the ReadReport method into an event that can be registered?
回答1:
The ReadReport method signature:
public delegate void ReadReportCallback(HidReport report);
Isn't a fit for New-ScriptBlockCallback. It works with methods taking an AsyncCallback parameter. IF you know the callback is called on the creating thread during the ReadReport method call you can use:
$device.ReadReport({param($hidReport) $hidReport.ReadStatus })
If it is called back on a different thread, try this modified version of the New-ScriptBlockCallback function:
function New-ScriptBlockCallback {
param(
[parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[scriptblock]$Callback
)
if (-not ("CallbackEventBridge" -as [type])) {
Add-Type @"
using System;
using HidLibrary;
public sealed class CallbackEventBridge
{
public event HidDevice.ReadReportCallback CallbackComplete = delegate { };
private CallbackEventBridge() {}
private void CallbackInternal(HidReport report)
{
CallbackComplete(report);
}
public HidDevice.ReadReportCallback Callback
{
get { return new HidDevice.ReadReportCallback(CallbackInternal); }
}
public static CallbackEventBridge Create()
{
return new CallbackEventBridge();
}
}
"@
}
$bridge = [callbackeventbridge]::create()
Register-ObjectEvent -input $bridge -EventName callbackcomplete -action $callback -messagedata $args > $null
$bridge.callback
}
来源:https://stackoverflow.com/questions/19102154/powershell-asynccallback-events-using-hidlibrary