C# c中的Linux键盘挂钩#

C# c中的Linux键盘挂钩#,c#,linux,raspberry-pi,C#,Linux,Raspberry Pi,我的问题是,我正试图运行一个专门为linux发布的自包含c#console应用程序,该应用程序打算在Raspberry上运行 使用场景是在公共交通中,乘客将使用RFID钥匙卡,我将通过传感器读取ID,该传感器被识别为键盘 由于这个应用程序必须一直运行,它将作为一个服务运行,这就是为什么我需要一个键盘挂钩,所以无论发生什么情况,服务都将读取传感器 我想知道是否有类似于此示例的东西适用于linux(警告:这是一个http网站): 以下是代码,您无需访问该网站: using System; using

我的问题是,我正试图运行一个专门为linux发布的自包含c#console应用程序,该应用程序打算在Raspberry上运行

使用场景是在公共交通中,乘客将使用RFID钥匙卡,我将通过传感器读取ID,该传感器被识别为键盘

由于这个应用程序必须一直运行,它将作为一个服务运行,这就是为什么我需要一个键盘挂钩,所以无论发生什么情况,服务都将读取传感器

我想知道是否有类似于此示例的东西适用于linux(警告:这是一个http网站):

以下是代码,您无需访问该网站:

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Input;
 
namespace DesktopWPFAppLowLevelKeyboardHook
{
    public class LowLevelKeyboardListener
    {
        private const int WH_KEYBOARD_LL = 13;
        private const int WM_KEYDOWN = 0x0100;
        private const int WM_SYSKEYDOWN = 0x0104;
 
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);
 
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool UnhookWindowsHookEx(IntPtr hhk);
 
        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
 
        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern IntPtr GetModuleHandle(string lpModuleName);
 
        public delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
 
        public event EventHandler<KeyPressedArgs> OnKeyPressed;
 
        private LowLevelKeyboardProc _proc;
        private IntPtr _hookID = IntPtr.Zero;
 
        public LowLevelKeyboardListener()
        {
            _proc = HookCallback;
        }
 
        public void HookKeyboard()
        {
            _hookID = SetHook(_proc);
        }
 
        public void UnHookKeyboard()
        {
            UnhookWindowsHookEx(_hookID);
        }
 
        private IntPtr SetHook(LowLevelKeyboardProc proc)
        {
            using (Process curProcess = Process.GetCurrentProcess())
            using (ProcessModule curModule = curProcess.MainModule)
            {
                return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0);
            }
        }
 
        private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN || wParam == (IntPtr)WM_SYSKEYDOWN)
            {
                int vkCode = Marshal.ReadInt32(lParam);
 
                if (OnKeyPressed != null) { OnKeyPressed(this, new KeyPressedArgs(KeyInterop.KeyFromVirtualKey(vkCode))); }
            }
 
            return CallNextHookEx(_hookID, nCode, wParam, lParam);
        }
    }
 
    public class KeyPressedArgs : EventArgs
    {
        public Key KeyPressed { get; private set; }
 
        public KeyPressedArgs(Key key)
        {
            KeyPressed = key;
        }
    }
}
使用系统;
使用系统诊断;
使用System.Runtime.InteropServices;
使用System.Windows.Input;
命名空间DeskTopWPFappLowLevel键盘挂钩
{
公共类低级键盘侦听器
{
专用常量int WH_键盘LL=13;
私有常量int WM_KEYDOWN=0x0100;
私有常量int WM_SYSKEYDOWN=0x0104;
[DllImport(“user32.dll”,CharSet=CharSet.Auto,SetLastError=true)]
私有静态外部IntPtr SETWINDOWSHOOKX(int idHook、低层键盘PROC lpfn、IntPtr hMod、uint dwThreadId);
[DllImport(“user32.dll”,CharSet=CharSet.Auto,SetLastError=true)]
[返回:Marshallas(UnmanagedType.Bool)]
私有静态外部bool unhookwindowshookx(IntPtr hhk);
[DllImport(“user32.dll”,CharSet=CharSet.Auto,SetLastError=true)]
私有静态外部IntPtr CallNextHookEx(IntPtr hhk、intncode、IntPtr wParam、IntPtr lParam);
[DllImport(“kernel32.dll”,CharSet=CharSet.Auto,SetLastError=true)]
私有静态外部IntPtr GetModuleHandle(字符串lpModuleName);
公共委托IntPtr低级键盘PROC(int nCode、IntPtr wParam、IntPtr lParam);
公共事件事件处理程序OnKeyPressed;
私人低层键盘程序;
私有IntPtr_hookID=IntPtr.Zero;
公共低层键盘侦听器()
{
_proc=HookCallback;
}
公用键盘()
{
_hookID=SetHook(_proc);
}
公众休憩用地
{
unhookwindowshookx(_hookID);
}
专用IntPtr设置挂钩(低层键盘程序)
{
使用(Process curProcess=Process.GetCurrentProcess())
使用(ProcessModule curModule=curProcess.MainModule)
{
返回SetWindowsHookEx(WH\u KEYBOARD\u LL,proc,GetModuleHandle(curModule.ModuleName),0);
}
}
专用IntPtr钩子回调(int nCode、IntPtr wParam、IntPtr lParam)
{
如果(nCode>=0&&wParam==(IntPtr)WM|u KEYDOWN | wParam==(IntPtr)WM|u SYSKEYDOWN)
{
int vkCode=Marshal.ReadInt32(LPRAM);
如果(OnKeyPressed!=null){OnKeyPressed(这是新的KeyPressedArgs(KeyInterop.KeyFromVirtualKey(vkCode));}
}
返回CallNextHookEx(_hookID,nCode,wParam,lParam);
}
}
public类KeyPressedArgs:EventArgs
{
按公钥键{get;private set;}
公用键按下箭头(键)
{
按键=按键;
}
}
}

我找到了一种不使用任何dll文件的方法,而是读取
/dev/input/eventX
这是一个在连接键盘或任何其他外围设备时生成的文件,系统使用它来了解设备生成的事件

这是c语言的代码#

代码打开
event0
FileStream
,这通常是您想要侦听输入的地方,生成的事件具有标准结构(您可以在此处找到更多信息:),根据我发现的文档,假定
timeval
为16字节,但在本例中,它使用8字节

事件有
类型
这是事件的类型,按下键的
code
,这是键的状态
pressed=1,unpressed=0
(在此处查找更多信息:)。 对于每一个代码,我们需要找到它的可读形式,为此,我创建了一个枚举器,其中包含我需要读取的键(28是enter键)。这些代码可以在上面的链接中找到

 public enum KEY_CODE
{
    KEY_1 = 2,
    KEY_2,
    KEY_3,
    KEY_4,
    KEY_5,
    KEY_6,
    KEY_7,
    KEY_8,
    KEY_9,
    KEY_0,
    KEY_MINUS,
    KEY_EQUAL,
    KEY_BACKSPACE,
    KEY_TAB,
    KEY_Q,
    KEY_W,
    KEY_E,
    KEY_R,
    KEY_T,
    KEY_Y,
    KEY_U,
    KEY_I,
    KEY_O,
    KEY_P,
    KEY_LEFTBRACE,
    KEY_RIGHTBRACE,
    KEY_ENTER,
    KEY_LEFTCTRL,
    KEY_A,
    KEY_S,
    KEY_D,
    KEY_F,
    KEY_G,
    KEY_H,
    KEY_J,
    KEY_K,
    KEY_L,
    KEY_SEMICOLON,
    KEY_APOSTROPHE,
    KEY_GRAVE,
    KEY_LEFTSHIFT,
    KEY_BACKSLASH,
    KEY_Z,
    KEY_X,
    KEY_C,
    KEY_V,
    KEY_B,
    KEY_N,
    KEY_M,
    KEY_COMMA,
    KEY_DOT,
    KEY_SLASH,
    KEY_RIGHTSHIFT,
    KEY_KPASTERISK,
    KEY_LEFTALT,
    KEY_SPACE,
    KEY_CAPSLOCK,
    KEY_F1,
    KEY_F2,
    KEY_F3,
    KEY_F4,
    KEY_F5,
    KEY_F6,
    KEY_F7,
    KEY_F8,
    KEY_F9,
    KEY_F10,
    KEY_NUMLOCK,
    KEY_SCROLLLOCK,
    KEY_KP7,
    KEY_KP8,
    KEY_KP9,
    KEY_KPMINUS,
    KEY_KP4,
    KEY_KP5,
    KEY_KP6,
    KEY_KPPLUS,
    KEY_KP1,
    KEY_KP2,
    KEY_KP3,
    KEY_KP0,
    KEY_KPDOT
}

我找到了一种不使用任何dll文件的方法,而是读取
/dev/input/eventX
这是一个在连接键盘或任何其他外围设备时生成的文件,系统使用它来了解设备生成的事件

这是c语言的代码#

代码打开
event0
FileStream
,这通常是您想要侦听输入的地方,生成的事件具有标准结构(您可以在此处找到更多信息:),根据我发现的文档,假定
timeval
为16字节,但在本例中,它使用8字节

事件有
类型
这是事件的类型,按下键的
code
,这是键的状态
pressed=1,unpressed=0
(在此处查找更多信息:)。 对于每一个代码,我们需要找到它的可读形式,为此,我创建了一个枚举器,其中包含我需要读取的键(28是enter键)。这些代码可以在上面的链接中找到

 public enum KEY_CODE
{
    KEY_1 = 2,
    KEY_2,
    KEY_3,
    KEY_4,
    KEY_5,
    KEY_6,
    KEY_7,
    KEY_8,
    KEY_9,
    KEY_0,
    KEY_MINUS,
    KEY_EQUAL,
    KEY_BACKSPACE,
    KEY_TAB,
    KEY_Q,
    KEY_W,
    KEY_E,
    KEY_R,
    KEY_T,
    KEY_Y,
    KEY_U,
    KEY_I,
    KEY_O,
    KEY_P,
    KEY_LEFTBRACE,
    KEY_RIGHTBRACE,
    KEY_ENTER,
    KEY_LEFTCTRL,
    KEY_A,
    KEY_S,
    KEY_D,
    KEY_F,
    KEY_G,
    KEY_H,
    KEY_J,
    KEY_K,
    KEY_L,
    KEY_SEMICOLON,
    KEY_APOSTROPHE,
    KEY_GRAVE,
    KEY_LEFTSHIFT,
    KEY_BACKSLASH,
    KEY_Z,
    KEY_X,
    KEY_C,
    KEY_V,
    KEY_B,
    KEY_N,
    KEY_M,
    KEY_COMMA,
    KEY_DOT,
    KEY_SLASH,
    KEY_RIGHTSHIFT,
    KEY_KPASTERISK,
    KEY_LEFTALT,
    KEY_SPACE,
    KEY_CAPSLOCK,
    KEY_F1,
    KEY_F2,
    KEY_F3,
    KEY_F4,
    KEY_F5,
    KEY_F6,
    KEY_F7,
    KEY_F8,
    KEY_F9,
    KEY_F10,
    KEY_NUMLOCK,
    KEY_SCROLLLOCK,
    KEY_KP7,
    KEY_KP8,
    KEY_KP9,
    KEY_KPMINUS,
    KEY_KP4,
    KEY_KP5,
    KEY_KP6,
    KEY_KPPLUS,
    KEY_KP1,
    KEY_KP2,
    KEY_KP3,
    KEY_KP0,
    KEY_KPDOT
}