我正在编写一种方法,用于在插入/拔出USB设备时从操作系统接收通知。我使用了这个问题的建议
How to know when a HID USB/Bluetooth device is connected in Cocoa?。
这就是我所拥有的:
io_iterator_t portIterator;
CFMutableDictionaryRef matchingDict = IOServiceMatching(kIOUSBDeviceClassName); // Interested in instances of class
long vendorID = usbVendorId;
long productID = usbProductID;
// Create a CFNumber for the idVendor and set the value in the dictionary
CFNumberRef numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vendorID);
CFDictionarySetValue(matchingDict, CFSTR(kUSBVendorID), numberRef);
CFRelease(numberRef);
// Create a CFNumber for the idProduct and set the value in the dictionary
numberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &productID);
CFDictionarySetValue(matchingDict, CFSTR(kUSBProductID), numberRef);
CFRelease(numberRef);
numberRef = NULL;
mach_port_t masterPort;
IOMasterPort(MACH_PORT_NULL, &masterPort);
// Set up notification port and add it to the current run loop for addition notifications.
IONotificationPortRef notificationPort = IONotificationPortCreate(masterPort);
CFRunLoopAddSource(CFRunLoopGetCurrent(),
IONotificationPortGetRunLoopSource(notificationPort),
kCFRunLoopDefaultMode);
// Register for notifications when a serial port is added to the system.
// Retain dictionary first because all IOServiceMatching calls consume dictionary.
CFRetain(matchingDict);
kern_return_t result = IOServiceAddMatchingNotification(notificationPort,
kIOMatchedNotification,
matchingDict,
usbDeviceAdded,
nil,
&portIterator);
// Run out the iterator or notifications won't start.
while (IOIteratorNext(portIterator)) {};
// Also Set up notification port and add it to the current run loop removal notifications.
IONotificationPortRef terminationNotificationPort = IONotificationPortCreate(kIOMasterPortDefault);
CFRunLoopAddSource(CFRunLoopGetCurrent(),
IONotificationPortGetRunLoopSource(terminationNotificationPort),
kCFRunLoopDefaultMode);
// Register for notifications when a serial port is added to the system.
// Retain dictionary first because all IOServiceMatching calls consume dictionary.
CFRetain(matchingDict);
kern_return_t result1 = IOServiceAddMatchingNotification(terminationNotificationPort,
kIOTerminatedNotification,
matchingDict,
usbDeviceRemoved,
this,
&portIterator);
// Run out the iterator or notifications won't start.
while (IOIteratorNext(portIterator)) {};
CFRetain(matchingDict);
我遇到了与原版海报相同的问题。我收到通知,但只有一次删除/添加。如果我尝试添加/删除其他设备无关紧要,我只收到一个通知。在那之后,我只是没有得到通知。
有人可以帮我弄清楚为什么会发生这种情况。谢谢!
答案 0 :(得分:1)
IOKit device adding/removal notifications - only fire once?
这是我找到答案的地方,虽然不容易发现。
事实证明,在添加/删除设备时接收通知的方法需要运行端口迭代器。
因此,在回调方法中,需要这样的语句。
while(IOIteratorNext(portIterator)){};
或用它做其他事情,只需运行迭代器。我对此表示不反对。