rusb (libusb のラッパー) を使用して、システムに接続されている USB デバイスの情報を取得します。
1. 依存関係の追加
src-tauri ディレクトリに移動して、以下のコマンドを実行します。
cargo add rusb
※ Windows ではドライバの問題(WinUSBドライバが必要)があるため、単にリストアップするだけであれば cargo add sysinfo などでシステム情報を取得する方が簡単な場合がありますが、ここでは USB 通信の前段階として rusb を紹介します。
2. 実装コード
use rusb::{Device, DeviceDescriptor, Context, UsbContext};
#[derive(serde::Serialize)]
struct UsbDevice {
bus: u8,
address: u8,
vid: u16,
pid: u16,
manufacturer: Option<String>,
product: Option<String>,
}
#[tauri::command]
fn list_usb_devices() -> Result<Vec<UsbDevice>, String> {
let context = Context::new().map_err(|e| e.to_string())?;
let devices = context.devices().map_err(|e| e.to_string())?;
let mut result = Vec::new();
for device in devices.iter() {
let device_desc = device.device_descriptor().map_err(|e| e.to_string())?;
let mut manufacturer = None;
let mut product = None;
// ハンドルを開いてデスクリプタを読み取る
// (権限がないと失敗するため、失敗時は無視してIDのみ返す)
if let Ok(handle) = device.open() {
let timeout = std::time::Duration::from_secs(1);
let languages = handle.read_languages(timeout).unwrap_or_default();
if let Some(&language) = languages.first() {
manufacturer = handle.read_manufacturer_string(language, &device_desc, timeout).ok();
product = handle.read_product_string(language, &device_desc, timeout).ok();
}
}
result.push(UsbDevice {
bus: device.bus_number(),
address: device.address(),
vid: device_desc.vendor_id(),
pid: device_desc.product_id(),
manufacturer,
product,
});
}
Ok(result)
}
注意点
rusb (libusb) でデバイスを開く(open())には、OS 側で適切なドライバ(WindowsならWinUSB、Linuxならudevルール)が設定されている必要があります。単に接続されていることを確認するだけであれば vid / pid のチェックのみで十分です。