我对 Mac OS X 操作系统的接触有限,现在我已经开始使用 Xcode 并正在研究 I/O 套件。我需要在命令行工具下在 Xcode 中创建一个程序,以便列出 Mac 系统中连接的所有 USB 设备。请有过这方面经验的人帮帮我。如果有人可以向我提供示例代码,那么它将很有用,因为我正在寻找起点。
您可以根据您的需求调整USBPrivateDataSample,该示例设置通知程序,列出当前连接的设备,然后等待设备连接/分离。如果这样做,您将需要删除
usbVendor
和 usbProduct
匹配字典,以便所有 USB 设备都匹配。
IOServiceGetMatchingServices
来获取所有当前匹配服务的迭代器,使用由 IOServiceMatching(kIOUSBDeviceClassName)
创建的字典。
这是一个简短的示例(我从未运行过):
#include <IOKit/IOKitLib.h>
#include <IOKit/usb/IOUSBLib.h>
int main(int argc, const char *argv[])
{
CFMutableDictionaryRef matchingDict;
io_iterator_t iter;
kern_return_t kr;
io_service_t device;
/* set up a matching dictionary for the class */
matchingDict = IOServiceMatching(kIOUSBDeviceClassName);
if (matchingDict == NULL)
{
return -1; // fail
}
/* Now we have a dictionary, get an iterator.*/
kr = IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, &iter);
if (kr != KERN_SUCCESS)
{
return -1;
}
/* iterate */
while ((device = IOIteratorNext(iter)))
{
/* do something with device, eg. check properties */
/* ... */
/* And free the reference taken before continuing to the next item */
IOObjectRelease(device);
}
/* Done, release the iterator */
IOObjectRelease(iter);
return 0;
}
您只需要访问 IOKit Registry。您或许可以使用
ioreg
工具来执行此操作(例如通过 system()
或 popen()
运行它)。如果没有,那么您至少可以使用它来验证您的代码:
有关
ioreg
工具的信息:
$ man ioreg
获取 USB 设备列表:
$ ioreg -Src IOUSBDevice
如果您运行
system_profiler SPUSBDataType
,它将列出连接到系统的所有 USB 设备,然后您可以通过将其转储到文本文件中或从命令将其读入应用程序并在那里使用来与该数据进行交互。
这里有一个 Swift 版本,用于列出已连接的 USB 设备:
import IOKit
import IOKit.ps
import IOKit.usb
func findMatchingPorts() -> Bool {
print("------------------")
print("findMatchingPorts")
print("------------------")
var matchingDict : CFMutableDictionary?
var iter : io_iterator_t = 0
var kr : kern_return_t
var device : io_service_t
/* set up a matching dictionary for the class */
matchingDict = IOServiceMatching(kIOUSBDeviceClassName)
if matchingDict == nil {
// no matching ports
print("no matching ports")
return false
}
/* Now we have a dictionary, get an iterator.*/
kr = IOServiceGetMatchingServices(
kIOMasterPortDefault,
matchingDict,
&iter
)
if (kr != KERN_SUCCESS) {
// fail
print("fail")
return false
}
/* iterate */
repeat {
device = IOIteratorNext(iter)
guard device != 0 else {
break
}
/* do something with device, eg. check properties */
/* ... */
/* And free the reference taken before continuing to the next item */
print("device: \(device)")
print(device.name())
// release device reference
IOObjectRelease(device)
} while (true)
/* Done, release the iterator */
IOObjectRelease(iter)
print("done")
return true
}
extension io_service_t {
/// - Returns: The device's name.
func name() -> String? {
let buf = UnsafeMutablePointer<io_name_t>.allocate(capacity: 1)
defer { buf.deallocate() }
return buf.withMemoryRebound(to: CChar.self, capacity: MemoryLayout<io_name_t>.size) {
if IORegistryEntryGetName(self, $0) == KERN_SUCCESS {
return String(cString: $0)
}
return nil
}
}
}