protected IntPtr WindowProcHandler(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { MessageType msgType = (MessageType)msg; Console.WriteLine(msgType); if (msg == (int)MessageType.WM_DEVICECHANGE) { DeviceBroadcastType dbt = (DeviceBroadcastType)wParam.ToInt32(); Console.WriteLine(dbt); switch (dbt) { case DeviceBroadcastType.DBT_DEVICEARRIVAL: case DeviceBroadcastType.DBT_DEVICEREMOVECOMPLETE: Console.WriteLine(dbt == DeviceBroadcastType.DBT_DEVICEARRIVAL ? "Device Arrival" : "Device Move Complete"); DEV_BROADCAST_HDR hdr = Marshal.PtrToStructure <DEV_BROADCAST_HDR>(lParam); Console.WriteLine("{0}", hdr); if (hdr.dbch_devicetype == DeviceType.DBT_DEVTYP_PORT) { DEV_BROADCAST_PORT port = Marshal.PtrToStructure <DEV_BROADCAST_PORT>(lParam); Console.WriteLine(port); } if (hdr.dbch_devicetype == DeviceType.DBT_DEVTYP_VOLUME) { DEV_BROADCAST_VOLUME volume = Marshal.PtrToStructure <DEV_BROADCAST_VOLUME>(lParam); Console.WriteLine(volume); } break; default: break; } handled = true; } return(IntPtr.Zero); }
/// <summary> /// 串口设备热插拔自动重新连接 /// <para>使用 HwndSource Hook Window Message #WM_DEVICECHANGE 事件监听模式</para> /// </summary> /// <param name="serialPort"></param> /// <param name="window">IsLoaded 为 True 的窗口对象</param> public static void AutoReconnection(this SerialPort serialPort, System.Windows.Window window) { if (serialPort == null || window == null) { throw new ArgumentException("参数不能为空"); } if (!window.IsLoaded) { throw new InvalidOperationException("Window 对象 IsLoaded 为 True 时才能获取窗口句柄"); } SpaceCGUtils.Log.InfoFormat("HwndSource Hook Window Message #WM_DEVICECHANGE Event Listen SerialPort Name:{0}", serialPort.PortName); HwndSource hwndSource = HwndSource.FromVisual(window) as HwndSource; if (hwndSource != null) { hwndSource.AddHook((IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) => { MessageType mt = (MessageType)msg; if (mt != MessageType.WM_DEVICECHANGE) { return(IntPtr.Zero); } DeviceBroadcastType dbt = (DeviceBroadcastType)wParam.ToInt32(); if (dbt == DeviceBroadcastType.DBT_DEVICEARRIVAL || dbt == DeviceBroadcastType.DBT_DEVICEREMOVECOMPLETE) { DEV_BROADCAST_HDR hdr = (DEV_BROADCAST_HDR)Marshal.PtrToStructure(lParam, typeof(DEV_BROADCAST_HDR)); if (hdr.dbch_devicetype != DeviceType.DBT_DEVTYP_PORT) { return(IntPtr.Zero); } DEV_BROADCAST_PORT port = (DEV_BROADCAST_PORT)Marshal.PtrToStructure(lParam, typeof(DEV_BROADCAST_PORT)); if (port.dbcp_name.ToUpper() != serialPort.PortName.ToUpper()) { return(IntPtr.Zero); } if (dbt == DeviceBroadcastType.DBT_DEVICEARRIVAL) { if (!serialPort.IsOpen) { serialPort.Open(); } SpaceCGUtils.Log.InfoFormat("Device Arrival SerialPort Name:{0}", port.dbcp_name); } if (dbt == DeviceBroadcastType.DBT_DEVICEREMOVECOMPLETE) { if (serialPort.IsOpen) { serialPort.Close(); } SpaceCGUtils.Log.ErrorFormat("Device Remove Complete SerialPort Name:{0}", port.dbcp_name); } handled = true; } return(IntPtr.Zero); }); } window.Closing += (s, e) => { hwndSource?.Dispose(); hwndSource = null; }; }