From 48e2f108a8d67b29a3faf71f4102c027ded69af7 Mon Sep 17 00:00:00 2001 From: Matthias Heil Date: Thu, 2 Apr 2026 10:09:10 +0200 Subject: [PATCH] Renamed --- .../IEnumerableVisualizerProvider.cs | 74 +++++++++++++++++ .../IEnumerableVisualizerSource.cs | 69 ++++++++++++++++ .../.vsextension/string-resources.json | 0 .../ExtensionEntrypoint.cs | 2 +- .../NrxDebugVisualizer.csproj | 4 +- .../NrxDebuggerVisualizerProvider.cs | 15 ++-- .../Vector3VisualizerUserControl.cs | 6 +- .../Vector3VisualizerUserControl.xaml | 0 .../NrxVisualizerObjectSource.cs | 16 ++-- .../NrxVisualizerObjectSource.csproj | 0 .../Vector3Model.cs | 2 +- Vector3Visualizer/MyRemoteUserControl.cs | 80 ------------------- Vector3VisualizerTest/Program.cs | 2 +- VisualizerExtensionExample.slnx | 6 +- 14 files changed, 172 insertions(+), 104 deletions(-) create mode 100644 IEnumerableVisualizer/IEnumerableVisualizerProvider.cs create mode 100644 IEnumerableVisualizer/IEnumerableVisualizerSource.cs rename {Vector3Visualizer => NrxDebuggerVisualizerProvider}/.vsextension/string-resources.json (100%) rename {Vector3Visualizer => NrxDebuggerVisualizerProvider}/ExtensionEntrypoint.cs (97%) rename Vector3Visualizer/Vector3Visualizer.csproj => NrxDebuggerVisualizerProvider/NrxDebugVisualizer.csproj (87%) rename Vector3Visualizer/Vector3DebuggerVisualizerProvider.cs => NrxDebuggerVisualizerProvider/NrxDebuggerVisualizerProvider.cs (84%) rename {Vector3Visualizer => NrxDebuggerVisualizerProvider}/Vector3VisualizerUserControl.cs (70%) rename {Vector3Visualizer => NrxDebuggerVisualizerProvider}/Vector3VisualizerUserControl.xaml (100%) rename Vector3VisualizerSource/Vector3ObjectSource.cs => NrxVisualizerObjectSource/NrxVisualizerObjectSource.cs (65%) rename Vector3VisualizerSource/Vector3VisualizerSource.csproj => NrxVisualizerObjectSource/NrxVisualizerObjectSource.csproj (100%) rename {Vector3VisualizerSource => NrxVisualizerObjectSource}/Vector3Model.cs (86%) delete mode 100644 Vector3Visualizer/MyRemoteUserControl.cs diff --git a/IEnumerableVisualizer/IEnumerableVisualizerProvider.cs b/IEnumerableVisualizer/IEnumerableVisualizerProvider.cs new file mode 100644 index 0000000..66017ed --- /dev/null +++ b/IEnumerableVisualizer/IEnumerableVisualizerProvider.cs @@ -0,0 +1,74 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.VisualStudio.DebuggerVisualizers.ExtensionProviders.IEnumerableVisualizerProvider +// Assembly: Microsoft.VisualStudio.DebuggerVisualizers.ExtensionProviders, Version=18.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a +// MVID: 98A3FADF-73D8-4308-9C72-EE68F73E4141 +// Assembly location: C:\Program Files\Microsoft Visual Studio\18\Professional\Common7\IDE\CommonExtensions\Platform\Debugger\Visualizers\Microsoft.VisualStudio.DebuggerVisualizers.ExtensionProviders.dll + +using Microsoft.Internal.VisualStudio.Shell.Interop; +using Microsoft.VisualStudio.Debugger.IEnumerableVisualizer; +using Microsoft.VisualStudio.Debugger.TabularDataUIShared.WPF; +using Microsoft.VisualStudio.Extensibility; +using Microsoft.VisualStudio.Extensibility.DebuggerVisualizers; +using Microsoft.VisualStudio.Extensibility.VSSdkCompatibility; +using Microsoft.VisualStudio.RpcContracts.DebuggerVisualizers; +using Microsoft.VisualStudio.RpcContracts.RemoteUI; +using Microsoft.VisualStudio.Shell; +using Microsoft.VisualStudio.Shell.Interop; +using System; +using System.Diagnostics; +using System.Threading; +using System.Threading.Tasks; +using System.Windows; + +#nullable enable +namespace Microsoft.VisualStudio.DebuggerVisualizers.ExtensionProviders; + +[VisualStudioContribution] +internal class IEnumerableVisualizerProvider : DebuggerVisualizerProvider +{ + public IEnumerableVisualizerProvider( + VisualStudioExtensibility extensibility, + TraceSource traceSource) + { + } + + public virtual DebuggerVisualizerProviderConfiguration DebuggerVisualizerProviderConfiguration + { + get + { + return new DebuggerVisualizerProviderConfiguration("%IEnumerableVisualizer.DisplayName%", "System.Collections.Generic.IEnumerable`1, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089") + { + VisualizerObjectSourceType = new VisualizerObjectSourceType(typeof (IEnumerableVisualizerSource)), + Style = (VisualizerStyle) 1 + }; + } + } + + public virtual async Task CreateVisualizerAsync( + VisualizerTarget visualizerTarget, + CancellationToken cancellationToken) + { + IEnumerableViewModel viewModel = new IEnumerableViewModel(visualizerTarget.ObjectSource, visualizerTarget.OriginalVisualizedExpression, VsTaskLibraryHelper.WithPriority(ThreadHelper.JoinableTaskFactory, (VsTaskRunContext) 6)); + visualizerTarget.VisualizedExpressionChanged += new Func(((TabularDataViewModel) viewModel).VisualizerTarget_VisualizedExpressionChangedAsync); + visualizerTarget.Changed += new Func(((TabularDataViewModel) viewModel).VisualizerTarget_StateChangedAsync); + await viewModel.InitializeAsync(); + await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(new CancellationToken()); + IVsDebugger debugger = await ServiceExtensions.GetServiceAsync(AsyncServiceProvider.GlobalProvider, cancellationToken); + bool flag = (await ServiceExtensions.GetServiceAsync(AsyncServiceProvider.GlobalProvider, cancellationToken)).IsFeatureEnabled("Debugger.EnableVisualizerDataTips", true); + IEnumerableVisualizerControl visualizerControl1 = new IEnumerableVisualizerControl(); + visualizerControl1.DataContext = (object) viewModel; + visualizerControl1.Debugger = debugger; + visualizerControl1.AreDataTipsEnabled = flag; + IEnumerableVisualizerControl visualizerControl2 = visualizerControl1; + viewModel.ViewHelper = (IViewHelper) visualizerControl2; + IRemoteUserControl visualizerAsync = (IRemoteUserControl) new WpfControlWrapper((FrameworkElement) visualizerControl2); + viewModel = (IEnumerableViewModel) null; + debugger = (IVsDebugger) null; + return visualizerAsync; + } + + protected virtual Task InitializeAsync(CancellationToken cancellationToken) + { + return ((ExtensionPart) this).InitializeAsync(cancellationToken); + } +} diff --git a/IEnumerableVisualizer/IEnumerableVisualizerSource.cs b/IEnumerableVisualizer/IEnumerableVisualizerSource.cs new file mode 100644 index 0000000..783bb6a --- /dev/null +++ b/IEnumerableVisualizer/IEnumerableVisualizerSource.cs @@ -0,0 +1,69 @@ +// Decompiled with JetBrains decompiler +// Type: Microsoft.VisualStudio.Debugger.IEnumerableVisualizer.IEnumerableVisualizerSource +// Assembly: IEnumerableVisualizer.DebuggeeSide, Version=18.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a +// MVID: CFD2027C-E4DB-4399-B4DA-641D6C32082D +// Assembly location: C:\Program Files\Microsoft Visual Studio\18\Professional\Common7\IDE\CommonExtensions\Platform\Debugger\Visualizers\net2.0\IEnumerableVisualizer.DebuggeeSide.dll + +using Microsoft.VisualStudio.DebuggerVisualizers; +using System; +using System.Collections.Generic; +using System.IO; + +namespace Microsoft.VisualStudio.Debugger.IEnumerableVisualizer; + +public class IEnumerableVisualizerSource : VisualizerObjectSource +{ + private static readonly Dictionary DataObjectHandlerDictionary = new Dictionary(); + private static IEnumerableObjectHandler CurrentObjectHandler = (IEnumerableObjectHandler)null; + + public static object GetObjectAt(int tableIndex, int rowIndex, int columnIndex) + { + return CurrentObjectHandler?.GetObjectAt(tableIndex, rowIndex, columnIndex) ?? (object)null; + } + + public virtual void TransferData(object obj, Stream fromVisualizer, Stream toVisualizer) + { + IEnumerableObjectHandler dataObjectHandler; + if (DataObjectHandlerDictionary.ContainsKey(obj)) + { + dataObjectHandler = DataObjectHandlerDictionary[obj]; + dataObjectHandler.Refresh(); + } + else + { + dataObjectHandler = CreateDataObjectHandler(obj); + DataObjectHandlerDictionary[obj] = dataObjectHandler; + } + CurrentObjectHandler = dataObjectHandler; + fromVisualizer.Seek(0L, SeekOrigin.Begin); + IDeserializableObject deserializableObject = VisualizerObjectSource.GetDeserializableObject(fromVisualizer); + Type type = (Type)null; + if (!deserializableObject.IsBinaryFormat) + { + string stringPropertyValue = deserializableObject.GetJsonStringPropertyValue("TypeName"); + if (!Utils.SupportedCommands.TryGetValue(stringPropertyValue, out type)) + throw new ArgumentException($"Unknown Command: {stringPropertyValue}. Cannot send command to debuggee-side visualizer."); + } + ICommunicatorCommand communicatorCommand = (ICommunicatorCommand)deserializableObject.ToObject(type); + if (communicatorCommand.TypeName.Equals("GetTableListCommand", StringComparison.InvariantCulture)) + dataObjectHandler.InitializeDataSource(); + SendResult(communicatorCommand.HandleCommand(dataObjectHandler), toVisualizer); + } + + private IEnumerableObjectHandler CreateDataObjectHandler(object obj) + { + return new IEnumerableObjectHandler(obj); + } + + public virtual object CreateReplacementObject(object obj, Stream serializedObject) + { + throw new NotSupportedException(); + } + + public virtual void GetData(object obj, Stream dataStream) => throw new NotSupportedException(); + + private void SendResult(CommunicatorResult result, Stream toVisualizer) + { + VisualizerObjectSource.Serialize(toVisualizer, (object)result); + } +} diff --git a/Vector3Visualizer/.vsextension/string-resources.json b/NrxDebuggerVisualizerProvider/.vsextension/string-resources.json similarity index 100% rename from Vector3Visualizer/.vsextension/string-resources.json rename to NrxDebuggerVisualizerProvider/.vsextension/string-resources.json diff --git a/Vector3Visualizer/ExtensionEntrypoint.cs b/NrxDebuggerVisualizerProvider/ExtensionEntrypoint.cs similarity index 97% rename from Vector3Visualizer/ExtensionEntrypoint.cs rename to NrxDebuggerVisualizerProvider/ExtensionEntrypoint.cs index ec0ad68..9313538 100644 --- a/Vector3Visualizer/ExtensionEntrypoint.cs +++ b/NrxDebuggerVisualizerProvider/ExtensionEntrypoint.cs @@ -1,7 +1,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.VisualStudio.Extensibility; -namespace Vector3Visualizer +namespace NrxDebugVisualizer { /// /// Extension entrypoint for the VisualStudio.Extensibility extension. diff --git a/Vector3Visualizer/Vector3Visualizer.csproj b/NrxDebuggerVisualizerProvider/NrxDebugVisualizer.csproj similarity index 87% rename from Vector3Visualizer/Vector3Visualizer.csproj rename to NrxDebuggerVisualizerProvider/NrxDebugVisualizer.csproj index 6a7a5ce..8cf7a50 100644 --- a/Vector3Visualizer/Vector3Visualizer.csproj +++ b/NrxDebuggerVisualizerProvider/NrxDebugVisualizer.csproj @@ -14,7 +14,7 @@ - + @@ -25,6 +25,6 @@ - + diff --git a/Vector3Visualizer/Vector3DebuggerVisualizerProvider.cs b/NrxDebuggerVisualizerProvider/NrxDebuggerVisualizerProvider.cs similarity index 84% rename from Vector3Visualizer/Vector3DebuggerVisualizerProvider.cs rename to NrxDebuggerVisualizerProvider/NrxDebuggerVisualizerProvider.cs index 19ddd53..92c632c 100644 --- a/Vector3Visualizer/Vector3DebuggerVisualizerProvider.cs +++ b/NrxDebuggerVisualizerProvider/NrxDebuggerVisualizerProvider.cs @@ -2,19 +2,16 @@ using Microsoft.VisualStudio.Extensibility.DebuggerVisualizers; using Microsoft.VisualStudio.RpcContracts.RemoteUI; using NamedPipes; +using NrxVisualizerObjectSource; using System; -using System.Collections; -using System.Collections.Generic; using System.Numerics; -using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; -using Vector3VisualizerSource; -namespace Vector3Visualizer; +namespace NrxDebugVisualizer; [VisualStudioContribution] -internal sealed class Vector3DebuggerVisualizerProvider : DebuggerVisualizerProvider +internal sealed class NrxDebuggerVisualizerProvider : DebuggerVisualizerProvider { public override DebuggerVisualizerProviderConfiguration DebuggerVisualizerProviderConfiguration => new( @@ -25,7 +22,7 @@ internal sealed class Vector3DebuggerVisualizerProvider : DebuggerVisualizerProv new VisualizerTargetType("%NrxIEnumerableVisualizer_DisplayName%", @"System.Collections.Generic.IEnumerable`1, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"), ]) { - VisualizerObjectSourceType = new VisualizerObjectSourceType(typeof(Vector3ObjectSource)), + VisualizerObjectSourceType = new VisualizerObjectSourceType(typeof(NrxVisualizerObjectSource.NrxVisualizerObjectSource)), Style = VisualizerStyle.ToolWindow, }; private static NamedPipeClient? PipeClient { get; set; } @@ -39,8 +36,8 @@ internal sealed class Vector3DebuggerVisualizerProvider : DebuggerVisualizerProv { Vector3Model? model = await visualizerTarget.ObjectSource.RequestDataAsync(jsonSerializer: null, cancellationToken); SendToVisualizer(model); + //throw new InvalidOperationException("This is a test exception to demonstrate the visualizer. Please remove this line and implement the visualizer logic."); var control = new Vector3VisualizerUserControl(dataContext: model); return await Task.FromResult(control); - //return await Task.FromResult(new MyRemoteUserControl(model)); - } + } } diff --git a/Vector3Visualizer/Vector3VisualizerUserControl.cs b/NrxDebuggerVisualizerProvider/Vector3VisualizerUserControl.cs similarity index 70% rename from Vector3Visualizer/Vector3VisualizerUserControl.cs rename to NrxDebuggerVisualizerProvider/Vector3VisualizerUserControl.cs index 54367f3..8482e33 100644 --- a/Vector3Visualizer/Vector3VisualizerUserControl.cs +++ b/NrxDebuggerVisualizerProvider/Vector3VisualizerUserControl.cs @@ -1,7 +1,7 @@ -using Vector3VisualizerSource; -using Microsoft.VisualStudio.Extensibility.UI; +using Microsoft.VisualStudio.Extensibility.UI; +using NrxVisualizerObjectSource; -namespace Vector3Visualizer; +namespace NrxDebugVisualizer; internal sealed class Vector3VisualizerUserControl : RemoteUserControl { diff --git a/Vector3Visualizer/Vector3VisualizerUserControl.xaml b/NrxDebuggerVisualizerProvider/Vector3VisualizerUserControl.xaml similarity index 100% rename from Vector3Visualizer/Vector3VisualizerUserControl.xaml rename to NrxDebuggerVisualizerProvider/Vector3VisualizerUserControl.xaml diff --git a/Vector3VisualizerSource/Vector3ObjectSource.cs b/NrxVisualizerObjectSource/NrxVisualizerObjectSource.cs similarity index 65% rename from Vector3VisualizerSource/Vector3ObjectSource.cs rename to NrxVisualizerObjectSource/NrxVisualizerObjectSource.cs index 365c05a..f583e96 100644 --- a/Vector3VisualizerSource/Vector3ObjectSource.cs +++ b/NrxVisualizerObjectSource/NrxVisualizerObjectSource.cs @@ -1,16 +1,14 @@ using Microsoft.VisualStudio.DebuggerVisualizers; -using NamedPipes; -using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Numerics; -namespace Vector3VisualizerSource; +namespace NrxVisualizerObjectSource; -public class Vector3ObjectSource : VisualizerObjectSource +public class NrxVisualizerObjectSource : VisualizerObjectSource { - public Vector3ObjectSource() + public NrxVisualizerObjectSource() { Debug.WriteLine("new Vector3ObjectSource"); } @@ -32,4 +30,12 @@ public class Vector3ObjectSource : VisualizerObjectSource } SerializeAsJson(outgoingData, vector3Model); } + public override object CreateReplacementObject(object target, Stream incomingData) + { + return base.CreateReplacementObject(target, incomingData); + } + public override void TransferData(object target, Stream incomingData, Stream outgoingData) + { + base.TransferData(target, incomingData, outgoingData); + } } \ No newline at end of file diff --git a/Vector3VisualizerSource/Vector3VisualizerSource.csproj b/NrxVisualizerObjectSource/NrxVisualizerObjectSource.csproj similarity index 100% rename from Vector3VisualizerSource/Vector3VisualizerSource.csproj rename to NrxVisualizerObjectSource/NrxVisualizerObjectSource.csproj diff --git a/Vector3VisualizerSource/Vector3Model.cs b/NrxVisualizerObjectSource/Vector3Model.cs similarity index 86% rename from Vector3VisualizerSource/Vector3Model.cs rename to NrxVisualizerObjectSource/Vector3Model.cs index cf26549..f2d04f8 100644 --- a/Vector3VisualizerSource/Vector3Model.cs +++ b/NrxVisualizerObjectSource/Vector3Model.cs @@ -1,6 +1,6 @@ using System.Numerics; using System.Runtime.Serialization; -namespace Vector3VisualizerSource; +namespace NrxVisualizerObjectSource; [DataContract] public class Vector3Model diff --git a/Vector3Visualizer/MyRemoteUserControl.cs b/Vector3Visualizer/MyRemoteUserControl.cs deleted file mode 100644 index 6727687..0000000 --- a/Vector3Visualizer/MyRemoteUserControl.cs +++ /dev/null @@ -1,80 +0,0 @@ -using Microsoft.VisualStudio.RpcContracts.RemoteUI; -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; -using Vector3VisualizerSource; -namespace Vector3Visualizer; - -public class MyRemoteUserControl : IRemoteWpfUserControl, IRemoteProxiedUserControl, IRemoteUserControl, IDisposable, IRemoteProxiedUserControl2 -{ - public Vector3Model? Model { get; } - - public MyRemoteUserControl(Vector3Model? model) => Model = model; - private bool disposedValue; - - - protected virtual void Dispose(bool disposing) - { - if (!disposedValue) - { - if (disposing) - { - // TODO: dispose managed state (managed objects) - } - - // TODO: free unmanaged resources (unmanaged objects) and override finalizer - // TODO: set large fields to null - disposedValue = true; - } - } - - // // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources - // ~MyRemoteUserControl() - // { - // // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method - // Dispose(disposing: false); - // } - - void IDisposable.Dispose() - { - // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method - Dispose(disposing: true); - GC.SuppressFinalize(this); - } - - Task IRemoteWpfUserControl.InitializeAsync(IRemoteProxiedUserControlClient remoteUserControlClient, CancellationToken cancellationToken) - { - return Task.FromResult(new RemoteWpfUserControlDefinition()); - } - - Task IRemoteWpfUserControl.ControlLoadedAsync(CancellationToken cancellationToken) - { - return Task.CompletedTask; - } - - Task IRemoteProxiedUserControl.GetObjectAsync(ObjectId id, CancellationToken cancellationToken) - { - return Task.FromResult(false); - } - - Task IRemoteProxiedUserControl.SetObjectPropertyAsync(ObjectId id, string propertyName, MessagePackFragment value, CancellationToken cancellationToken) - { - return Task.FromResult(false); - } - - Task IRemoteProxiedUserControl.SetCollectionEntryAsync(ObjectId id, int index, MessagePackFragment value, ObjectVersion? version, CancellationToken cancellationToken) - { - return Task.FromResult(false); - } - - Task IRemoteProxiedUserControl.InvokeAsync(ObjectId id, MessagePackFragment parameter, CancellationToken cancellationToken) - { - return Task.FromResult(false); - } - - Task IRemoteProxiedUserControl2.InvokeAsync(ObjectId id, MessagePackFragment parameter, IReadOnlyDictionary context, CancellationToken cancellationToken) - { - return Task.FromResult(false); - } -} \ No newline at end of file diff --git a/Vector3VisualizerTest/Program.cs b/Vector3VisualizerTest/Program.cs index af9639c..4adc770 100644 --- a/Vector3VisualizerTest/Program.cs +++ b/Vector3VisualizerTest/Program.cs @@ -6,7 +6,7 @@ var typeName = a.GetType().AssemblyQualifiedName; var b = new Vector3(5, 6, 7); Vector3[] v3Array = [a, b]; -List v3List = v3Array.ToList(); +List v3List = [.. v3Array]; var quaternion = new Quaternion(1,2,3,4); return; \ No newline at end of file diff --git a/VisualizerExtensionExample.slnx b/VisualizerExtensionExample.slnx index cb391a5..e2c4a1d 100644 --- a/VisualizerExtensionExample.slnx +++ b/VisualizerExtensionExample.slnx @@ -7,6 +7,8 @@ - - + + + +