USB输入监控

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace HansCustomEvent.DeviceControl
{
    public class UsbDevice : Control
    {
        public event Action<string> InputDeviceEvent;//获取输入设备名称
        public event Action<char> InputCharEvent;//设备每次输入字符
        public event Action<string> InputOKEvent;//设备输入完成事件
        public string BindDevice { get; set; }//绑定设备名称
        public ushort ReceiveTimeOut = 0;//数据接收超时时间
        public ushort EndCharAsii = 13;//结束字符Ascii码//扫码结束标记ASCII,13表示回车,9标识tab制表符
        string saveData;
        Timer timer = new Timer();


        protected override void WndProc(ref Message message)
        {
            processMessage(message);
            base.WndProc(ref message);
        }

        public void RegisterKeyboardDevice()
        {
            RAWINPUTDEVICE[] rid = new RAWINPUTDEVICE[1];

            rid[0].usUsagePage = 0x01;

            rid[0].usUsage = 0x06;
            //RIDEV_INPUTSINK(程序不再前台也接收数据)
            //RIDEV_NoLegacy(接收数据不显示)
            rid[0].dwFlags = RIDEV_INPUTSINK | RIDEV_NoLegacy;
            //rid[0].dwFlags = RIDEV_INPUTSINK;

            rid[0].hwndTarget = this.Handle;
            RegisterRawInputDevices(rid, (uint)rid.Length, (uint)Marshal.SizeOf(rid[0]));
            timer.Tick -= Timer_Tick;
            timer.Tick += Timer_Tick;
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            InputOKEvent?.BeginInvoke(saveData, null, null);
            //InputOKEvent?.Invoke(saveData);
            saveData = "";
            timer.Stop();
        }

        private void processMessage(Message message)
        {
            if (message.Msg != WM_INPUT)
                return;
            uint dwSize = 0;
            GetRawInputData(message.LParam, RID_INPUT, IntPtr.Zero, ref dwSize, (uint)Marshal.SizeOf(typeof(RAWINPUTHEADER)));
            IntPtr buffer = Marshal.AllocHGlobal((int)dwSize);
            GetRawInputData(message.LParam, RID_INPUT, buffer, ref dwSize, (uint)Marshal.SizeOf(typeof(RAWINPUTHEADER)));
            RAWINPUT raw = (RAWINPUT)Marshal.PtrToStructure(buffer, typeof(RAWINPUT));
            uint size = (uint)Marshal.SizeOf(typeof(RID_DEVICE_INFO));
            GetRawInputDeviceInfo(raw.header.hDevice, RIDI_DEVICENAME, IntPtr.Zero, ref size);
            IntPtr pData = Marshal.AllocHGlobal((int)size);
            GetRawInputDeviceInfo(raw.header.hDevice, RIDI_DEVICENAME, pData, ref size);
            string deviceName = (string)Marshal.PtrToStringAnsi(pData);
            //下面两句是释放了缓存
            Marshal.FreeHGlobal(buffer);
            Marshal.FreeHGlobal(pData);

            //InputDeviceEvent?.BeginInvoke(deviceName, null, null);
            InputDeviceEvent?.Invoke(deviceName);
            if (BindDevice != null && deviceName.Contains(BindDevice))
            {
                //256-KeyDown 257-KeyUp
                if (raw.keyboard.Message == 257) return;
                ushort VKey = raw.keyboard.VKey;

                GetKeyState(0);
                byte[] keyboardState = new byte[256];
                GetKeyboardState(keyboardState);
                char keyChar;
                ToAscii(VKey, raw.keyboard.Message, keyboardState, out keyChar, 0U);
                InputCharEvent?.BeginInvoke(keyChar, null, null);
                if (Glb.StartApp == "10")
                {
                    EndCharAsii = 9;
                }
                if (VKey == EndCharAsii)
                {
                    InputOKEvent?.BeginInvoke(saveData, null, null);
                    //InputOKEvent?.Invoke(saveData);
                    //InputOKEvent?.Invoke(CommunicationMsgType.DataReceived, this, new string[] { saveData, UsbConf.Cmd5 });

                    timer.Stop();
                    saveData = "";
                    return;
                }
                //过滤不可见字符
                if (VKey > 31 && VKey != 127)
                {
                    saveData += keyChar.ToString();
                }

                if (ReceiveTimeOut > 0)
                {
                    timer.Interval = ReceiveTimeOut;
                    timer.Stop();
                    timer.Start();
                }

            }


        }






        #region //基础数据
        private const int RIDEV_INPUTSINK = 0x100;
        private const int RIDEV_NoLegacy = 0x30;
        private const int RIDEV_DEVNOTIFY = 0x00002000;

        private const int RIDEV_REMOVE = 0x00000001;


        private const int WM_INPUT = 0x00FF;
        private const uint RID_INPUT = 0x10000003;
        private const uint RIDI_DEVICENAME = 0x20000007;

        [StructLayout(LayoutKind.Sequential)]
        internal struct RAWINPUTDEVICE
        {
            [MarshalAs(UnmanagedType.U2)]
            public ushort usUsagePage;
            [MarshalAs(UnmanagedType.U2)]
            public ushort usUsage;
            [MarshalAs(UnmanagedType.U4)]
            public int dwFlags;
            public IntPtr hwndTarget;
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct RAWINPUTHEADER
        {
            [MarshalAs(UnmanagedType.U4)]
            public int dwType;

            [MarshalAs(UnmanagedType.U4)]

            public int dwSize;

            public IntPtr hDevice;

            [MarshalAs(UnmanagedType.U4)]

            public int wParam;

        }

        [StructLayout(LayoutKind.Explicit)]
        internal struct RAWINPUT
        {

            [FieldOffset(0)]

            public RAWINPUTHEADER header;

            [FieldOffset(16)]

            public RAWMOUSE mouse;

            [FieldOffset(16)]

            public RAWKEYBOARD keyboard;

            [FieldOffset(16)]

            public RAWHID hid;

        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct RAWKEYBOARD
        {
            [MarshalAs(UnmanagedType.U2)]
            public ushort MakeCode;
            [MarshalAs(UnmanagedType.U2)]

            public ushort Flags;

            [MarshalAs(UnmanagedType.U2)]

            public ushort Reserved;

            [MarshalAs(UnmanagedType.U2)]

            public ushort VKey;

            [MarshalAs(UnmanagedType.U4)]

            public uint Message;

            [MarshalAs(UnmanagedType.U4)]

            public uint ExtraInformation;

        }

        [StructLayout(LayoutKind.Explicit)]
        internal struct RAWMOUSE
        {
            [MarshalAs(UnmanagedType.U2)]
            [FieldOffset(0)]
            public ushort usFlags;
            [MarshalAs(UnmanagedType.U4)]
            [FieldOffset(4)]
            public uint ulButtons;
            [FieldOffset(4)]
            public BUTTONSSTR buttonsStr;
            [MarshalAs(UnmanagedType.U4)]
            [FieldOffset(8)]
            public uint ulRawButtons;
            [FieldOffset(12)]
            public int lLastX;
            [FieldOffset(16)]
            public int lLastY;
            [MarshalAs(UnmanagedType.U4)]
            [FieldOffset(20)]
            public uint ulExtraInformation;
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct BUTTONSSTR
        {
            [MarshalAs(UnmanagedType.U2)]
            public ushort usButtonFlags;
            [MarshalAs(UnmanagedType.U2)]
            public ushort usButtonData;
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct RAWHID
        {
            [MarshalAs(UnmanagedType.U4)]
            public int dwSizHid;
            [MarshalAs(UnmanagedType.U4)]
            public int dwCount;
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct RID_DEVICE_INFO_HID
        {
            [MarshalAs(UnmanagedType.U4)]
            public int dwVendorId;
            [MarshalAs(UnmanagedType.U4)]
            public int dwProductId;
            [MarshalAs(UnmanagedType.U4)]
            public int dwVersionNumber;
            [MarshalAs(UnmanagedType.U2)]
            public ushort usUsagePage;
            [MarshalAs(UnmanagedType.U2)]
            public ushort usUsage;
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct RID_DEVICE_INFO_KEYBOARD
        {
            [MarshalAs(UnmanagedType.U4)]
            public int dwType;
            [MarshalAs(UnmanagedType.U4)]
            public int dwSubType;
            [MarshalAs(UnmanagedType.U4)]
            public int dwKeyboardMode;
            [MarshalAs(UnmanagedType.U4)]
            public int dwNumberOfFunctionKeys;
            [MarshalAs(UnmanagedType.U4)]
            public int dwNumberOfIndicators;
            [MarshalAs(UnmanagedType.U4)]
            public int dwNumberOfKeysTotal;
        }

        [StructLayout(LayoutKind.Explicit)]
        internal struct RID_DEVICE_INFO
        {
            [FieldOffset(0)]
            public int cbSize;
            [FieldOffset(4)]
            public int dwType;
            [FieldOffset(8)]
            public RID_DEVICE_INFO_MOUSE mouse;
            [FieldOffset(8)]
            public RID_DEVICE_INFO_KEYBOARD keyboard;
            [FieldOffset(8)]
            public RID_DEVICE_INFO_HID hid;
        }

        [StructLayout(LayoutKind.Sequential)]
        internal struct RID_DEVICE_INFO_MOUSE
        {
            [MarshalAs(UnmanagedType.U4)]
            public int dwId;
            [MarshalAs(UnmanagedType.U4)]
            public int dwNumberOfButtons;
            [MarshalAs(UnmanagedType.U4)]
            public int dwSampleRate;
            [MarshalAs(UnmanagedType.U4)]
            public int fHasHorizontalWheel;
        }

        [DllImport("User32.dll")]
        extern static uint GetRawInputData(IntPtr hRawInput, uint uiCommand, IntPtr pData, ref uint pcbSize, uint cbSizeHeader);

        [DllImport("User32.dll")]
        extern static bool RegisterRawInputDevices(RAWINPUTDEVICE[] pRawInputDevice, uint uiNumDevices, uint cbSize);

        [DllImport("User32.dll")]
        extern static uint GetRawInputDeviceInfo(IntPtr hDevice, uint uiCommand, IntPtr pData, ref uint pcbSize);

        /// <summary>
        /// 将虚拟键的状态拷贝到缓冲区
        /// </summary>
        /// <param name="lpKeyState">指向一个256字节的数组,数组用于接收每个虚拟键的状态。</param>
        /// <returns></returns>
        // Token: 0x06000024 RID: 36
        [DllImport("user32.dll", BestFitMapping = false, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GetKeyboardState(byte[] lpKeyState);

        /// <summary>
        /// 获取虚拟键状态
        /// </summary>
        /// <param name="nVirtKey"></param>
        /// <returns>高位为1,表示按下,为0表示未按下。低位为1,表示虚拟键被切换。比如按下Caps Lock键,低位为1,反之低位为0</returns>
        // Token: 0x06000025 RID: 37
        [DllImport("user32.dll", BestFitMapping = false, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
        public static extern short GetKeyState(int nVirtKey);

        /// <summary>
        /// 该函数将指定的虚拟键码和键盘状态翻译为相应的字符或字符串。该函数使用由给定的键盘布局句柄标识的物理键盘布局和输入语言来翻译代码。
        /// </summary>
        /// <param name="uVirtKey">指定要翻译的虚拟键码。</param>
        /// <param name="uScanCode">定义被翻译键的硬件扫描码。若该键处于Up状态,则该值的最高位被设置。</param>
        /// <param name="lpKeyState">指向包含当前键盘状态的一个256字节数组。数组的每个成员包含一个键的状态。若某字节的最高位被设置,则该键处于Down状态。若最低位被设置,则表明该键被触发。在此函数中,仅有Caps Lock键的触发位是相关的。Num Lock和Scroll Lock键的触发状态将被忽略。</param>
        /// <param name="lpChar">指向接受翻译所得字符或字符串的缓冲区。</param>
        /// <param name="uFlags">定义一个菜单是否处于激活状态。若一菜单是活动的,则该参数为1,否则为0。</param>
        /// <returns></returns>
        // Token: 0x06000026 RID: 38
        [DllImport("user32.dll", BestFitMapping = false, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
        public static extern int ToAscii(uint uVirtKey, uint uScanCode, byte[] lpKeyState, out char lpChar, uint uFlags);
        #endregion
    }
}
View Code

界面使用案例

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using NetFwTypeLib;
using System.Management; // 需要添加System.Management的引用
using System.Net.NetworkInformation;
using Microsoft.Win32;
using System.Security.Principal;
using HansCommon.INI;
using HansCustomEvent.DeviceControl;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void 打开防火墙_Click(object sender, EventArgs e)
        {
            FirewallOperateByObject(true, true, true);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            FirewallOperateByObject(false, false, false);

        }

        private void button2_Click(object sender, EventArgs e)
        {

            MessageBox.Show($"{Checkadmin()}") ;

        }


        private bool Checkadmin()
        {
            {
                WindowsIdentity current = WindowsIdentity.GetCurrent();
                WindowsPrincipal windowsPrincipal = new WindowsPrincipal(current);
                return windowsPrincipal.IsInRole(WindowsBuiltInRole.Administrator);
            }
        }     
        /// 通过对象防火墙操作
        /// 域网络防火墙(禁用:false;启用(默认):true)
        /// 公共网络防火墙(禁用:false;启用(默认):true)
        /// 专用网络防火墙(禁用: false;启用(默认):true)
        public static bool FirewallOperateByObject(bool isOpenDomain = true, bool isOpenPublicState = true, bool isOpenStandard = true)
        {
            try
            {
                INetFwPolicy2 firewallPolicy = (INetFwPolicy2)Activator.CreateInstance(Type.GetTypeFromProgID("HNetCfg.FwPolicy2"));
                // 启用<高级安全Windows防火墙> - 专有配置文件的防火墙
                firewallPolicy.set_FirewallEnabled(NET_FW_PROFILE_TYPE2_.NET_FW_PROFILE2_PRIVATE, isOpenStandard);
                // 启用<高级安全Windows防火墙> - 公用配置文件的防火墙
                firewallPolicy.set_FirewallEnabled(NET_FW_PROFILE_TYPE2_.NET_FW_PROFILE2_PUBLIC, isOpenPublicState);
                // 启用<高级安全Windows防火墙> - 域配置文件的防火墙
                firewallPolicy.set_FirewallEnabled(NET_FW_PROFILE_TYPE2_.NET_FW_PROFILE2_DOMAIN, isOpenDomain);
            }
            catch (Exception e)
            {
                string error = $"防火墙修改出错:{e.Message}";
                throw new Exception(error);
            }
            return true;
        }

        public IniFileReadUtil iniFileReadUtil = new IniFileReadUtil(@".\FileParameter\GlobalPar\Conf.ini");

        UsbDevice device = new UsbDevice();

        private void button3_Click(object sender, EventArgs e)
        {
            device.BindDevice = textBox1.Text;
            iniFileReadUtil.WriteString("ParmPart1", "logingUserNames", $"{textBox1.Text}");
        }

        private void button4_Click(object sender, EventArgs e)
        {
            textBox2.Clear();
        }
        public string ReadUser()
        {
            return iniFileReadUtil.ReadString("ParmPart1", "logingUserNames", "");
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            textBox1.Text= ReadUser();
            device.InputDeviceEvent += Device_InputDeviceEvent;
            device.InputOKEvent += Device_ReceiveDataEvent;
            device.RegisterKeyboardDevice();
            device.BindDevice = ReadUser();
        }
        private void Device_InputDeviceEvent(string obj)
        {
            textBox1.Text = obj;

        }
        //输入数据
        private void Device_ReceiveDataEvent(string obj)
        {
            Invoke(new MethodInvoker(() =>
            {
                textBox2.Text = obj;
            
               
            }));
            //MessageBox.Show(obj);
            Console.WriteLine($"{obj}");
           
        }
    }
}
View Code

 

posted @ 2025-11-27 22:41  家煜宝宝  阅读(2)  评论(0)    收藏  举报