来自 Mac OS 的 USB 设备添加/删除通知

标签 notifications usb iokit

我正在编写一种方法来在插入/拔出 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);

我遇到了与原始海报相同的问题。我收到通知,但只有一次删除/添加。如果我尝试添加/删除不同的设备并不重要,我只会收到一个通知。在那之后,我只是没有得到通知。

有人可以帮我弄清楚为什么会发生这种情况。谢谢!

最佳答案

IOKit device adding/removal notifications - only fire once?

这是我找到答案的地方,虽然不容易发现。

事实证明,在添加/删除设备时接收通知的方法必须运行端口迭代器。

因此,在回调方法中,需要这样的语句。

while (IOIteratorNext(portIterator)) {};

或者用它做其他事情,只需运行迭代器。我很失望这没有在任何地方指定。

关于来自 Mac OS 的 USB 设备添加/删除通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16488222/

相关文章:

c++ - 在 macOS 中处理 VBI 数据

java - 关闭应用程序后服务未运行

c++ - 在 C++ 上遇到 MFC lntelliSense 的问题

delphi - 我如何在delphi中与HID USB设备通信

cocoa 获取电源适配器状态

swift - 使用 Swift 获取 Apple NVRAM 值

sdk - 在 Symbian S60v3 中禁用所有传入消息的通知

通知服务中的android内存泄漏

android - 如何从另一个应用程序的通知中获取图像?

serial-port - Arduino伺服平滑