OS-Specific Constraints
This article describes OS-specific constrains and other things that should be noted about OS support.
Windows
Supported Versions
Only Windows 10 and 11 are supported.
Important
If the global hook runs on versions of Windows older than Windows 10 1607, then it will destroy dead keys rendering
them unusable. This is because it uses the
ToUnicodeEx
function to
determine which characters are typed by key presses, and before Windows 10 1607 this function changed the keyboard
state.
Supported Architectures
x86, x64, and Arm64 are supported. Arm32 is not supported since its support was dropped in .NET 5.
Visual C++ Redistributable
The libuiohook build used by SharpHook on Windows is statically linked to the C runtime which means that client apps don't need the Visual C++ Redistributable package.
An exception is the logging functionality - LogEntryParser
uses the vsprintf
function from the C runtime, and as
such, it requires the Visual C++ Redistributable package on Windows, unlike the rest of SharpHook. If you don't want
your app to be dependent on this package, then you can use the EmptyLogSource
class instead of LogSource
in release
builds of your app. EmptyLogSource
implements ILogSource
, but never raises the MessageLogged
event and doesn't
subscribe to libuiohook logs.
DPI Awareness
An application manifest is required on Windows to enable DPI awareness for your app. If it's not enabled then mouse coordinates will be wrong on high-DPI screens. You can look at the sample app in the SharpHook repository to see the manifest example.
Text Entry Simulation
On Windows text simulation should work correctly and consistently.
macOS
Supported Versions
macOS 10.15+ is supported. Mac Catalyst 13.1+ is supported.
Supported Architectures
x64 and Arm64 are supported.
Accessibility API
macOS requires that the accessibility API be enabled for the application if it wants to create a global hook.
If the accessiblity API is not enabled, then Run
will fail and return UioHookResult.ErrorAxApiDisabled
. If that
happens then the OS will show a dialog about enabling accessibility for the app.
Main Run-Loop
On macOS running the global hook requires that the main run-loop is present. libuiohook takes care of it if the hook
is run on the main thread. It's also taken care of by UI frameworks since they need an event loop on the main thread
to run. But if you're using a global hook in a console app or a background service and want to run it on some thread
other than the main one then you should take care of it yourself. You can do that by P/Invoking the native
CFRunLoopRun
function on the main thread.
Simulating Multiple Mouse Clicks
macOS doesn't recognize that a mouse was clicked multiple times when multiple press/release events have been simulated.
Instead, the click count must be explicitly provided. This is why IEvenSimulator
contains the SimulateMousePress
and
SimulateMouseRelease
overloads with the clicks
parameter. This parameter should be incremented for each
press/release, starting with 1
.
Text Entry Simulation
On macOS applications are not required to process text entry simulation, but most of them should handle it correctly.
Linux
Supported Distributions
Linux distributions supported by .NET are supported by SharpHook. It may work correctly on other distributions, but if it doesn't then the problems will most probably not be fixed.
Supported Architectures
x64, Arm32, and Arm64 are supported. x86 is not supported by .NET itself.
X11 and Wayland
Only X11 is supported. Wayland support may be available in a future version.
Text Entry Simulation
X11 doesn't support text simulation directly. Instead, for each character, an unused key code is remapped to that character, and then key press/release is simulated. Since the receiving application must react to the remapping, and may not do so instantaneously, a delay is needed for accurate simulation. This means that text simulation on Linux works slowly and is not guaranteed to be correct.
UioHook
contains the SetPostTextDelayX11
method which can be used to increase (or decrease) the delay if needed -
longer delays add consistency but may be more jarring to end users. UioHook
also contains the GetPostTextDelayX11
which can be used to get the currently configured delay - the default is 50 milliseconds. Delays are configurable on a
nanosecond level. On Windows and macOS SetPostTextDelayX11
does nothing, and GetPostTextDelayX11
always returns 0.
IEventSimulator
contains the TextSimulationDelayOnX11
property which is wrapper arount the aforementioned methods.