Вызов IOKit завершается с ошибкой kIOReturnExclusiveAccess, когда запущено другое приложение

Я создаю приложение MacOS с помощью IOKit.

Я столкнулся с проблемой, когда Karabiner запущен до того, как я запустил приложение, открытие HIDManager завершается с ошибкой kIOReturnExclusiveAccess.

Если я закрою Karabiner и запущу свое приложение, HIDManager откроется успешно. Затем я могу снова открыть карабин, и оба приложения работают как обычно.

Это фрагмент кода, где это происходит.

let noreturn = IOHIDManagerOpen(manager, IOOptionBits(kIOHIDOptionsTypeNone));
if(noreturn == kIOReturnExclusiveAccess) {
   print("FAILED");
}

Первоначально я отправил эту как проблему разработчику, но я Я не уверен, это я или они. Кроме того, я увидел, что эта предыдущая проблема осталась неподтвержденной, так что подумал лучше спросить здесь также.

Я новичок в использовании IOKit с MacOS и пока не понимаю, почему это может произойти.

Кто-нибудь может дать мне понять, должен ли я что-то делать, чтобы обойти это на моей стороне? Это кажется сложным, если другое приложение может использовать HID-интерфейс.

Любая помощь приветствуется.

Обновлять

Разработчик ответил на мой вопрос о проблеме GitHub, которую я поднял.

Karabiner-Elements открывает IOHIDDevice с kIOHIDOptionsTypeSeizeDevice, чтобы избежать получения hidd немодифицированных входных событий. Это вызывает kIOReturnExclusiveAccess, если другие приложения будут открывать устройства.

Согласно документации Apple для kIOHIDOptionsTypeSeizeDevice

Используется для открытия эксклюзивной связи с устройством. Это предотвратит получение системой и другими клиентами событий от устройства.

Karabiner делает это, чтобы система не получала HID-события до того, как Karabiner сможет их изменить.

Если кому-то вроде меня нужно немного больше информации об этом, я нашел технические примечания для API HID Manager очень полезны.

На данный момент я все еще выясняю лучшие варианты вокруг этого.


person Chris    schedule 27.12.2020    source источник


Ответы (1)


Вы действительно пытаетесь использовать устройство, которое открыл Карабинер (думаю, это мышь)? Если нет, вы сможете избежать этого, используя HID Manager по-другому.

HID Manager плохо документирован и сбивает с толку, особенно то, как работает IOHIDManagerOpen. IOHIDManagerOpen открывает каждое соответствующее устройство, подключенное к системе (и если вы еще не установили соответствующий словарь, он откроет каждое подключенное устройство). Вероятно, проблема в том, что вы пытаетесь открыть каждое устройство, когда вам нужно только определенное.

Вы должны либо:

  • установите соответствующий словарь перед вызовом IOHIDManagerOpen
  • или вообще не звоните IOHIDManagerOpen. Вам не нужно! Вы можете использовать IOHIDManagerCopyDevices или IOHIDManagerRegisterDeviceMatchingCallback для обнаружения устройств, а затем использовать IOHIDDeviceOpen для их открытия.
person Brendan Shanks    schedule 29.12.2020
comment
Спасибо, Брендан. Это полезно. Я уже получил соответствие на странице правильного использования и использования. Мне нужно прослушивать события с любой клавиатуры, подключенной к системе. Но сейчас я только изучаю концепцию работы с отдельными устройствами. Что касается разницы между hid-менеджером и hid-устройствами. Позволяет ли открытие HID-менеджера одновременно прослушивать устройства данной страницы использования/использования, где открытие устройства позволяет одновременно открывать отдельные интересующие устройства? ? (таким образом, обеспечивая большую степень детализации/контроля, если это необходимо?) - person Chris; 29.12.2020
comment
Я выбрал подход обнаружения устройств, а затем их выборочное открытие. В случае с трекпадом/клавиатурой Apple (да, мне нужен HID-доступ к этой и любой другой клавиатуре) я все еще не могу открыть устройство из-за вышеупомянутого захвата. Если я закрою карабин, я смогу открыть устройство, как положено, и получать отчеты. - person Chris; 29.12.2020