c# - 与人机接口(interface)设备 (HID) 通信的 VBA 代码

标签 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

谢谢大家

最佳答案

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

这是枚举 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;
}

关于c# - 与人机接口(interface)设备 (HID) 通信的 VBA 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33865536/

相关文章:

vb.net - Visual Studio 宏/任何其他遍历所有项目并设置项目属性

c# - 为什么 System.Design 中的许多 Designer 类都标记为内部类?

vba - 从 excel 打开 word doc 并将所需信息复制到 excel 文件

c# - 如果母版页使用 css 文件,其他文件是否也可以使用该 css 文件?

c# - 使用设置的最大精度格式化十进制数,但没有不需要的尾随零

c# - 单例模式用于创建 Web 服务,但如何处置。

c# - 在功能区 UI 中切换选项卡

c# - 泛型的默认值

excel - 访问由 LinEst 函数产生的数组

arrays - 在数组中查找和返回重复项的更好解决方案 - VBA