object[] GetDeviceKeys(string kind) { var paths = new List <NativeMethods.io_string_t>(); var matching = NativeMethods.IOServiceMatching(kind).ToCFType(); // Consumed by IOServiceGetMatchingServices, so DON'T Dispose(). if (matching.IsSet) { int iteratorObj; if (NativeMethods.IOReturn.Success == NativeMethods.IOServiceGetMatchingServices(0, matching, out iteratorObj)) { using (var iterator = iteratorObj.ToIOObject()) { while (true) { using (var handle = NativeMethods.IOIteratorNext(iterator).ToIOObject()) { if (!handle.IsSet) { break; } NativeMethods.io_string_t path; if (NativeMethods.IOReturn.Success == NativeMethods.IORegistryEntryGetPath(handle, "IOService", out path)) { paths.Add(path); } } } } } } return(paths.Cast <object>().ToArray()); }
protected override void Run(Action readyCallback) { using (var manager = NativeMethods.IOHIDManagerCreate(IntPtr.Zero).ToCFType()) { RunAssert(manager.IsSet, "HidSharp IOHIDManagerCreate failed."); using (var matching = NativeMethods.IOServiceMatching("IOHIDDevice").ToCFType()) { RunAssert(matching.IsSet, "HidSharp IOServiceMatching failed."); var devicesChangedCallback = new NativeMethods.IOHIDDeviceCallback(DevicesChangedCallback); NativeMethods.IOHIDManagerSetDeviceMatching(manager.Handle, matching.Handle); NativeMethods.IOHIDManagerRegisterDeviceMatchingCallback(manager.Handle, devicesChangedCallback, IntPtr.Zero); NativeMethods.IOHIDManagerRegisterDeviceRemovalCallback(manager.Handle, devicesChangedCallback, IntPtr.Zero); var runLoop = NativeMethods.CFRunLoopGetCurrent(); NativeMethods.CFRetain(runLoop); NativeMethods.IOHIDManagerScheduleWithRunLoop(manager, runLoop, NativeMethods.kCFRunLoopDefaultMode); try { readyCallback(); NativeMethods.CFRunLoopRun(); } finally { NativeMethods.IOHIDManagerUnscheduleFromRunLoop(manager, runLoop, NativeMethods.kCFRunLoopDefaultMode); NativeMethods.CFRelease(runLoop); } GC.KeepAlive(devicesChangedCallback); } } }