TolikPylypchuk / SharpHook

SharpHook provides a cross-platform global keyboard and mouse hook, event simulation, and text entry simulation for .NET
https://sharphook.tolik.io
MIT License
335 stars 32 forks source link

Keyboard capture failing on macos apps #121

Open adminmilvus opened 1 day ago

adminmilvus commented 1 day ago

I'm trying to capture keyboard data using the SharpHook library in a Mac OS environment, as per the example on the website.

Everything works great, except if the machine is accessed via AnyDesk.

On Intel processors, only some keys are recognized, as below (such as CTRL, ALT or SHIFT) and the rest do not trigger events. The other keys such as 'Q', 'W', '1', etc., all do not work.

On ARM processors, all keys are recognized as 'A' (except special keys such as CTRL, ALT or SHIFT).

Mouse events are working correctly (via AnyDesk or physically on the machine). Keyboard events only work correctly using the machine physically.

Is there any solution?

Here is an example of my PublishProfile:

<?xml version="1.0" encoding="utf-8"?>
<Project>
  <PropertyGroup>
    <Configuration>Release</Configuration>
    <Platform>Any CPU</Platform>
    <PublishDir>bin\Release\net6.0\publish\osx-x64\</PublishDir>
    <PublishProtocol>FileSystem</PublishProtocol>
    <_TargetId>Folder</_TargetId>
    <TargetFramework>net6.0</TargetFramework>
    <RuntimeIdentifier>osx-x64</RuntimeIdentifier>
    <SelfContained>true</SelfContained>
    <PublishSingleFile>true</PublishSingleFile>
    <PublishTrimmed>false</PublishTrimmed>
  </PropertyGroup>
</Project>

Here is the source code:

using SharpHook;
using SharpHook.Providers;
using SharpHook.Reactive;
using System.Reactive.Concurrency;
using System.Reactive.Linq;

namespace _005_SharpHook
{
    internal class Program
    {
        static void Main(string[] args)
        {
            var provider = UioHookProvider.Instance;
            Console.WriteLine("System Info:");
            Console.WriteLine($"Auto-repeat  rate: {provider.GetAutoRepeatRate()}");
            Console.WriteLine($"Auto-repeat delay: {provider.GetAutoRepeatDelay()}");
            Console.WriteLine($"Pointer acceleration multiplier: {provider.GetPointerAccelerationMultiplier()}");
            Console.WriteLine($"Pointer acceleration threshold: {provider.GetPointerAccelerationThreshold()}");
            Console.WriteLine($"Pointer sensitivity: {provider.GetPointerSensitivity()}");
            Console.WriteLine($"Multi-click time: {provider.GetMultiClickTime()}");

            var screens = provider.CreateScreenInfo();

            foreach(var screen in screens)
            {
                Console.WriteLine($"Screen #{screen.Number}: {screen.Width}x{screen.Height}; {screen.X}, {screen.Y}");
            }

            Console.WriteLine("---------- Press q to quit ----------\n");

            var hook = new SimpleReactiveGlobalHook(TaskPoolScheduler.Default);

            hook.HookEnabled.Subscribe(OnHookEvent);
            hook.HookDisabled.Subscribe(OnHookEvent);

            hook.KeyTyped.Subscribe(OnHookEvent);
            hook.KeyPressed.Subscribe(OnHookEvent);
            hook.KeyReleased.Subscribe(e => OnKeyReleased(e, hook));

            hook.MouseClicked.Subscribe(OnHookEvent);
            hook.MousePressed.Subscribe(OnHookEvent);
            hook.MouseReleased.Subscribe(OnHookEvent);

            hook.MouseMoved
                //.Throttle(TimeSpan.FromSeconds(1))
                .Subscribe(OnHookEvent);

            hook.MouseDragged
                .Throttle(TimeSpan.FromSeconds(1))
                .Subscribe(OnHookEvent);

            hook.MouseWheel.Subscribe(OnHookEvent);

            hook.Run();

        }

        static void OnHookEvent(HookEventArgs e)
        {
            Console.WriteLine($"{e.EventTime.ToLocalTime()}: {e.RawEvent}");
        }

        static void OnKeyReleased(KeyboardHookEventArgs e, IReactiveGlobalHook hook)
        {
            if(e.Data.KeyCode == SharpHook.Native.KeyCode.VcQ)
            {
                hook.Dispose();
            }
        }
    }
}
adminmilvus commented 1 day ago

If it helps, I noticed that when holding the ctrl key and pressing keys like A, B, C, keyboard events are fired correctly via anydesk.

TolikPylypchuk commented 23 hours ago

Hi! Thanks for posting this issue! I will try installing AnyDesk and reproducing this problem. In the meantime, could you please share the libuiohook debug logs? Maybe, they will contain some interesting info.

adminmilvus commented 22 hours ago

Hi @TolikPylypchuk , thank you very much for your feedback!

I am attaching the logs below.

I captured the logs in a Mac environment with an ARM processor, and with an Intel processor, to check the differences.

In both tests, I typed '123456' in sequence to see what happened. These characters are included in the logs to check the order in which they were entered (lines that begin with 'Log received').

Logs MAC Intel Processor (Mac Mini with Intel Core I5)

Log received: hook_set_dispatch_proc [53]: Setting new dispatch callback to 0x114d23124.
Log received: run [391]: Accessibility API is enabled.
Log received: run [402]: CFRunLoopGetCurrent successful.
Log received: create_event_runloop_info [304]: CGEventTapCreate Successful.
Log received: create_event_runloop_info [316]: CFMachPortCreateRunLoopSource successful.
Log received: create_event_runloop_info [334]: CFRunLoopObserverCreate successful.
Log received: dispatch_event [63]: Dispatching event type 1.
123456Log received: dispatch_modifier_change [339]: Modifiers Changed for key 0X3B. (0X20040001)
Log received: dispatch_key_press [131]: Key 0XA011 pressed. (0X3B)
Log received: dispatch_event [63]: Dispatching event type 4.
Log received: event_to_unicode [713]: Using no runloop for key typed events.
Log received: dispatch_modifier_change [339]: Modifiers Changed for key 0X3B. (0X20000000)
Log received: dispatch_key_release [186]: Key 0XA011 released. (0X3B)
Log received: dispatch_event [63]: Dispatching event type 5.
16/10/2024 16:04:17 -03:00: UioHookEvent: Type = KeyPressed; Time = 1729105457022; Mask = LeftCtrl; Reserved = SimulatedEvent; Keyboard = KeyboardEventData: KeyCode = VcLeftControl; RawCode = 59; KeyChar = ￿
16/10/2024 16:04:17 -03:00: UioHookEvent: Type = KeyReleased; Time = 1729105457250; Mask = None; Reserved = SimulatedEvent; Keyboard = KeyboardEventData: KeyCode = VcLeftControl; RawCode = 59; KeyChar = ￿
123456Log received: dispatch_modifier_change [339]: Modifiers Changed for key 0X3B. (0X20040001)
Log received: dispatch_key_press [131]: Key 0XA011 pressed. (0X3B)
Log received: dispatch_event [63]: Dispatching event type 4.
16/10/2024 16:04:24 -03:00: UioHookEvent: Type = KeyPressed; Time = 1729105464696; Mask = LeftCtrl; Reserved = SimulatedEvent; Keyboard = KeyboardEventData: KeyCode = VcLeftControl; RawCode = 59; KeyChar = ￿
Log received: event_to_unicode [713]: Using no runloop for key typed events.
^ALog received: dispatch_modifier_change [339]: Modifiers Changed for key 0X3B. (0X20000000)
Log received: dispatch_key_release [186]: Key 0XA011 released. (0X3B)
Log received: dispatch_event [63]: Dispatching event type 5.
16/10/2024 16:04:29 -03:00: UioHookEvent: Type = KeyReleased; Time = 1729105469924; Mask = None; Reserved = SimulatedEvent; Keyboard = KeyboardEventData: KeyCode = VcLeftControl; RawCode = 59; KeyChar = ￿
123456Log received: dispatch_modifier_change [339]: Modifiers Changed for key 0X3B. (0X20040001)
Log received: dispatch_key_press [131]: Key 0XA011 pressed. (0X3B)
Log received: dispatch_event [63]: Dispatching event type 4.
Log received: event_to_unicode [713]: Using no runloop for key typed events.
16/10/2024 16:04:45 -03:00: UioHookEvent: Type = KeyPressed; Time = 1729105485768; Mask = LeftCtrl; Reserved = SimulatedEvent; Keyboard = KeyboardEventData: KeyCode = VcLeftControl; RawCode = 59; KeyChar = ￿

Logs MAC ARM Processor (MacBook Pro - Apple M1)

Log received: hook_set_dispatch_proc [53]: Setting new dispatch callback to 0x30002c160.
Log received: run [391]: Accessibility API is enabled.
Log received: run [402]: CFRunLoopGetCurrent successful.
Log received: create_event_runloop_info [304]: CGEventTapCreate Successful.
Log received: create_event_runloop_info [316]: CFMachPortCreateRunLoopSource successful.
Log received: create_event_runloop_info [334]: CFRunLoopObserverCreate successful.
Log received: dispatch_event [63]: Dispatching event type 1.
16/10/2024 16:09:03 -03:00: UioHookEvent: Type = HookEnabled; Time = 1729105743113; Mask = None; Reserved = None
Log received: dispatch_key_press [131]: Key 0X41 pressed. (0)
Log received: dispatch_event [63]: Dispatching event type 4.
16/10/2024 16:09:05 -03:00: UioHookEvent: Type = KeyPressed; Time = 1729105745954; Mask = None; Reserved = SimulatedEvent; Keyboard = KeyboardEventData: KeyCode = VcA; RawCode = 0; KeyChar = ￿
Log received: event_to_unicode [713]: Using no runloop for key typed events.
Log received: dispatch_key_press [156]: Key 0X41 typed. (a)
Log received: dispatch_event [63]: Dispatching event type 3.
16/10/2024 16:09:05 -03:00: UioHookEvent: Type = KeyTyped; Time = 1729105745954; Mask = None; Reserved = SimulatedEvent; Keyboard = KeyboardEventData: KeyCode = VcA; RawCode = 0; KeyChar = a
1Log received: dispatch_key_release [186]: Key 0X41 released. (0)
Log received: dispatch_event [63]: Dispatching event type 5.
Log received: dispatch_key_press [131]: Key 0X41 pressed. (0)
Log received: dispatch_event [63]: Dispatching event type 4.
Log received: event_to_unicode [713]: Using no runloop for key typed events.
Log received: dispatch_key_press [156]: Key 0X41 typed. (a)
16/10/2024 16:09:06 -03:00: UioHookEvent: Type = KeyPressed; Time = 1729105746265; Mask = None; Reserved = SimulatedEvent; Keyboard = KeyboardEventData: KeyCode = VcA; RawCode = 0; KeyChar = ￿
Log received: dispatch_event [63]: Dispatching event type 3.
16/10/2024 16:09:06 -03:00: UioHookEvent: Type = KeyTyped; Time = 1729105746265; Mask = None; Reserved = SimulatedEvent; Keyboard = KeyboardEventData: KeyCode = VcA; RawCode = 0; KeyChar = a
2Log received: dispatch_key_release [186]: Key 0X41 released. (0)
Log received: dispatch_event [63]: Dispatching event type 5.
Log received: dispatch_key_press [131]: Key 0X41 pressed. (0)
Log received: dispatch_event [63]: Dispatching event type 4.
Log received: event_to_unicode [713]: Using no runloop for key typed events.
Log received: dispatch_key_press [156]: Key 0X41 typed. (a)
Log received: dispatch_event [63]: Dispatching event type 3.
16/10/2024 16:09:06 -03:00: UioHookEvent: Type = KeyPressed; Time = 1729105746594; Mask = None; Reserved = SimulatedEvent; Keyboard = KeyboardEventData: KeyCode = VcA; RawCode = 0; KeyChar = ￿
16/10/2024 16:09:06 -03:00: UioHookEvent: Type = KeyTyped; Time = 1729105746594; Mask = None; Reserved = SimulatedEvent; Keyboard = KeyboardEventData: KeyCode = VcA; RawCode = 0; KeyChar = a
3Log received: dispatch_key_release [186]: Key 0X41 released. (0)
Log received: dispatch_event [63]: Dispatching event type 5.
Log received: dispatch_key_press [131]: Key 0X41 pressed. (0)
Log received: dispatch_event [63]: Dispatching event type 4.
Log received: event_to_unicode [713]: Using no runloop for key typed events.
Log received: dispatch_key_press [156]: Key 0X41 typed. (a)
Log received: dispatch_event [63]: Dispatching event type 3.
16/10/2024 16:09:06 -03:00: UioHookEvent: Type = KeyPressed; Time = 1729105746867; Mask = None; Reserved = SimulatedEvent; Keyboard = KeyboardEventData: KeyCode = VcA; RawCode = 0; KeyChar = ￿
16/10/2024 16:09:06 -03:00: UioHookEvent: Type = KeyTyped; Time = 1729105746867; Mask = None; Reserved = SimulatedEvent; Keyboard = KeyboardEventData: KeyCode = VcA; RawCode = 0; KeyChar = a
4Log received: dispatch_key_release [186]: Key 0X41 released. (0)
Log received: dispatch_event [63]: Dispatching event type 5.
Log received: dispatch_key_press [131]: Key 0X41 pressed. (0)
Log received: dispatch_event [63]: Dispatching event type 4.
Log received: event_to_unicode [713]: Using no runloop for key typed events.
Log received: dispatch_key_press [156]: Key 0X41 typed. (a)
Log received: dispatch_event [63]: Dispatching event type 3.
16/10/2024 16:09:07 -03:00: UioHookEvent: Type = KeyPressed; Time = 1729105747093; Mask = None; Reserved = SimulatedEvent; Keyboard = KeyboardEventData: KeyCode = VcA; RawCode = 0; KeyChar = ￿
16/10/2024 16:09:07 -03:00: UioHookEvent: Type = KeyTyped; Time = 1729105747093; Mask = None; Reserved = SimulatedEvent; Keyboard = KeyboardEventData: KeyCode = VcA; RawCode = 0; KeyChar = a
5Log received: dispatch_key_release [186]: Key 0X41 released. (0)
Log received: dispatch_event [63]: Dispatching event type 5.
Log received: dispatch_key_press [131]: Key 0X41 pressed. (0)
Log received: dispatch_event [63]: Dispatching event type 4.
Log received: event_to_unicode [713]: Using no runloop for key typed events.
Log received: dispatch_key_press [156]: Key 0X41 typed. (a)
Log received: dispatch_event [63]: Dispatching event type 3.
16/10/2024 16:09:07 -03:00: UioHookEvent: Type = KeyTyped; Time = 1729105747523; Mask = None; Reserved = SimulatedEvent; Keyboard = KeyboardEventData: KeyCode = VcA; RawCode = 0; KeyChar = a
16/10/2024 16:09:07 -03:00: UioHookEvent: Type = KeyPressed; Time = 1729105747523; Mask = None; Reserved = SimulatedEvent; Keyboard = KeyboardEventData: KeyCode = VcA; RawCode = 0; KeyChar = ￿
6Log received: dispatch_key_release [186]: Key 0X41 released. (0)
Log received: dispatch_event [63]: Dispatching event type 5.
Log received: dispatch_modifier_change [339]: Modifiers Changed for key 0X3B. (0X20040001)
Log received: dispatch_key_press [131]: Key 0XA011 pressed. (0X3B)
Log received: dispatch_event [63]: Dispatching event type 4.
Log received: event_to_unicode [713]: Using no runloop for key typed events.
16/10/2024 16:09:12 -03:00: UioHookEvent: Type = KeyPressed; Time = 1729105752868; Mask = LeftCtrl; Reserved = SimulatedEvent; Keyboard = KeyboardEventData: KeyCode = VcLeftControl; RawCode = 59; KeyChar = ￿
Log received: dispatch_key_press [131]: Key 0X43 pressed. (0X8)
Log received: dispatch_event [63]: Dispatching event type 4.
Log received: event_to_unicode [713]: Using no runloop for key typed events.
Log received: dispatch_key_press [156]: Key 0X43 typed. (c)
Log received: dispatch_event [63]: Dispatching event type 3.
16/10/2024 16:09:13 -03:00: UioHookEvent: Type = KeyPressed; Time = 1729105753058; Mask = LeftCtrl; Reserved = SimulatedEvent; Keyboard = KeyboardEventData: KeyCode = VcC; RawCode = 8; KeyChar = ￿
16/10/2024 16:09:13 -03:00: UioHookEvent: Type = KeyTyped; Time = 1729105753058; Mask = LeftCtrl; Reserved = SimulatedEvent; Keyboard = KeyboardEventData: KeyCode = VcC; RawCode = 8; KeyChar = c
^C
TolikPylypchuk commented 22 hours ago

Thanks a lot, I will look into it when I have some spare time.