SharpHook 5.2.3
See the version list below for details.
dotnet add package SharpHook --version 5.2.3
NuGet\Install-Package SharpHook -Version 5.2.3
<PackageReference Include="SharpHook" Version="5.2.3" />
<PackageVersion Include="SharpHook" Version="5.2.3" />
<PackageReference Include="SharpHook" />
paket add SharpHook --version 5.2.3
#r "nuget: SharpHook, 5.2.3"
#:package SharpHook@5.2.3
#addin nuget:?package=SharpHook&version=5.2.3
#tool nuget:?package=SharpHook&version=5.2.3
SharpHook
SharpHook provides a cross-platform global keyboard and mouse hook, event simulation, and text entry simulation for .NET. It is a wrapper of libuiohook and provides direct access to its features as well as higher-level types to work with it.
Usage
Native Functions of libuiohook
SharpHook exposes the functions of libuiohook in the SharpHook.Native.UioHook class. The SharpHook.Native
namespace also contains types which represent the data used by libuiohook.
In general, you don't need to use the native methods directly. Instead, use the higher-level interfaces and classes provided by SharpHook. However, you should still read this section to know how the high-level features work under the hood.
UioHook contains the following methods for working with the global hook:
SetDispatchProc- sets the function which will be called when an event is raised by libuiohook.Run- creates a global hook and runs it on the current thread, blocking it untilStopis called.Stop- destroys the global hook.
You have to remember that only one global hook can exist at a time since calling SetDispatchProc will override the
previously set one.
Additionally, UioHook contains the PostEvent method for simulating input events, and the SetLoggerProc method for
setting the log callback.
Starting with version 5.0.0, SharpHook also provides text entry simulation and UioHook contains the PostText method.
The text to simulate doesn't depend on the current keyboard layout. The full range of UTF-16 (including surrogate pairs,
e.g. emojis) is supported.
libuiohook also provides functions to get various system properties. The corresponding methods are also present in
UioHook.
If you want to use the low-level functionality, you don't need to use the UioHook class directly. Instead you can use
interfaces in the SharpHook.Providers namespace. The methods in those interfaces are the same as in the UioHook
class. SharpHook.Providers.UioHookProvider implements all of these interfaces and simply calls the corresponding
methods in UioHook. This should be done to decouple your code from UioHook and make testing easier.
Global Hooks
SharpHook provides the IGlobalHook interface along with two default implementations which you can use to control the
hook and subscribe to its events. Here's a basic usage example:
using SharpHook;
// ...
var hook = new TaskPoolGlobalHook();
hook.HookEnabled += OnHookEnabled; // EventHandler<HookEventArgs>
hook.HookDisabled += OnHookDisabled; // EventHandler<HookEventArgs>
hook.KeyTyped += OnKeyTyped; // EventHandler<KeyboardHookEventArgs>
hook.KeyPressed += OnKeyPressed; // EventHandler<KeyboardHookEventArgs>
hook.KeyReleased += OnKeyReleased; // EventHandler<KeyboardHookEventArgs>
hook.MouseClicked += OnMouseClicked; // EventHandler<MouseHookEventArgs>
hook.MousePressed += OnMousePressed; // EventHandler<MouseHookEventArgs>
hook.MouseReleased += OnMouseReleased; // EventHandler<MouseHookEventArgs>
hook.MouseMoved += OnMouseMoved; // EventHandler<MouseHookEventArgs>
hook.MouseDragged += OnMouseDragged; // EventHandler<MouseHookEventArgs>
hook.MouseWheel += OnMouseWheel; // EventHandler<MouseWheelHookEventArgs>
hook.Run();
// or
await hook.RunAsync();
First, you create the hook, then subscribe to its events, and then run it. The Run method runs the hook on the current
thread, blocking it. The RunAsync() method runs the hook on a separate thread and returns a Task which is finished
when the hook is destroyed. You can subscribe to events after the hook is started.
IGlobalHook extends IDisposable. When you call the Dispose method on a hook, it's destroyed. The contract of
the interface is that once a hook has been destroyed, it cannot be started again - you'll have to create a new instance.
Calling Dispose when the hook is not running is safe - it just won't do anything (other than marking the instance as
disposed).
Hook events are of type HookEvent or a derived type which contains more info. It's possible to suppress event
propagation by setting the SuppressEvent property to true inside the event handler. This must be done synchronously
and is only supported on Windows and macOS.
Important: Always use one instance of IGlobalHook at a time in the entire application since they all must use
the same static method to set the hook callback for libuiohook, so there may only be one callback at a time.
SharpHook provides two implementations of IGlobalHook:
SharpHook.SimpleGlobalHookruns all of its event handlers on the same thread on which the hook itself runs. This means that the handlers should generally be fast since they will block the hook from handling the events that follow if they run for too long.SharpHook.TaskPoolGlobalHookruns all of its event handlers on other threads inside the default thread pool for tasks. The parallelism level of the handlers can be configured. On backpressure it will queue the remaining handlers. This means that the hook will be able to process all events. This implementation should be preferred toSimpleGlobalHookexcept for very simple use-cases. But it has a downside - suppressing event propagation will be ignored since event handlers are run on other threads.
The library also provides the SharpHook.GlobalHookBase class which you can extend to create your own implementation
of the global hook. It calls the appropriate event handlers, and you only need to implement a strategy for dispatching
the events. It also contains a finalizer which will stop the global hook if this object is not reachable anymore.
Reactive Global Hooks
Use the SharpHook.Reactive package for reactive global hooks.
Event Simulation
SharpHook provides the ability to simulate keyboard and mouse events in a cross-platform way as well. Here's a quick example:
using SharpHook;
using SharpHook.Native;
// ...
var simulator = new EventSimulator();
// Press Ctrl+C
simulator.SimulateKeyPress(KeyCode.VcLeftControl);
simulator.SimulateKeyPress(KeyCode.VcC);
// Release Ctrl+C
simulator.SimulateKeyRelease(KeyCode.VcC);
simulator.SimulateKeyRelease(KeyCode.VcLeftControl);
// Press the left mouse button
simulator.SimulateMousePress(MouseButton.Button1);
// Release the left mouse button
simulator.SimulateMouseRelease(MouseButton.Button1);
// Press the left mouse button at (0, 0)
simulator.SimulateMousePress(0, 0, MouseButton.Button1);
// Release the left mouse button at (0, 0)
simulator.SimulateMouseRelease(0, 0, MouseButton.Button1);
// Move the mouse pointer to (0, 0)
simulator.SimulateMouseMovement(0, 0);
// Move the mouse pointer 50 pixels to the right and 100 pixels down
simulator.SimulateMouseMovementRelative(50, 100);
// Scroll the mouse wheel
simulator.SimulateMouseWheel(
rotation: -120,
direction: MouseWheelScrollDirection.Vertical, // MouseWheelScrollDirection.Vertical by default
type: MouseWheelScrollType.UnitScroll); // MouseWheelScrollType.UnitScroll by default
SharpHook provides the IEventSimulator interface, and the default implementation, EventSimulator, which calls
UioHook.PostEvent to simulate the events.
Text Entry Simulation
Starting with version 5.0.0, SharpHook also provides text entry simulation. IEventSimulator contains the
SimulateTextEntry method which accepts a string. The text to simulate doesn't depend on the current keyboard layout.
The full range of UTF-16 (including surrogate pairs, e.g. emojis) is supported.
Logging
libuiohook can log messages throughout its execution. By default the messages are not logged anywhere, but you can get
these logs by using the ILogSource interface and its default implementation, LogSource:
using SharpHook.Logging;
// ...
var logSource = LogSource.RegisterOrGet(minLevel: LogLevel.Info);
logSource.MessageLogged += this.OnMessageLogged;
private void OnMessageLogged(object? sender, LogEventArgs e) =>
this.logger.Log(this.AdaptLogLevel(e.LogEntry.Level), e.LogEntry.FullText);
As with global hooks, you should use only one LogSource object at a time. ILogSource extends IDisposable - you
can dispose of a log source to stop receiving libuiohook messages. You should keep a reference to an instance of
LogSource when you use it since it will stop receiving messages when garbage collector deletes it, to avoid memory
leaks.
An EmptyLogSource class is also available - this class doesn't listen to the libuiohook logs and can be used instead
of LogSource in release builds.
Testing
SharpHook provides two classes which make testing easier. They aren't required since mocks can be used instead, but unlike mocks, no setup is required to use these classes.
SharpHook.Testing.TestGlobalHook provides an implementation of IGlobalHook and IEventSimulator which can be used
for testing. When the Run or RunAsync method is called, it will dispatch events using the various Simulate methods
from IEventSimulator.
If this class is used as an IEventSimulator in tested code, then the SimulatedEvents property can be checked to see
which events were simulated using the test instance.
If an IReactiveGlobalHook is needed for testing, then ReactiveGlobalHookAdapter can be used to adapt an instance of
TestGlobalHook.
If the low-level functionality of SharpHook should be mocked, or mocking should be pushed as far away as possible,
then SharpHook.Testing.TestProvider can be used. It implements every interface in the SharpHook.Providers namespace
and as such it can be used instead of a normal low-level functionality provider.
Like TestGlobalHook, this class can post events using the PostEvent method and dispatch them if Run was called.
It also contains the PostedEvents property.
Icon
Icon made by Freepik from www.flaticon.com.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 is compatible. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.6.2
- No dependencies.
-
.NETStandard 2.0
- No dependencies.
-
net6.0
- No dependencies.
-
net7.0
- No dependencies.
-
net8.0
- No dependencies.
NuGet packages (9)
Showing the top 5 NuGet packages that depend on SharpHook:
| Package | Downloads |
|---|---|
|
GetIt
.NET library to help introduce programming in a funnier way. Inspired by Scratch and Turtle graphics. |
|
|
SharpHook.Reactive
SharpHook provides a cross-platform global keyboard and mouse hook, event simulation, and text entry simulation for .NET. |
|
|
VL.IO.MouseKeyGlobal
Global mouse and keyboard hook for vvvv gamma based on Sharphook by Tolik Pylypchuk |
|
|
Frank.GameEngine.Input
Package Description |
|
|
SharpHotHook
Read global hotkeys on C#. // Зчитування глобальних гарячих клавіш |
GitHub repositories (14)
Showing the top 14 popular GitHub repositories that depend on SharpHook:
| Repository | Stars |
|---|---|
|
timschneeb/GalaxyBudsClient
Unofficial Galaxy Buds Manager for Windows, macOS, Linux, and Android
|
|
|
Jeric-X/SyncClipboard
跨平台剪贴板同步、历史记录管理工具 / Cross-platform cipboard syncing, history management tool
|
|
|
SciSharp/BotSharp
AI Multi-Agent Framework in .NET
|
|
|
flyingpie/windows-terminal-quake
Enable Quake-style dropdown for (almost) any application.
|
|
|
Sidekick-Poe/Sidekick
The main repository for the Sidekick project, a companion trade tool for Path of Exile and Path of Exile 2.
|
|
|
awaescher/StageManager
🖥️ Stage Manager for Microsoft Windows (feasibility study)
|
|
|
lulzsun/RePlays
Open-source game recording management software
|
|
|
Particle1904/DatasetHelpers
Dataset Helper program to automatically select, re scale and tag Datasets (composed of image and text) for Machine Learning training.
|
|
|
tghamm/Anthropic.SDK
An unofficial C#/.NET SDK for accessing the Anthropic Claude API. This package is not affiliated with, endorsed by, or sponsored by Anthropic. Anthropic and Claude are trademarks of Anthropic, PBC.
|
|
|
PizzaLovers007/AdofaiTweaks
Helpful tweaks for A Dance of Fire and Ice
|
|
|
jooapa/jammer
light-weight CLI music player with Soundcloud, Youtube, Rss, Midi Support for Win & Linux
|
|
|
SweetSmellFox/MFAAvalonia
基于 Avalonia 的 MAAFramework 通用 GUI 项目 | A universal GUI project for MAAFramework based on Avalonia
|
|
|
dan0v/AmplitudeSoundboard
A sleek, cross-platform soundboard, available for Windows, MacOS, and Linux
|
|
|
deanthecoder/ZXSpeculator
Cross-platform ZX Spectrum emulator written in C#
|
| Version | Downloads | Last Updated |
|---|---|---|
| 7.0.3 | 785 | 10/5/2025 |
| 7.0.2 | 1,814 | 9/21/2025 |
| 7.0.1 | 5,159 | 8/17/2025 |
| 7.0.0 | 976 | 8/10/2025 |
| 6.2.0 | 1,824 | 7/19/2025 |
| 6.1.2 | 2,758 | 6/22/2025 |
| 6.1.1 | 1,203 | 6/3/2025 |
| 6.1.0 | 761 | 5/23/2025 |
| 6.0.0 | 730 | 5/18/2025 |
| 5.3.9 | 11,493 | 3/29/2025 |
| 5.3.8 | 24,469 | 9/27/2024 |
| 5.3.7 | 14,297 | 7/9/2024 |
| 5.3.6 | 3,676 | 5/22/2024 |
| 5.3.5 | 6,158 | 5/20/2024 |
| 5.3.4 | 1,126 | 5/5/2024 |
| 5.3.3 | 855 | 4/28/2024 |
| 5.3.2 | 4,638 | 4/2/2024 |
| 5.3.1 | 22,425 | 3/3/2024 |
| 5.3.0 | 2,267 | 2/24/2024 |
| 5.2.3 | 16,315 | 2/1/2024 |
| 5.2.2 | 1,533 | 1/13/2024 |
| 5.2.1 | 1,866 | 1/3/2024 |
| 5.2.0 | 1,673 | 12/16/2023 |
| 5.1.2 | 2,401 | 11/25/2023 |
| 5.1.1 | 7,176 | 10/13/2023 |
| 5.1.0 | 718 | 10/8/2023 |
| 5.0.0 | 7,346 | 8/10/2023 |
| 4.2.1 | 4,767 | 6/18/2023 |
| 4.2.0 | 4,945 | 4/8/2023 |
| 4.1.0 | 755 | 3/26/2023 |
| 4.0.1 | 734 | 3/12/2023 |
| 4.0.0 | 4,751 | 11/9/2022 |
| 3.1.3 | 1,357 | 10/27/2022 |
| 3.1.2 | 1,585 | 10/19/2022 |
| 3.1.1 | 3,664 | 8/5/2022 |
| 3.1.0 | 1,321 | 7/30/2022 |
| 3.0.2 | 8,876 | 7/1/2022 |
| 3.0.1 | 848 | 6/25/2022 |
| 3.0.0 | 1,262 | 3/27/2022 |
| 2.0.0 | 1,321 | 2/4/2022 |
| 1.1.0 | 1,210 | 12/4/2021 |
| 1.0.1 | 935 | 11/21/2021 |
| 1.0.0 | 889 | 11/8/2021 |