用于与人机接口设备(HID)通信的VBA代码
本文关键字:通信 VBA 代码 HID 人机接口 用于 | 更新日期: 2023-09-27 18:23:57
我最近买了一个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;
}