java JNA检测音频设备到达/删除
我看到了一些关于这方面的问题,但没有一个对我需要做的事情有帮助
我正在使用JNA来帮助我检测USB设备何时插入/移除
插入/卸下USB驱动器(加密狗)时会收到DBT_DEVICEARRIVAL
和DBT_DEVICEREMOVECOMPLETE
事件。但是,当插入/删除音频接口时,不会接收这些事件,只会接收DBT_DEVNODES_CHANGES
DBT_DEVNODES_CHANGES
不保存有关设备的任何信息,因为LPRAM始终为0
我想我需要做的是检测这些DBT_DEVNODES_CHANGES
事件,并在它们上枚举我的USB设备以识别发生了什么变化?但是如何通过JNA访问所有USB设备呢
到目前为止,我的代码如下(精简):
package com.company;
import com.sun.jna.Callback;
import com.sun.jna.FromNativeContext;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.*;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIOptions;
import libs.User32;
import javax.swing.*;
public class MyForm
{
private JPanel top_panel;
public static final com.sun.jna.platform.win32.Guid.GUID GUID_DEVINTERFACE_USB_DEVICE = new Guid.GUID(new byte[] {
(byte)0xA5, (byte)0xDC, (byte)0xBF, 0x10, 0x65, 0x30, 0x11, (byte)0xD2, (byte)0x90, 0x1F, 0x00, (byte)0xC0, 0x4F, (byte)0xB9, 0x51, (byte)0xED
});
public interface MyUser32 extends User32
{
public static final MyUser32 MYINSTANCE = (MyUser32) Native.loadLibrary("user32", MyUser32.class, W32APIOptions.UNICODE_OPTIONS);
public static final int GWLP_WNDPROC = -4;
public int SetWindowLong(WinDef.HWND hWnd, int nIndex, Callback callback);
public int RegisterDeviceNotification(WinNT.HANDLE hRecipient, Pointer NotificationFilter, int Flags);
}
public interface MyWinUser extends WinUser
{
public static final int WM_DEVICECHANGE = 0x0219;
public static final int DBT_DEVICEARRIVAL = 0x8000;
public static final int DBT_DEVICEREMOVECOMPLETE = 0x8004;
public static final int DBT_DEVNODES_CHANGED = 0x0007;
}
//Create the callback interface
public interface MyListener extends StdCallLibrary.StdCallCallback
{
public WinDef.LRESULT callback(WinDef.HWND hWnd, int uMsg, WinDef.WPARAM uParam, WinDef.LPARAM lParam);
}
public static MyListener listener = new MyListener()
{
public WinDef.LRESULT callback(WinDef.HWND hWnd, int uMsg, WinDef.WPARAM uParam, WinDef.LPARAM lParam)
{
if (uMsg == MyWinUser.WM_DEVICECHANGE)
{
if(uParam.intValue() == MyWinUser.DBT_DEVICEARRIVAL)
{
System.out.println("Device was added");
}
if(uParam.intValue() == MyWinUser.DBT_DEVICEREMOVECOMPLETE)
{
System.out.println("Device was removed");
}
if(uParam.intValue() == MyWinUser.DBT_DEVNODES_CHANGED)
{
System.out.println("Device node changed" + lParam.longValue());
}
return new WinDef.LRESULT(1);
}
return new WinDef.LRESULT(0);
}
};
public static void main(String[] args)
{
JFrame frame = new JFrame("MyForm");
frame.setContentPane(new MyForm().top_panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
WinDef.HWND hWnd = new WinDef.HWND();
hWnd.setPointer(Native.getWindowPointer(frame));
MyUser32.MYINSTANCE.SetWindowLong(hWnd,MyUser32.GWLP_WNDPROC,listener);
}
}
编辑:我已开始在收到到达/移除事件后获取设备,并手动检测连接或移除的设备。首先调用SetupDiGetClassDevs工作正常,我能够使用SetupDiEnumDeviceInfo进行迭代。之后,我将调用SetupDienumDeviceInterface,以获取调用SetupDiGetDeviceInterface Detail时所需的SP_设备_接口_数据,这将最终使我能够访问有关设备的供应商、产品等信息
问题是,调用SetupDiEnumDeviceInfo时,我会立即收到一个错误\u NO\u更多\u项
您可以在下面看到我的代码:
com.sun.jna.Pointer enume = new Pointer(0);
WinNT.HANDLE hDevInfo = SetupAPI.INSTANCE.SetupDiGetClassDevs(null,enume,hWnd.getPointer(),SetupAPI.DIGCF_PRESENT | SetupAPI.DIGCF_ALLCLASSES);
SetupAPI.SP_DEVINFO_DATA spDevInfoData = new SetupAPI.SP_DEVINFO_DATA();
spDevInfoData.cbSize = spDevInfoData.size();
int i = 0;
while(SetupAPI.INSTANCE.SetupDiEnumDeviceInfo(hDevInfo, i, spDevInfoData))
{
i++;
IntByReference requiredSize = null;
SetupAPI.SP_DEVICE_INTERFACE_DATA devInterfaceData = new SetupAPI.SP_DEVICE_INTERFACE_DATA();
int j = 0;
while(SetupAPI.INSTANCE.SetupDiEnumDeviceInterfaces(hDevInfo,spDevInfoData.getPointer(),spDevInfoData.InterfaceClassGuid,j,devInterfaceData))
{
j++;
if(Native.getLastError() == ERROR_NO_MORE_ITEMS)
{
System.out.println("No more items to enumerate");
}
}
SetupAPI.SP_DEVINFO_DATA deviceInfoData = new SetupAPI.SP_DEVINFO_DATA();
deviceInfoData.cbSize = deviceInfoData.size();
boolean test2 = SetupAPI.INSTANCE.SetupDiGetDeviceInterfaceDetail(hDevInfo,devInterfaceData,null,0,requiredSize,deviceInfoData);
int error = Native.getLastError();
test2 = true;
}
# 1 楼答案
我无法用当前的实现解决我的问题,但我很幸运地偶然发现了一个实现了我所需要的东西的库。因为我不能简单地发布一个链接(违反规则),所以我在这里发布了完整的类,因为方法与我自己的完全不同,我不能指出代码中帮助我让自己的实现工作的部分