Powershell:使用Hidlibrary的AsyncCallback事件

时间:2013-09-30 19:24:20

标签: powershell dll hid asynccallback

我需要一些帮助在Powershell中实现异步事件。

作为一个更大的HID项目的测试平台,我想使用Powershell从亚马逊的usb恐慌按钮中读取数据。完美的解决方案将数据回调实现为可以使用Register-ObjectEvent注册的事件。

我目前的方法是使用Hidlibrary库。我无法同时调用Read()或ReadReport()方法。它们似乎不是典型的asynccallbacks,使用New-ScriptBlockCallback的标准解决方案不起作用。

到目前为止,我的工作原理是允许我拉一个读句柄。

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()

这不起作用。 (找不到超载)

$device.ReadReport((New-ScriptBlockCallback {Write-host "HI"}))

如何将ReadReport方法转换为可以注册的事件?

1 个答案:

答案 0 :(得分:2)

ReadReport方法签名:

public delegate void ReadReportCallback(HidReport report);

不适合New-ScriptBlockCallback。它适用于采用AsyncCallback参数的方法。 IF 你知道在你可以使用的ReadReport方法调用期间在创建线程上调用回调:

$device.ReadReport({param($hidReport) $hidReport.ReadStatus })

如果在另一个线程上回调它,请尝试使用New-ScriptBlockCallback函数的这个修改版本:

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
}