Exe net10.0-windows enable disable CS8600;CS8601;CS8602;CS8603;CS8604;CS8618;CS8620;CS8625;CA1416 tools/SolidWorksHoverProbe/Program.cs Full file content failed to load using SolidWorks.Interop.sldworks; using SolidWorks.Interop.swconst; using System.Runtime.InteropServices; using System.Text; namespace SolidWorksHoverProbe; internal static class Program { private static string _lastSignature = ""; private static ModelDoc2 _activeDoc; private static DrawingDoc _drawingDoc; private static DDrawingDocEvents_Event _drawingEvents; private static DDrawingDocEvents_DynamicHighlightNotifyEventHandler _dynamicHighlightHandler; private static DMouseEvents_Event _mouseEvents; private static DMouseEvents_MouseMoveNotifyEventHandler _mouseMoveHandler; [DllImport("ole32.dll", CharSet = CharSet.Unicode)] private static extern int CLSIDFromProgID(string progId, out Guid clsid); [DllImport("oleaut32.dll", PreserveSig = false)] [return: MarshalAs(UnmanagedType.IUnknown)] private static extern object GetActiveObject(ref Guid clsid, IntPtr reserved); [DllImport("user32.dll")] private static extern bool GetCursorPos(out Point point); [STAThread] private static int Main(string[] args) { var pollMs = args.Length > 0 && int.TryParse(args[0], out var parsed) ? Math.Max(parsed, 50) : 200; try { var sw = ConnectSolidWorks(); _activeDoc = sw.ActiveDoc as ModelDoc2 ?? throw new InvalidOperationException("SolidWorks does not have an active document."); if (Safe(() => _activeDoc.GetType(), 0) != (int)swDocumentTypes_e.swDocDRAWING) throw new InvalidOperationException("Active SolidWorks document is not a drawing. Please activate the SLDDRW window first."); _drawingDoc = _activeDoc as DrawingDoc ?? throw new InvalidOperationException("Active document cannot be cast to DrawingDoc."); HookEvents(); Console.OutputEncoding = Encoding.UTF8; Console.WriteLine("SolidWorks hover probe is running."); Console.WriteLine("Put the mouse over a drawing edge/section line without clicking."); Console.WriteLine("Press Ctrl+C to stop."); Console.WriteLine(); while (true) { PrintProbe("poll"); Thread.Sleep(pollMs); } } catch (Exception ex) { Console.Error.WriteLine(ex); return 1; } } private static SldWorks ConnectSolidWorks() { int hr = CLSIDFromProgID("SldWorks.Application", out var clsid); if (hr < 0) Marshal.ThrowExceptionForHR(hr); return (SldWorks)GetActiveObject(ref clsid, IntPtr.Zero); } private static void HookEvents() { try { _drawingEvents = _drawingDoc as DDrawingDocEvents_Event; if (_drawingEvents != null) { _dynamicHighlightHandler = OnDynamicHighlight; _drawingEvents.DynamicHighlightNotify += _dynamicHighlightHandler; } } catch (Exception ex) { Console.WriteLine("DynamicHighlightNotify hook failed: " + ex.Message); } try { var modelView = _activeDoc.ActiveView as ModelView; var mouse = modelView?.GetMouse(); _mouseEvents = mouse as DMouseEvents_Event; if (_mouseEvents != null) { _mouseMoveHandler = OnMouseMove; _mouseEvents.MouseMoveNotify += _mouseMoveHandler; } } catch (Exception ex) { Console.WriteLine("MouseMoveNotify hook failed: " + ex.Message); } } private static int OnDynamicHighlight(bool highlightState) { PrintProbe("DynamicHighlightNotify highlight=" + highlightState); return 0; } private static int OnMouseMove(int x, int y, int wParam) { PrintProbe($"MouseMoveNotify x={x} y={y}"); return 0; } private static void PrintProbe(string trigger) { try { var probe = ReadProbe(trigger); if (probe.Signature == _lastSignature) return; _lastSignature = probe.Signature; Console.WriteLine("---- " + DateTime.Now.ToString("HH:mm:ss.fff") + " " + trigger + " ----"); foreach (var line in probe.Lines) Console.WriteLine(line); Console.WriteLine(); } catch (Exception ex) { Console.WriteLine("probe failed: " + ex.Message); } } private static ProbeResult ReadProbe(string trigger) { var lines = new List(); GetCursorPos(out var cursor); lines.Add($"cursor_screen=({cursor.X},{cursor.Y})"); lines.Add("doc_title=" + Safe(() => _activeDoc.GetTitle(), "")); var selectionMgr = _activeDoc.SelectionManager as SelectionMgr; if (selectionMgr == null) { lines.Add("selection_manager=null"); return new ProbeResult(trigger + "|selection_manager=null", lines); } var preselected = Safe(() => selectionMgr.GetPreSelectedObject(), null); lines.Add("preselected=" + DescribeObject(preselected)); AppendEntityOwnership(lines, "preselected", preselected, null); var selectedCount = Safe(() => selectionMgr.GetSelectedObjectCount2(-1), 0); lines.Add("selected_count=" + selectedCount); for (var i = 1; i <= Math.Min(selectedCount, 5); i++) { var selected = Safe(() => selectionMgr.GetSelectedObject6(i, -1), null); var selectedType = Safe(() => selectionMgr.GetSelectedObjectType3(i, -1), 0); var drawingView = Safe(() => selectionMgr.GetSelectedObjectsDrawingView2(i, -1), null); var point = DoubleArray(Safe(() => selectionMgr.GetSelectionPoint2(i, -1), null)); lines.Add($"selected[{i}].type={SelectionTypeName(selectedType)}({selectedType})"); lines.Add($"selected[{i}].object={DescribeObject(selected)}"); lines.Add($"selected[{i}].drawing_view={DescribeView(drawingView)}"); if (point.Count > 0) lines.Add($"selected[{i}].point_m=({string.Join(",", point.Select(v => v.ToString("G6")))})"); AppendEntityOwnership(lines, $"selected[{i}]", selected, drawingView); } var signature = string.Join("|", lines); return new ProbeResult(signature, lines); } private static void AppendEntityOwnership(List lines, string prefix, object obj, View selectedView) { if (obj is not IEntity entity) { lines.Add(prefix + ".entity=no"); return; } lines.Add(prefix + ".entity=yes"); var component = Safe(() => entity.GetComponent() as Component2, null); lines.Add(prefix + ".entity_component=" + DescribeComponent(component)); var candidateViews = EnumerateCandidateViews(selectedView).ToList(); foreach (var view in candidateViews) { var drawingComponent = Safe(() => entity.GetDrawingComponent(view), null); if (drawingComponent == null) { lines.Add(prefix + $".drawing_component[{DescribeView(view)}]=null"); continue; } lines.Add(prefix + $".drawing_component[{DescribeView(view)}]=" + DescribeDrawingComponent(drawingComponent)); } } private static IEnumerable EnumerateCandidateViews(View selectedView) { if (selectedView != null) yield return selectedView; var activeView = Safe(() => _drawingDoc.ActiveDrawingView, null); if (activeView != null && !SameComObject(activeView, selectedView)) yield return activeView; var viewObj = Safe(() => _drawingDoc.GetFirstView(), null); var guard = 0; while (viewObj is View view && guard++ < 200) { if (!SameComObject(view, selectedView) && !SameComObject(view, activeView)) yield return view; viewObj = Safe(() => view.GetNextView(), null); } } private static string DescribeObject(object obj) { if (obj == null) return "null"; var parts = new List { "runtime=" + (obj.GetType().FullName ?? obj.GetType().Name), "com=" + ComIdentity(obj) }; AddIf(parts, "name", Safe(() => Convert.ToString(GetMember(obj, "Name")), "")); AddIf(parts, "name2", Safe(() => Convert.ToString(GetMember(obj, "Name2")), "")); AddIf(parts, "typeName", Safe(() => Convert.ToString(Invoke(obj, "GetTypeName2")), "")); AddIf(parts, "selectName", Safe(() => Convert.ToString(Invoke(obj, "GetSelectByIDString")), "")); return string.Join("; ", parts); } private static string DescribeDrawingComponent(DrawingComponent drawingComponent) { if (drawingComponent == null) return "null"; var component = Safe(() => drawingComponent.Component as Component2, null); return string.Join("; ", new[] { "drawing_name=" + Safe(() => drawingComponent.Name, ""), "visible=" + Safe(() => drawingComponent.Visible, false), "component=" + DescribeComponent(component) }); } private static string DescribeComponent(Component2 component) { if (component == null) return "null"; return string.Join("; ", new[] { "name=" + Safe(() => component.Name2, ""), "path=" + Safe(() => component.GetPathName(), ""), "config=" + Safe(() => component.ReferencedConfiguration, "") }); } private static string DescribeView(View view) { if (view == null) return "null"; var name = Safe(() => view.GetName2(), Safe(() => view.Name, "")); var type = Safe(() => view.Type, 0); return $"{name}/type={DrawingViewTypeName(type)}({type})"; } private static string DrawingViewTypeName(int typeCode) { return typeCode switch { 1 => "Model", 2 => "Projected", 3 => "Auxiliary", 4 => "Section", 5 => "Detail", 6 => "Relative", 7 => "Detached", 8 => "Standard", 9 => "Named", 10 => "Empty", _ => "Unknown" }; } private static string SelectionTypeName(int type) { return Enum.GetName(typeof(swSelectType_e), type) ?? "unknown"; } private static object Invoke(object target, string name, params object[] args) { return target?.GetType().InvokeMember( name, System.Reflection.BindingFlags.InvokeMethod, null, target, args); } private static object GetMember(object target, string name) { return target?.GetType().InvokeMember( name, System.Reflection.BindingFlags.GetProperty | System.Reflection.BindingFlags.GetField, null, target, Array.Empty()); } private static void AddIf(List parts, string key, string value) { if (!string.IsNullOrWhiteSpace(value)) parts.Add(key + "=" + value); } private static string ComIdentity(object obj) { if (obj == null) return ""; try { var ptr = Marshal.GetIUnknownForObject(obj); try { return "0x" + ptr.ToInt64().ToString("X"); } finally { Marshal.Release(ptr); } } catch { return ""; } } private static bool SameComObject(object left, object right) { if (left == null || right == null) return false; return ComIdentity(left) == ComIdentity(right); } private static List DoubleArray(object value) { if (value == null) return new List(); if (value is double[] doubles) return doubles.ToList(); if (value is object[] objects) return objects.Where(x => x != null).Select(Convert.ToDouble).ToList(); if (value is Array array) { var values = new List(); foreach (var item in array) { if (item != null) values.Add(Convert.ToDouble(item)); } return values; } return new List(); } private static T Safe(Func action, T fallback) { try { return action(); } catch { return fallback; } } private readonly record struct Point(int X, int Y); private sealed record ProbeResult(string Signature, List Lines); }