用于与人机接口设备(HID)通信的VBA代码

时间:2015-11-23 07:17:46

标签: c# vb.net vba hid rfid

我最近买了一台RFID R / W设备,我想从它发送和接收数据到我已经开发的VBA应用程序。我一直在寻找解决方案,但我找不到任何解决方案。

我想知道是否有任何VBA指令用于接收和发送数据到HID。如果没有,这将是与我的设备进行通信的最简单方式?代码非常简单,只需编写和读取十六进制代码即可。我也可以在vb或C#中管理应用程序。

已正确安装驱动程序及其规格。在链接中:http://www.securakey.com/PRODUCTS/RFID_PRODUCTS/ET4AUS_D_AUM_7656.pdf

谢谢大家。

1 个答案:

答案 0 :(得分:0)

距离我完成VBA编程已有很长时间了,但是您将能够使用C#或VB.Net使用的相同Windows API调用。这是一些枚举Hid设备并进行连接的示例代码。您将需要翻译为VBA。这是VBA https://riptutorial.com/vba/example/31727/windows-api---dedicated-module--1-of-2-中Windows API上的链接。

以下是用于枚举Hid设备的Windows API代码: https://github.com/MelbourneDeveloper/Device.Net/blob/master/src/Device.Net/Windows/WindowsDeviceFactoryBase.cs

           var deviceDefinitions = new Collection<DeviceDefinition>();
            var spDeviceInterfaceData = new SpDeviceInterfaceData();
            var spDeviceInfoData = new SpDeviceInfoData();
            var spDeviceInterfaceDetailData = new SpDeviceInterfaceDetailData();
            spDeviceInterfaceData.CbSize = (uint)Marshal.SizeOf(spDeviceInterfaceData);
            spDeviceInfoData.CbSize = (uint)Marshal.SizeOf(spDeviceInfoData);

            var guidString = ClassGuid.ToString();
            var copyOfClassGuid = new Guid(guidString);

            var i = APICalls.SetupDiGetClassDevs(ref copyOfClassGuid, IntPtr.Zero, IntPtr.Zero, APICalls.DigcfDeviceinterface | APICalls.DigcfPresent);

            if (IntPtr.Size == 8)
            {
                spDeviceInterfaceDetailData.CbSize = 8;
            }
            else
            {
                spDeviceInterfaceDetailData.CbSize = 4 + Marshal.SystemDefaultCharSize;
            }

            var x = -1;

            while (true)
            {
                x++;

                var isSuccess = APICalls.SetupDiEnumDeviceInterfaces(i, IntPtr.Zero, ref copyOfClassGuid, (uint)x, ref spDeviceInterfaceData);
                if (!isSuccess)
                {
                    var errorCode = Marshal.GetLastWin32Error();
                    if (errorCode == APICalls.ERROR_NO_MORE_ITEMS)
                    {
                        break;
                    }

                    throw new Exception($"Could not enumerate devices. Error code: {errorCode}");
                }

                isSuccess = APICalls.SetupDiGetDeviceInterfaceDetail(i, ref spDeviceInterfaceData, ref spDeviceInterfaceDetailData, 256, out _, ref spDeviceInfoData);
                WindowsDeviceBase.HandleError(isSuccess, "Could not get device interface detail");

                //Note this is a bit nasty but we can filter Vid and Pid this way I think...
                var vendorHex = vendorId?.ToString("X").ToLower().PadLeft(4, '0');
                var productIdHex = productId?.ToString("X").ToLower().PadLeft(4, '0');
                if (vendorId.HasValue && !spDeviceInterfaceDetailData.DevicePath.ToLower().Contains(vendorHex)) continue;
                if (productId.HasValue && !spDeviceInterfaceDetailData.DevicePath.ToLower().Contains(productIdHex)) continue;

                var deviceDefinition = GetDeviceDefinition(spDeviceInterfaceDetailData.DevicePath);

                deviceDefinitions.Add(deviceDefinition);
            }

            APICalls.SetupDiDestroyDeviceInfoList(i);

            return deviceDefinitions;

这是连接代码:

public bool Initialize()
{
    Dispose();

    if (DeviceInformation == null)
    {
        throw new WindowsHidException($"{nameof(DeviceInformation)} must be specified before {nameof(Initialize)} can be called.");
    }

    var pointerToPreParsedData = new IntPtr();
    _HidCollectionCapabilities = new HidCollectionCapabilities();
    var pointerToBuffer = Marshal.AllocHGlobal(126);

    _ReadSafeFileHandle = APICalls.CreateFile(DeviceInformation.DeviceId, APICalls.GenericRead | APICalls.GenericWrite, APICalls.FileShareRead | APICalls.FileShareWrite, IntPtr.Zero, APICalls.OpenExisting, 0, IntPtr.Zero);
    _WriteSafeFileHandle = APICalls.CreateFile(DeviceInformation.DeviceId, APICalls.GenericRead | APICalls.GenericWrite, APICalls.FileShareRead | APICalls.FileShareWrite, IntPtr.Zero, APICalls.OpenExisting, 0, IntPtr.Zero);

    if (!HidAPICalls.HidD_GetPreparsedData(_ReadSafeFileHandle, ref pointerToPreParsedData))
    {
        throw new Exception("Could not get pre parsed data");
    }

    var getCapsResult = HidAPICalls.HidP_GetCaps(pointerToPreParsedData, ref _HidCollectionCapabilities);

    //TODO: Deal with issues here

    Marshal.FreeHGlobal(pointerToBuffer);

    var preparsedDataResult = HidAPICalls.HidD_FreePreparsedData(ref pointerToPreParsedData);

    //TODO: Deal with issues here

    if (_ReadSafeFileHandle.IsInvalid)
    {
        return false;
    }

    _ReadFileStream = new FileStream(_ReadSafeFileHandle, FileAccess.ReadWrite, _HidCollectionCapabilities.OutputReportByteLength, false);
    _WriteFileStream = new FileStream(_WriteSafeFileHandle, FileAccess.ReadWrite, _HidCollectionCapabilities.InputReportByteLength, false);

    IsInitialized = true;

    RaiseConnected();

    return true;
}