private static DeviceEventInfo TransformDeviceEvent(ref Message m) { var tm = new DeviceEventInfo { DEVICEEVENT = (ServicesAPI.SERVICE_CONTROL_DEVICEEVENT_Control)(int) m.WParam }; DEV_BROADCAST_HDR dbh = (DEV_BROADCAST_HDR)Marshal.PtrToStructure(m.LParam, typeof(DEV_BROADCAST_HDR)); tm.DeviceType = dbh.dbch_devicetype; switch (dbh.dbch_devicetype) { case dbch_devicetype.DBT_DEVTYP_DEVICEINTERFACE: DEV_BROADCAST_DEVICEINTERFACE dbdi = (DEV_BROADCAST_DEVICEINTERFACE)Marshal.PtrToStructure(m.LParam, typeof(DEV_BROADCAST_DEVICEINTERFACE)); tm.DeviceId = cstr_to_string(dbdi.dbcc_name); tm.DeviceName = ConvertDbccNameToFriendlyName(cstr_to_string(dbdi.dbcc_name)); break; case dbch_devicetype.DBT_DEVTYP_HANDLE: DEV_BROADCAST_HANDLE dbbh = (DEV_BROADCAST_HANDLE)Marshal.PtrToStructure(m.LParam, typeof(DEV_BROADCAST_HANDLE)); tm.DeviceName = "Handle Id " + dbbh.dbch_handle.ToString(); break; case dbch_devicetype.DBT_DEVTYP_OEM: DEV_BROADCAST_OEM dbo = (DEV_BROADCAST_OEM)Marshal.PtrToStructure(m.LParam, typeof(DEV_BROADCAST_OEM)); tm.DeviceName = string.Format("OEM: {0} Value: {1}", dbo.dbco_identifier, dbo.dbco_suppfunc); break; case dbch_devicetype.DBT_DEVTYP_PORT: DEV_BROADCAST_PORT dbp = (DEV_BROADCAST_PORT)Marshal.PtrToStructure(m.LParam, typeof(DEV_BROADCAST_PORT)); IntPtr pData = (IntPtr)(m.LParam.ToInt32() + dbp.dbcp_size); // (*1) IntPtr offsetDbcpName = Marshal.OffsetOf(typeof(DEV_BROADCAST_PORT), "dbcp_name"); int len = (int)pData - (int)offsetDbcpName; tm.DeviceName = Marshal.PtrToStringAuto(offsetDbcpName, len); break; case dbch_devicetype.DBT_DEVTYP_VOLUME: DEV_BROADCAST_VOLUME dbv = (DEV_BROADCAST_VOLUME)Marshal.PtrToStructure(m.LParam, typeof(DEV_BROADCAST_VOLUME)); tm.DeviceName = dbv.dbcv_unitmask.ToString(); if (dbv.dbcv_flags != dbcv_flags.None) { tm.DeviceName += " " + dbv.dbcv_flags.ToString(); } break; } //dbh.dbch_devicetype == dbch_devicetype. //IntPtr pData = (IntPtr)(m.LParam.ToInt32() + Marshal.SizeOf(ps)); // (*1) return(tm); }
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); }
protected override void WndProc(ref Message m) { switch (m.Msg) { case WM_CREATE: try { DEV_BROADCAST_DEVICEINTERFACE devBroadcastDeviceInterface = new DEV_BROADCAST_DEVICEINTERFACE(); IntPtr devBroadcastDeviceInterfaceBuffer; IntPtr deviceNotificationHandle = IntPtr.Zero; Int32 size = 0; // frmMy is the form that will receive device-change messages. size = Marshal.SizeOf(devBroadcastDeviceInterface); devBroadcastDeviceInterface.dbcc_size = size; devBroadcastDeviceInterface.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; devBroadcastDeviceInterface.dbcc_reserved = 0; devBroadcastDeviceInterface.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE.ToByteArray(); devBroadcastDeviceInterfaceBuffer = Marshal.AllocHGlobal(size); Marshal.StructureToPtr(devBroadcastDeviceInterface, devBroadcastDeviceInterfaceBuffer, true); deviceNotificationHandle = NativeMethods.RegisterDeviceNotification(this.Handle, devBroadcastDeviceInterfaceBuffer, DEVICE_NOTIFY_WINDOW_HANDLE); } catch { } break; case WM_DEVICECHANGE: // The WParam value identifies what is occurring. WM_DEVICECHANGE_enum n = (WM_DEVICECHANGE_enum)m.WParam; int l = (int)m.LParam; if (n == WM_DEVICECHANGE_enum.DBT_DEVICEREMOVEPENDING) { Console.WriteLine("DBT_DEVICEREMOVEPENDING"); } if (n == WM_DEVICECHANGE_enum.DBT_DEVNODES_CHANGED) { Console.WriteLine("DBT_DEVNODES_CHANGED"); } if (n == WM_DEVICECHANGE_enum.DBT_DEVICEARRIVAL || n == WM_DEVICECHANGE_enum.DBT_DEVICEREMOVECOMPLETE) { Console.WriteLine(((WM_DEVICECHANGE_enum)n).ToString()); DEV_BROADCAST_HDR hdr = new DEV_BROADCAST_HDR(); Marshal.PtrToStructure(m.LParam, hdr); try { switch (hdr.dbch_devicetype) { case DBT_DEVTYP_DEVICEINTERFACE: DEV_BROADCAST_DEVICEINTERFACE inter = new DEV_BROADCAST_DEVICEINTERFACE(); Marshal.PtrToStructure(m.LParam, inter); log.InfoFormat("Interface {0}", ASCIIEncoding.Unicode.GetString(inter.dbcc_name, 0, inter.dbcc_size - (4 * 3))); break; case DBT_DEVTYP_PORT: DEV_BROADCAST_PORT prt = new DEV_BROADCAST_PORT(); Marshal.PtrToStructure(m.LParam, prt); log.InfoFormat("port {0}", ASCIIEncoding.Unicode.GetString(prt.dbcp_name, 0, prt.dbcp_size - (4 * 3))); break; } } catch { } //string port = Marshal.PtrToStringAuto((IntPtr)((long)m.LParam + 12)); //Console.WriteLine("Added port {0}",port); } log.InfoFormat("Device Change {0} {1} {2}", m.Msg, (WM_DEVICECHANGE_enum)m.WParam, m.LParam); if (DeviceChanged != null) { try { DeviceChanged((WM_DEVICECHANGE_enum)m.WParam); } catch { } } foreach (Plugin.Plugin item in MissionPlanner.Plugin.PluginLoader.Plugins) { item.Host.ProcessDeviceChanged((WM_DEVICECHANGE_enum)m.WParam); } break; default: break; } base.WndProc(ref m); }
protected override void WndProc(ref Message m) { base.WndProc(ref m); //Log.PrintLine(TAG, LogLevel.Information, $"WndProc m={m}"); switch (m.Msg) { case WM_DEVICECHANGE: { var wParam = m.WParam.ToInt32(); //Log.PrintLine(TAG, LogLevel.Information, $"WndProc WM_DEVICECHANGE wParam=0x{wParam:X8}"); /* * var serialPorts = SerialPort.GetPortNames().OrderBy(name => name); * foreach (var serialPort in serialPorts) * { * Log.PrintLine(TAG, LogLevel.Information, $"WndProc WM_DEVICECHANGE serialPort={serialPort}"); * } */ switch (wParam) { /* * case DBT_DEVNODES_CHANGED: * { * Log.PrintLine(TAG, LogLevel.Information, "WndProc DBT_DEVNODES_CHANGED"); * break; * } */ case DBT_DEVICEARRIVAL: case DBT_DEVICEREMOVECOMPLETE: { ChangeType changeType; switch (wParam) { case DBT_DEVICEARRIVAL: changeType = ChangeType.Add; break; case DBT_DEVICEREMOVECOMPLETE: changeType = ChangeType.Remove; break; default: return; } var lParam = m.LParam; DEV_BROADCAST_HDR pHdr = (DEV_BROADCAST_HDR)Marshal.PtrToStructure(lParam, typeof(DEV_BROADCAST_HDR)); var deviceType = pHdr.dbch_DeviceType; Log.PrintLine(TAG, LogLevel.Information, $"WndProc {changeType} deviceType={deviceType}"); switch (deviceType) { case DBT_DEVTYP_DEVICEINTERFACE: { //Log.PrintLine(TAG, LogLevel.Information, $"WndProc {changeType} devType=DBT_DEVTYP_DEVICEINTERFACE"); DEV_BROADCAST_DEVICEINTERFACE pDevice = (DEV_BROADCAST_DEVICEINTERFACE)Marshal.PtrToStructure(lParam, typeof(DEV_BROADCAST_DEVICEINTERFACE)); var deviceName = pDevice.dbcc_name; Log.PrintLine(TAG, LogLevel.Information, $"WndProc {changeType} pDevice.dbcc_name={Utils.Quote(deviceName)}"); /* * deviceName = CleanUpDeviceInterfaceName(deviceName); * if (DeviceNamesSubscribed.Contains(deviceName)) * { * OnUsbChange?.Invoke(this, new UsbChangeEventArgs(changeType, deviceName)); * } */ break; } case DBT_DEVTYP_PORT: { //Log.PrintLine(TAG, LogLevel.Information, $"WndProc {changeType} devType=DBT_DEVTYP_PORT"); DEV_BROADCAST_PORT pPort = (DEV_BROADCAST_PORT)Marshal.PtrToStructure(lParam, typeof(DEV_BROADCAST_PORT)); var portName = pPort.dbcp_name; Log.PrintLine(TAG, LogLevel.Information, $"WndProc {changeType} pPort.dbcp_name={Utils.Quote(portName)}"); /* * if (SerialPortsSubscribed.Contains(portName)) * { * OnSerialPortChange?.Invoke(this, new SerialPortChangeEventArgs(changeType, portName)); * } */ break; } } break; } } break; } } }
protected override void WndProc(ref Message m) { switch (m.Msg) { case WM_CREATE: try { DEV_BROADCAST_DEVICEINTERFACE devBroadcastDeviceInterface = new DEV_BROADCAST_DEVICEINTERFACE(); IntPtr devBroadcastDeviceInterfaceBuffer; IntPtr deviceNotificationHandle = IntPtr.Zero; Int32 size = 0; // frmMy is the form that will receive device-change messages. size = Marshal.SizeOf(devBroadcastDeviceInterface); devBroadcastDeviceInterface.dbcc_size = size; devBroadcastDeviceInterface.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; devBroadcastDeviceInterface.dbcc_reserved = 0; devBroadcastDeviceInterface.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE.ToByteArray(); devBroadcastDeviceInterfaceBuffer = Marshal.AllocHGlobal(size); Marshal.StructureToPtr(devBroadcastDeviceInterface, devBroadcastDeviceInterfaceBuffer, true); deviceNotificationHandle = NativeMethods.RegisterDeviceNotification(this.Handle, devBroadcastDeviceInterfaceBuffer, DEVICE_NOTIFY_WINDOW_HANDLE); } catch { } break; case WM_DEVICECHANGE: // The WParam value identifies what is occurring. WM_DEVICECHANGE_enum n = (WM_DEVICECHANGE_enum)m.WParam; var l = m.LParam; if (n == WM_DEVICECHANGE_enum.DBT_DEVICEREMOVEPENDING) { Console.WriteLine("DBT_DEVICEREMOVEPENDING"); } if (n == WM_DEVICECHANGE_enum.DBT_DEVNODES_CHANGED) { Console.WriteLine("DBT_DEVNODES_CHANGED"); } if (n == WM_DEVICECHANGE_enum.DBT_DEVICEARRIVAL || n == WM_DEVICECHANGE_enum.DBT_DEVICEREMOVECOMPLETE) { Console.WriteLine(((WM_DEVICECHANGE_enum)n).ToString()); DEV_BROADCAST_HDR hdr = new DEV_BROADCAST_HDR(); Marshal.PtrToStructure(m.LParam, hdr); try { switch (hdr.dbch_devicetype) { case DBT_DEVTYP_DEVICEINTERFACE: DEV_BROADCAST_DEVICEINTERFACE inter = new DEV_BROADCAST_DEVICEINTERFACE(); Marshal.PtrToStructure(m.LParam, inter); log.InfoFormat("Interface {0}", ASCIIEncoding.Unicode.GetString(inter.dbcc_name, 0, inter.dbcc_size - (4 * 3))); break; case DBT_DEVTYP_PORT: DEV_BROADCAST_PORT prt = new DEV_BROADCAST_PORT(); Marshal.PtrToStructure(m.LParam, prt); log.InfoFormat("port {0}", ASCIIEncoding.Unicode.GetString(prt.dbcp_name, 0, prt.dbcp_size - (4 * 3))); this.BeginInvoke(new Action(() => { textBox1.AppendText("port " + ASCIIEncoding.Unicode.GetString(prt.dbcp_name, 0, prt.dbcp_size - (4 * 3)).Trim().TrimEnd('\0') + "\r\n"); })); new Thread(FWUpload).Start(new Tuple <int, string>(index++, ASCIIEncoding.Unicode.GetString(prt.dbcp_name, 0, prt.dbcp_size - (4 * 3)) .Trim().TrimEnd('\0'))); break; } } catch { } //string port = Marshal.PtrToStringAuto((IntPtr)((long)m.LParam + 12)); //Console.WriteLine("Added port {0}",port); } log.InfoFormat("Device Change {0} {1} {2}", m.Msg, (WM_DEVICECHANGE_enum)m.WParam, m.LParam); if (DeviceChanged != null) { try { DeviceChanged((WM_DEVICECHANGE_enum)m.WParam); } catch { } } break; default: //Console.WriteLine(m.ToString()); break; } base.WndProc(ref m); }
/// <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; }; }
protected override void WndProc(ref Message m) { switch (m.Msg) { case WM_CREATE: try { DEV_BROADCAST_DEVICEINTERFACE devBroadcastDeviceInterface = new DEV_BROADCAST_DEVICEINTERFACE(); IntPtr devBroadcastDeviceInterfaceBuffer; IntPtr deviceNotificationHandle = IntPtr.Zero; Int32 size = 0; // frmMy is the form that will receive device-change messages. size = Marshal.SizeOf(devBroadcastDeviceInterface); devBroadcastDeviceInterface.dbcc_size = size; devBroadcastDeviceInterface.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; devBroadcastDeviceInterface.dbcc_reserved = 0; devBroadcastDeviceInterface.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE.ToByteArray(); devBroadcastDeviceInterfaceBuffer = Marshal.AllocHGlobal(size); Marshal.StructureToPtr(devBroadcastDeviceInterface, devBroadcastDeviceInterfaceBuffer, true); deviceNotificationHandle = NativeMethods.RegisterDeviceNotification(this.Handle, devBroadcastDeviceInterfaceBuffer, DEVICE_NOTIFY_WINDOW_HANDLE); } catch { } break; case WM_DEVICECHANGE: // The WParam value identifies what is occurring. WM_DEVICECHANGE_enum n = (WM_DEVICECHANGE_enum)m.WParam; var l = m.LParam; if (n == WM_DEVICECHANGE_enum.DBT_DEVICEREMOVEPENDING) { Console.WriteLine("DBT_DEVICEREMOVEPENDING"); } if (n == WM_DEVICECHANGE_enum.DBT_DEVNODES_CHANGED) { Console.WriteLine("DBT_DEVNODES_CHANGED"); // DoScan(); } if (n == WM_DEVICECHANGE_enum.DBT_DEVICEARRIVAL) { Console.WriteLine(((WM_DEVICECHANGE_enum)n).ToString()); DEV_BROADCAST_HDR hdr = new DEV_BROADCAST_HDR(); Marshal.PtrToStructure(m.LParam, hdr); try { switch (hdr.dbch_devicetype) { case DBT_DEVTYP_DEVICEINTERFACE: DEV_BROADCAST_DEVICEINTERFACE inter = new DEV_BROADCAST_DEVICEINTERFACE(); Marshal.PtrToStructure(m.LParam, inter); var devname = GetDeviceName(inter); Console.WriteLine("Interface {0} {1}", inter.dbcc_name, devname); break; case DBT_DEVTYP_PORT: DEV_BROADCAST_PORT prt = new DEV_BROADCAST_PORT(); Marshal.PtrToStructure(m.LParam, prt); Console.WriteLine("port {0}", prt.dbcp_name); Uploader up = null; try { up = new px4uploader.Uploader(new SerialPort(prt.dbcp_name, 115200)); up.identify(); up.close(); } catch { } break; } } catch { } //string port = Marshal.PtrToStringAuto((IntPtr)((long)m.LParam + 12)); //Console.WriteLine("Added port {0}",port); } Console.WriteLine("Device Change {0} {1} {2}", m.Msg, (WM_DEVICECHANGE_enum)m.WParam, m.LParam); if (DeviceChanged != null) { try { DeviceChanged((WM_DEVICECHANGE_enum)m.WParam); } catch { } } break; default: //Console.WriteLine(m.ToString()); break; } base.WndProc(ref m); }