SharpHook 4.1.0
See the version list below for details.
dotnet add package SharpHook --version 4.1.0
NuGet\Install-Package SharpHook -Version 4.1.0
<PackageReference Include="SharpHook" Version="4.1.0" />
paket add SharpHook --version 4.1.0
#r "nuget: SharpHook, 4.1.0"
// Install SharpHook as a Cake Addin #addin nuget:?package=SharpHook&version=4.1.0 // Install SharpHook as a Cake Tool #tool nuget:?package=SharpHook&version=4.1.0
SharpHook
SharpHook provides a cross-platform global keyboard and mouse hook for .NET, and the ability to simulate input events. It is a thin 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 structs and enums which represent the data returned by libuiohook.
Note: In general, you don't need to use the native methods directly. Instead, use the higher-level types provided by SharpHook.
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 untilStop
is called.Stop
- destroys the global hook.
Additionally, UioHook
contains the PostEvent
method for simulating input events, and the SetLoggerProc
method for
setting the log callback.
libuiohook also provides functions to get various system properties. The corresponding methods are also present in
UioHook
.
Important: 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 this repository to see the manifest example.
Default 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;
hook.HookDisabled += OnHookDisabled;
hook.KeyTyped += OnKeyTyped;
hook.KeyPressed += OnKeyPressed;
hook.KeyReleased += OnKeyReleased;
hook.MouseClicked += OnMouseClicked;
hook.MousePressed += OnMousePressed;
hook.MouseReleased += OnMouseReleased;
hook.MouseMoved += OnMouseMoved;
hook.MouseDragged += OnMouseDragged;
hook.MouseWheel += OnMouseWheel;
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).
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
:
SimpleGlobalHook
runs all of its event handlers on the same thread where 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.TaskPoolGlobalHook
runs 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 toSimpleGlobalHook
except 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 GlobalHookBase
class which you can extend to create your own implementation of the
global hook. It calls appropriate event handlers, and you only need to implement a strategy for dispatching the events.
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);
// Move the mouse pointer to (0, 0)
simulator.SimulateMouseMovement(0, 0);
// Scroll the mouse wheel
simulator.SimulateMouseWheel(2, -120);
SharpHook provides the IEventSimulator
interface, and the default implementation, EventSimulator
, which calls
UioHook.PostEvent
to simulate the events.
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.Register();
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.
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 was computed. 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. |
.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 is compatible. net462 was computed. 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.1
- No dependencies.
-
.NETStandard 2.0
- No dependencies.
-
net6.0
- No dependencies.
-
net7.0
- No dependencies.
NuGet packages (5)
Showing the top 5 NuGet packages that depend on SharpHook:
Package | Downloads |
---|---|
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 |
|
Frank.GameEngine.Rendering.MonoGame
Package Description |
|
SharpHotHook
Read global hotkeys on C#. // Зчитування глобальних гарячих клавіш |
GitHub repositories (6)
Showing the top 5 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 Solution
|
|
awaescher/StageManager
🖥️ Stage Manager for Microsoft Windows (feasibility study)
|
|
Particle1904/DatasetHelpers
Dataset Helper program to automatically select, re scale and tag Datasets (composed of image and text) for Machine Learning training.
|
|
lulzsun/RePlays
Open-source game recording management software
|
Version | Downloads | Last updated |
---|---|---|
5.3.8 | 2,371 | 9/27/2024 |
5.3.7 | 5,856 | 7/9/2024 |
5.3.6 | 2,885 | 5/22/2024 |
5.3.5 | 2,940 | 5/20/2024 |
5.3.4 | 917 | 5/5/2024 |
5.3.3 | 714 | 4/28/2024 |
5.3.2 | 3,481 | 4/2/2024 |
5.3.1 | 12,138 | 3/3/2024 |
5.3.0 | 1,616 | 2/24/2024 |
5.2.3 | 4,919 | 2/1/2024 |
5.2.2 | 1,196 | 1/13/2024 |
5.2.1 | 1,481 | 1/3/2024 |
5.2.0 | 1,221 | 12/16/2023 |
5.1.2 | 1,884 | 11/25/2023 |
5.1.1 | 5,323 | 10/13/2023 |
5.1.0 | 534 | 10/8/2023 |
5.0.0 | 6,169 | 8/10/2023 |
4.2.1 | 2,983 | 6/18/2023 |
4.2.0 | 4,496 | 4/8/2023 |
4.1.0 | 593 | 3/26/2023 |
4.0.1 | 588 | 3/12/2023 |
4.0.0 | 4,471 | 11/9/2022 |
3.1.3 | 1,195 | 10/27/2022 |
3.1.2 | 1,375 | 10/19/2022 |
3.1.1 | 3,093 | 8/5/2022 |
3.1.0 | 1,147 | 7/30/2022 |
3.0.2 | 7,047 | 7/1/2022 |
3.0.1 | 724 | 6/25/2022 |
3.0.0 | 1,114 | 3/27/2022 |
2.0.0 | 1,152 | 2/4/2022 |
1.1.0 | 1,036 | 12/4/2021 |
1.0.1 | 797 | 11/21/2021 |
1.0.0 | 611 | 11/8/2021 |
1.0.0-preview.4 | 156 | 11/6/2021 |
1.0.0-preview.3 | 172 | 11/1/2021 |
1.0.0-preview.2 | 153 | 10/26/2021 |
1.0.0-preview.1 | 154 | 10/26/2021 |