diff --git a/.idea/.idea.VisualizerExtensionExample/.idea/.gitignore b/.idea/.idea.VisualizerExtensionExample/.idea/.gitignore new file mode 100644 index 0000000..fde4f89 --- /dev/null +++ b/.idea/.idea.VisualizerExtensionExample/.idea/.gitignore @@ -0,0 +1,15 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Rider ignored files +/projectSettingsUpdater.xml +/modules.xml +/contentModel.xml +/.idea.VisualizerExtensionExample.iml +# Editor-based HTTP Client requests +/httpRequests/ +# Ignored default folder with query files +/queries/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/.idea.VisualizerExtensionExample/.idea/encodings.xml b/.idea/.idea.VisualizerExtensionExample/.idea/encodings.xml new file mode 100644 index 0000000..df87cf9 --- /dev/null +++ b/.idea/.idea.VisualizerExtensionExample/.idea/encodings.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/.idea.VisualizerExtensionExample/.idea/indexLayout.xml b/.idea/.idea.VisualizerExtensionExample/.idea/indexLayout.xml new file mode 100644 index 0000000..7b08163 --- /dev/null +++ b/.idea/.idea.VisualizerExtensionExample/.idea/indexLayout.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/.idea.VisualizerExtensionExample/.idea/vcs.xml b/.idea/.idea.VisualizerExtensionExample/.idea/vcs.xml new file mode 100644 index 0000000..8fe5bdb --- /dev/null +++ b/.idea/.idea.VisualizerExtensionExample/.idea/vcs.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/Directory.Build.props b/Directory.Build.props new file mode 100644 index 0000000..10ae4ed --- /dev/null +++ b/Directory.Build.props @@ -0,0 +1,17 @@ + + + net10.0 + true + latest + latest-recommended + $(MSBuildThisFileDirectory)bin + $(MSBuildThisFileDirectory)packages + $(MSBuildProjectName) + $(AssemblyName) + $(BinDir)\$(Configuration)\ + $(BinDir)\obj\$(MSBuildProjectName)\ + false + en + enable + + diff --git a/Creating custom debug visualizers for Visual Studio 2022.url b/Doc/Creating custom debug visualizers for Visual Studio 2022.url similarity index 98% rename from Creating custom debug visualizers for Visual Studio 2022.url rename to Doc/Creating custom debug visualizers for Visual Studio 2022.url index ebe0892..c2a26f3 100644 --- a/Creating custom debug visualizers for Visual Studio 2022.url +++ b/Doc/Creating custom debug visualizers for Visual Studio 2022.url @@ -1,2 +1,2 @@ -[InternetShortcut] -URL=https://blog.elmah.io/creating-custom-debug-visualizers-for-visual-studio-2022/ +[InternetShortcut] +URL=https://blog.elmah.io/creating-custom-debug-visualizers-for-visual-studio-2022/ diff --git a/NamedPipes/IVisualizerKontract.cs b/NamedPipes/IVisualizerKontract.cs new file mode 100644 index 0000000..ebc5896 --- /dev/null +++ b/NamedPipes/IVisualizerKontract.cs @@ -0,0 +1,22 @@ +using System; +using System.Numerics; +using System.Threading.Tasks; +namespace NamedPipes; + +[Serializable] +public struct Frame(Vector3 translation, Quaternion orientation) +{ + public Vector3 Translation => translation; + public Quaternion Orientation => orientation; +} +[Serializable] +public class DebugObject +{ + public string? Type { get; set; } + public byte[]? Data { get; set; } +} +public interface IDebugVisualizer +{ + Task SetDebugObjectAsync(DebugObject debugObject); + Task SetMessageAsync(string message); +} diff --git a/NamedPipes/NamedPipeClient.cs b/NamedPipes/NamedPipeClient.cs new file mode 100644 index 0000000..1982486 --- /dev/null +++ b/NamedPipes/NamedPipeClient.cs @@ -0,0 +1,54 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Threading.Tasks; +using PipeMethodCalls; + +namespace NamedPipes; + +public class NamedPipeClient (string pipeName,string? serverLocation = null, string? serverName = null,Action? logger = null): IDebugVisualizer, IDisposable +{ + private bool IsConnected => PipeClient.State == PipeState.Connected; + private PipeClient PipeClient { get; }= new(new PipeSerializer(), pipeName); + private string ServerLocation { get; } = serverLocation ?? Environment.GetEnvironmentVariable("USERPROFILE") + @"\Documents\Visual Studio 2026\Visualizers\Server\NrxVisualizer\"; + private string ServerName { get; } = serverName ?? "Num.Roto.Nrx.VisualizerServer"; + private Action Logger { get;} = logger ??((m) => Trace.WriteLine(m)); + + private async Task StartServerAsync() + { + if (IsConnected) return; + PipeClient.SetLogger((m) => Trace.WriteLine(m)); + var serverAvailable = Process.GetProcessesByName(ServerName).Length > 0; + if (!serverAvailable) + { + var serverPath = ServerLocation + ServerName + ".exe"; + if (!File.Exists(serverPath)) throw new FileNotFoundException(serverPath); + var server = new Process { StartInfo = { FileName = serverPath } }; + server.Start(); + } + await PipeClient.ConnectAsync(); + } + + public async Task SetDebugObjectAsync(DebugObject debugObject) + { + await StartServerAsync(); + var result = PipeClient.InvokeAsync(server => server.SetDebugObjectAsync(debugObject)).Result; + Logger("NamedPipeClient.SetDebugObject: result = " + result); + return result; + } + + public async Task SetMessageAsync(string message) + { + await StartServerAsync(); + var result = PipeClient.InvokeAsync(server => server.SetMessageAsync(message)).Result; + Logger("NamedPipeClient.SetMessage: result = " + result); + return result; + } + + public void Dispose() + { + GC.SuppressFinalize(this); + PipeClient.Dispose(); + } +} + diff --git a/NamedPipes/NamedPipeServer.cs b/NamedPipes/NamedPipeServer.cs new file mode 100644 index 0000000..0cabc29 --- /dev/null +++ b/NamedPipes/NamedPipeServer.cs @@ -0,0 +1,52 @@ +using System; +using System.Diagnostics; +using System.Threading.Tasks; +using CommunityToolkit.Mvvm.ComponentModel; +using PipeMethodCalls; + +namespace NamedPipes; +public partial class NamedPipesServer(string pipeName,Action? logger = null) : ObservableObject,IDebugVisualizer, IDisposable +{ + public bool IsConnected => PipeServer is { State: PipeState.Connected }; + private PipeServer? PipeServer {get; set;} + private string PipeName { get; } = pipeName; + private Action Logger { get; } = logger ?? ((m) => Trace.WriteLine(m)); + + public async Task WaitForConnectionAsync() + { + if(IsConnected) return; + if (PipeServer == null || PipeServer.State == PipeState.Closed) + { + PipeServer?.Dispose(); + PipeServer = new PipeServer(new PipeSerializer(), PipeName, () => this); + PipeServer.SetLogger((m) => Trace.WriteLine(m)); + } + await PipeServer.WaitForConnectionAsync(); + } + + [ObservableProperty] + public partial DebugObject? DebugObject { get; private set; } + + public async Task SetDebugObjectAsync(DebugObject debugObject) + { + await Task.Delay(1); + DebugObject = debugObject; + Logger("Received DebugObject of type: " + DebugObject.Type); + return true; + } + + public async Task SetMessageAsync(string message) + { + await Task.Delay(1); + Logger("Received message: " + message); + return true; + } + + public void Dispose() + { + GC.SuppressFinalize(this); + PipeServer?.Dispose(); + PipeServer = null; + } +} + diff --git a/NamedPipes/NamedPipes.csproj b/NamedPipes/NamedPipes.csproj new file mode 100644 index 0000000..a4ac975 --- /dev/null +++ b/NamedPipes/NamedPipes.csproj @@ -0,0 +1,16 @@ + + + + netstandard2.0 + Library + preview + enable + + + + + + + + + diff --git a/NamedPipes/PipeSerializer.cs b/NamedPipes/PipeSerializer.cs new file mode 100644 index 0000000..609baf7 --- /dev/null +++ b/NamedPipes/PipeSerializer.cs @@ -0,0 +1,38 @@ +using System; +using MessagePack; +using PipeMethodCalls; + +namespace NamedPipes +{ + public class PipeSerializer : IPipeSerializer + { + public object? Deserialize(byte[] data, Type type) + { + if (data.Length == 0) return null; + //Log.Trace("PipeSerializer.Deserialize: type = " + type + " , data.length = " + data.Length); + var obj = MessagePackSerializer.Deserialize(type, data, MessagePack.Resolvers.ContractlessStandardResolver.Options); + //if (obj is DebugObject debugObject) + //{ + // var length = debugObject.Data?.Length ?? 0; + // var debugObjectType = debugObject.Type ?? "null"; + // Log.Trace("PipeSerializer.Deserialize: debugObject.Type = " + debugObjectType + " , debugObject.Data.Length = " + length); + //} + return obj; + } + + public byte[] Serialize(object o) + { + if (o.GetType().FullName == "System.Threading.Tasks.VoidTaskResult") return []; + //if (o is DebugObject debugObject) + //{ + // var length = debugObject.Data?.Length ?? 0; + // Log.Trace("PipeSerializer.Deserialize: debugObject.Type = " + debugObject.Type + " , debugObject.Data.Length = " + length); + //} + + var bytearray = MessagePackSerializer.Serialize(o.GetType(), o, MessagePack.Resolvers.ContractlessStandardResolver.Options); + //var xxx = Deserialize(bytearray, o.GetType()); + //Log.Trace("PipeSerializer.Serialize: type = " + o.GetType() + " , bytearray.length = " + bytearray.Length); + return bytearray; + } + } +} diff --git a/TestClient/Program.cs b/TestClient/Program.cs new file mode 100644 index 0000000..12794ad --- /dev/null +++ b/TestClient/Program.cs @@ -0,0 +1,12 @@ +using System.Text; +using NamedPipes; +var count = 0; +var message = "Hello World!".ToCharArray(); +while (true) +{ + var pipeClient = new NamedPipeClient("testPipe",@".\","TestServer"); + Thread.Sleep(100); + pipeClient.SetMessageAsync($"Hello from TestClient " + count++).GetAwaiter().GetResult(); + pipeClient.SetDebugObjectAsync(new DebugObject{Type = typeof(string).FullName,Data = Encoding.GetEncoding("UTF-8").GetBytes(message)}).GetAwaiter().GetResult(); + pipeClient.Dispose(); +} diff --git a/TestClient/TestClient.csproj b/TestClient/TestClient.csproj new file mode 100644 index 0000000..03352d9 --- /dev/null +++ b/TestClient/TestClient.csproj @@ -0,0 +1,14 @@ + + + + Exe + net10.0 + enable + enable + + + + + + + diff --git a/TestServer/Program.cs b/TestServer/Program.cs new file mode 100644 index 0000000..5dcb78e --- /dev/null +++ b/TestServer/Program.cs @@ -0,0 +1,7 @@ +using System; +using System.Threading; + +var pipeServer = new NamedPipes.NamedPipesServer("testPipe",Console.WriteLine); +pipeServer.WaitForConnectionAsync().GetAwaiter().GetResult(); +while (pipeServer.IsConnected) Thread.Sleep(100); + diff --git a/Vector3Visualizer/DebugVisualizer/DebugVisualizer.csproj b/TestServer/TestServer.csproj similarity index 77% rename from Vector3Visualizer/DebugVisualizer/DebugVisualizer.csproj rename to TestServer/TestServer.csproj index be29180..620d94f 100644 --- a/Vector3Visualizer/DebugVisualizer/DebugVisualizer.csproj +++ b/TestServer/TestServer.csproj @@ -3,8 +3,6 @@ Exe net10.0 - enable - enable diff --git a/Vector3Visualizer/DebugVisualizer/Program.cs b/Vector3Visualizer/DebugVisualizer/Program.cs deleted file mode 100644 index 1dd89cf..0000000 --- a/Vector3Visualizer/DebugVisualizer/Program.cs +++ /dev/null @@ -1,2 +0,0 @@ -var pipeServer = new NamedPipes.Receiver(); -pipeServer.Start(); diff --git a/Vector3Visualizer/Directory.Build.props b/Vector3Visualizer/Directory.Build.props deleted file mode 100644 index 9a6f2ef..0000000 --- a/Vector3Visualizer/Directory.Build.props +++ /dev/null @@ -1,14 +0,0 @@ - - - Debug - $([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)')) - $(RepoRootPath)obj\$(MSBuildProjectName)\ - $(RepoRootPath)bin\$(MSBuildProjectName)\ - false - false - true - false - false - latest - - diff --git a/Vector3Visualizer/Vector3Visualizer/ExtensionEntrypoint.cs b/Vector3Visualizer/ExtensionEntrypoint.cs similarity index 92% rename from Vector3Visualizer/Vector3Visualizer/ExtensionEntrypoint.cs rename to Vector3Visualizer/ExtensionEntrypoint.cs index 6beb06c..ec0ad68 100644 --- a/Vector3Visualizer/Vector3Visualizer/ExtensionEntrypoint.cs +++ b/Vector3Visualizer/ExtensionEntrypoint.cs @@ -1,31 +1,31 @@ -using Microsoft.Extensions.DependencyInjection; -using Microsoft.VisualStudio.Extensibility; - -namespace Vector3Visualizer -{ - /// - /// Extension entrypoint for the VisualStudio.Extensibility extension. - /// - [VisualStudioContribution] - internal class ExtensionEntrypoint : Extension - { - /// - public override ExtensionConfiguration ExtensionConfiguration => new() - { - Metadata = new( - id: "Vector3Visualizer.3c0400c3-acec-4b09-b561-c11fac7b10a7", - version: this.ExtensionAssemblyVersion, - publisherName: "Nrx Visualizer", - displayName: "Vector3Visualizer", - description: "Visualizer for MailAdress"), - }; - - /// - protected override void InitializeServices(IServiceCollection serviceCollection) - { - base.InitializeServices(serviceCollection); - - // You can configure dependency injection here by adding services to the serviceCollection. - } - } -} +using Microsoft.Extensions.DependencyInjection; +using Microsoft.VisualStudio.Extensibility; + +namespace Vector3Visualizer +{ + /// + /// Extension entrypoint for the VisualStudio.Extensibility extension. + /// + [VisualStudioContribution] + internal sealed class ExtensionEntrypoint : Extension + { + /// + public override ExtensionConfiguration ExtensionConfiguration => new() + { + Metadata = new( + id: "Vector3Visualizer.3c0400c3-acec-4b09-b561-c11fac7b10a7", + version: this.ExtensionAssemblyVersion, + publisherName: "Nrx Visualizer", + displayName: "Vector3Visualizer", + description: "Visualizer for MailAdress"), + }; + + /// + protected override void InitializeServices(IServiceCollection serviceCollection) + { + base.InitializeServices(serviceCollection); + + // You can configure dependency injection here by adding services to the serviceCollection. + } + } +} diff --git a/Vector3Visualizer/Vector3Visualizer/MyRemoteUserControl.cs b/Vector3Visualizer/MyRemoteUserControl.cs similarity index 97% rename from Vector3Visualizer/Vector3Visualizer/MyRemoteUserControl.cs rename to Vector3Visualizer/MyRemoteUserControl.cs index 689347b..6727687 100644 --- a/Vector3Visualizer/Vector3Visualizer/MyRemoteUserControl.cs +++ b/Vector3Visualizer/MyRemoteUserControl.cs @@ -1,80 +1,80 @@ -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); - } +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/Vector3Visualizer/NamedPipes/NamedPipes.csproj b/Vector3Visualizer/NamedPipes/NamedPipes.csproj deleted file mode 100644 index dbdcea4..0000000 --- a/Vector3Visualizer/NamedPipes/NamedPipes.csproj +++ /dev/null @@ -1,7 +0,0 @@ - - - - netstandard2.0 - - - diff --git a/Vector3Visualizer/NamedPipes/ReadFileToStream.cs b/Vector3Visualizer/NamedPipes/ReadFileToStream.cs deleted file mode 100644 index d43f9a0..0000000 --- a/Vector3Visualizer/NamedPipes/ReadFileToStream.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System.IO; - -namespace NamedPipes -{ - // Contains the method executed in the context of the impersonated user - public class ReadFileToStream - { - private readonly string fn; - private readonly StreamString ss; - - public ReadFileToStream(StreamString str, string filename) - { - fn = filename; - ss = str; - } - - public void Start() - { - string contents = File.ReadAllText(fn); - ss.WriteString(contents); - } - } -} diff --git a/Vector3Visualizer/NamedPipes/Receiver.cs b/Vector3Visualizer/NamedPipes/Receiver.cs deleted file mode 100644 index 6b16d99..0000000 --- a/Vector3Visualizer/NamedPipes/Receiver.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System; -using System.IO; -using System.IO.Pipes; -using System.Text; -using System.Threading; - -namespace NamedPipes -{ - - public class Receiver - { - public readonly static string PipeName = "testpipe"; - public Receiver() - { - } - ~Receiver() - { - } - public void Start() - { - while (true) - { - var pipeServer = new NamedPipeServerStream(PipeName, PipeDirection.InOut); - int threadId = Thread.CurrentThread.ManagedThreadId; - - // Wait for a client to connect - pipeServer.WaitForConnection(); - Console.WriteLine($"Client connected on thread[{threadId}]."); - try - { - // Read the request from the client. Once the client has - // written to the pipe its security token will be available. - - StreamString stream = new StreamString(pipeServer); - - // Verify our identity to the connected client using a - // string that the client anticipates. - - stream.WriteString("I am the one true server!"); - string message = stream.ReadString(); - Console.WriteLine($"Received: {message}"); - - - // Read in the contents of the file while impersonating the client. - //ReadFileToStream fileReader = new ReadFileToStream(ss, filename); - - // Display the name of the user we are impersonating. - //Console.WriteLine($"Reading file: {filename} on thread[{threadId}] as user: {pipeServer.GetImpersonationUserName()}."); - //pipeServer.RunAsClient(fileReader.Start); - } - // Catch the IOException that is raised if the pipe is broken - // or disconnected. - catch (IOException e) - { - Console.WriteLine($"ERROR: {e.Message}"); - } - finally - { - pipeServer.Dispose(); - } - } - - } - } -} diff --git a/Vector3Visualizer/NamedPipes/Sender.cs b/Vector3Visualizer/NamedPipes/Sender.cs deleted file mode 100644 index aa13840..0000000 --- a/Vector3Visualizer/NamedPipes/Sender.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System; -using System.IO.Pipes; -using System.Security.Principal; -using System.Threading; - - -namespace NamedPipes -{ - public class Sender - { - public Sender() { } - public void SendMessage(string message) - { - var pipeClient = new NamedPipeClientStream(".", Receiver.PipeName, PipeDirection.InOut, PipeOptions.None, TokenImpersonationLevel.Impersonation); - Console.WriteLine("Connecting to server...\n"); - pipeClient.Connect(5000); - Console.WriteLine("Connected.\n"); - - var ss = new StreamString(pipeClient); - // Validate the server's signature string. - if (ss.ReadString() == "I am the one true server!") - { - // The client security token is sent with the first write. - // Send the name of the file whose contents are returned - // by the server. - ss.WriteString(message); - - // Print the file to the screen. - Console.Write(ss.ReadString()); - } - else - { - Console.WriteLine("Server could not be verified."); - } - pipeClient.Dispose(); - // Give the client process some time to display results before exiting. - Thread.Sleep(100); - } - } -} \ No newline at end of file diff --git a/Vector3Visualizer/NamedPipes/StreamString.cs b/Vector3Visualizer/NamedPipes/StreamString.cs deleted file mode 100644 index 6a5cea2..0000000 --- a/Vector3Visualizer/NamedPipes/StreamString.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; -using System.IO; -using System.Text; - - -namespace NamedPipes -{ - // Defines the data protocol for reading and writing strings on our stream. - public class StreamString - { - private readonly Stream ioStream; - private readonly UnicodeEncoding streamEncoding; - - public StreamString(Stream ioStream) - { - this.ioStream = ioStream; - streamEncoding = new UnicodeEncoding(); - } - - public string ReadString() - { - int len; - len = ioStream.ReadByte() * 256; - len += ioStream.ReadByte(); - var inBuffer = new byte[len]; - ioStream.Read(inBuffer, 0, len); - - return streamEncoding.GetString(inBuffer); - } - - public int WriteString(string outString) - { - byte[] outBuffer = streamEncoding.GetBytes(outString); - int len = outBuffer.Length; - if (len > UInt16.MaxValue) - { - len = (int)UInt16.MaxValue; - } - ioStream.WriteByte((byte)(len / 256)); - ioStream.WriteByte((byte)(len & 255)); - ioStream.Write(outBuffer, 0, len); - ioStream.Flush(); - - return outBuffer.Length + 2; - } - } -} diff --git a/Vector3Visualizer/Vector3Visualizer/Vector3DebuggerVisualizerProvider.cs b/Vector3Visualizer/Vector3DebuggerVisualizerProvider.cs similarity index 95% rename from Vector3Visualizer/Vector3Visualizer/Vector3DebuggerVisualizerProvider.cs rename to Vector3Visualizer/Vector3DebuggerVisualizerProvider.cs index e4d11fe..285f465 100644 --- a/Vector3Visualizer/Vector3Visualizer/Vector3DebuggerVisualizerProvider.cs +++ b/Vector3Visualizer/Vector3DebuggerVisualizerProvider.cs @@ -9,7 +9,7 @@ using Vector3VisualizerSource; namespace Vector3Visualizer; [VisualStudioContribution] -internal class Vector3DebuggerVisualizerProvider : DebuggerVisualizerProvider +internal sealed class Vector3DebuggerVisualizerProvider : DebuggerVisualizerProvider { [System.Diagnostics.CodeAnalysis.SuppressMessage("ConstantExpressionEvaluator", "CEE0027:String not localized", Justification = "")] public override DebuggerVisualizerProviderConfiguration DebuggerVisualizerProviderConfiguration => new( diff --git a/Vector3Visualizer/Vector3Visualizer/Vector3Visualizer.csproj b/Vector3Visualizer/Vector3Visualizer.csproj similarity index 67% rename from Vector3Visualizer/Vector3Visualizer/Vector3Visualizer.csproj rename to Vector3Visualizer/Vector3Visualizer.csproj index f1e1206..8c363a7 100644 --- a/Vector3Visualizer/Vector3Visualizer/Vector3Visualizer.csproj +++ b/Vector3Visualizer/Vector3Visualizer.csproj @@ -14,8 +14,8 @@ - - + + diff --git a/Vector3Visualizer/Vector3VisualizerSource/Vector3ObjectSource.cs b/Vector3Visualizer/Vector3VisualizerSource/Vector3ObjectSource.cs deleted file mode 100644 index 75e9210..0000000 --- a/Vector3Visualizer/Vector3VisualizerSource/Vector3ObjectSource.cs +++ /dev/null @@ -1,42 +0,0 @@ -using Microsoft.VisualStudio.DebuggerVisualizers; -using NamedPipes; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Numerics; - -namespace Vector3VisualizerSource; - -public class Vector3ObjectSource : VisualizerObjectSource -{ - public static void Send(Vector3Model vector3Model) - { - var pipeClient = new Sender(); - - pipeClient.SendMessage($"Hello from {nameof(Vector3ObjectSource)}"); - } - public Vector3ObjectSource():base() - { - Debug.WriteLine("new Vector3ObjectSource"); - } - public override void GetData(object target, Stream outgoingData) - { - Vector3Model vector3Model = new(); - if (target is Vector3 vector3) - { - vector3Model.Vector3 = vector3.ToString(); - } - if (target is IEnumerable vector3List) - { - vector3Model.Vector3 = vector3List.Last().ToString(); - } - - if (target is Quaternion quaternion) - { - vector3Model.Quaternion = quaternion.ToString(); - } - Send(vector3Model); - SerializeAsJson(outgoingData, vector3Model); - } -} \ No newline at end of file diff --git a/Vector3Visualizer/Vector3VisualizerTest/Program.cs b/Vector3Visualizer/Vector3VisualizerTest/Program.cs deleted file mode 100644 index c7bb497..0000000 --- a/Vector3Visualizer/Vector3VisualizerTest/Program.cs +++ /dev/null @@ -1,12 +0,0 @@ - -using System.Numerics; - -var a = new Vector3(1,2,3); -var typeName = a.GetType().AssemblyQualifiedName; - -var b = new Vector3(5, 6, 7); -Vector3[] v3Array = [a, b]; -List v3List = v3Array.ToList(); - -var quaternion = new Quaternion(1,2,3,4); -return; \ No newline at end of file diff --git a/Vector3Visualizer/Vector3VisualizerTest/Test.csproj b/Vector3Visualizer/Vector3VisualizerTest/Test.csproj deleted file mode 100644 index 206b89a..0000000 --- a/Vector3Visualizer/Vector3VisualizerTest/Test.csproj +++ /dev/null @@ -1,10 +0,0 @@ - - - - Exe - net8.0 - enable - enable - - - diff --git a/Vector3Visualizer/Vector3VisualizerTest/Test.slnx b/Vector3Visualizer/Vector3VisualizerTest/Test.slnx deleted file mode 100644 index 33b33b1..0000000 --- a/Vector3Visualizer/Vector3VisualizerTest/Test.slnx +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/Vector3Visualizer/Vector3Visualizer/Vector3VisualizerUserControl.cs b/Vector3Visualizer/Vector3VisualizerUserControl.cs similarity index 80% rename from Vector3Visualizer/Vector3Visualizer/Vector3VisualizerUserControl.cs rename to Vector3Visualizer/Vector3VisualizerUserControl.cs index 2535e6b..54367f3 100644 --- a/Vector3Visualizer/Vector3Visualizer/Vector3VisualizerUserControl.cs +++ b/Vector3Visualizer/Vector3VisualizerUserControl.cs @@ -1,14 +1,14 @@ -using Vector3VisualizerSource; -using Microsoft.VisualStudio.Extensibility.UI; - -namespace Vector3Visualizer; - -internal class Vector3VisualizerUserControl : RemoteUserControl -{ - public Vector3VisualizerUserControl(Vector3Model? dataContext) : base(dataContext) - { - Vector3Model = (Vector3Model?)DataContext; - } - - public Vector3Model? Vector3Model { get; } +using Vector3VisualizerSource; +using Microsoft.VisualStudio.Extensibility.UI; + +namespace Vector3Visualizer; + +internal sealed class Vector3VisualizerUserControl : RemoteUserControl +{ + public Vector3VisualizerUserControl(Vector3Model? dataContext) : base(dataContext) + { + Vector3Model = (Vector3Model?)DataContext; + } + + public Vector3Model? Vector3Model { get; } } \ No newline at end of file diff --git a/Vector3Visualizer/Vector3Visualizer/Vector3VisualizerUserControl.xaml b/Vector3Visualizer/Vector3VisualizerUserControl.xaml similarity index 96% rename from Vector3Visualizer/Vector3Visualizer/Vector3VisualizerUserControl.xaml rename to Vector3Visualizer/Vector3VisualizerUserControl.xaml index f1ca51c..35f36db 100644 --- a/Vector3Visualizer/Vector3Visualizer/Vector3VisualizerUserControl.xaml +++ b/Vector3Visualizer/Vector3VisualizerUserControl.xaml @@ -1,16 +1,16 @@ - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Vector3Visualizer/Vector3VisualizerSource/Vector3Model.cs b/Vector3VisualizerSource/Vector3Model.cs similarity index 95% rename from Vector3Visualizer/Vector3VisualizerSource/Vector3Model.cs rename to Vector3VisualizerSource/Vector3Model.cs index 8f70829..624a1fb 100644 --- a/Vector3Visualizer/Vector3VisualizerSource/Vector3Model.cs +++ b/Vector3VisualizerSource/Vector3Model.cs @@ -1,12 +1,12 @@ -using System.Runtime.Serialization; -namespace Vector3VisualizerSource; - -[DataContract] -public class Vector3Model -{ - [DataMember] - public string Vector3 { get; set; } = "Null"; - [DataMember] - public string Quaternion { get; set; } = "Null"; -} - +using System.Runtime.Serialization; +namespace Vector3VisualizerSource; + +[DataContract] +public class Vector3Model +{ + [DataMember] + public string Vector3 { get; set; } = "Null"; + [DataMember] + public string Quaternion { get; set; } = "Null"; +} + diff --git a/Vector3VisualizerSource/Vector3ObjectSource.cs b/Vector3VisualizerSource/Vector3ObjectSource.cs new file mode 100644 index 0000000..d8313a7 --- /dev/null +++ b/Vector3VisualizerSource/Vector3ObjectSource.cs @@ -0,0 +1,42 @@ +using Microsoft.VisualStudio.DebuggerVisualizers; +using NamedPipes; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Numerics; + +namespace Vector3VisualizerSource; + +public class Vector3ObjectSource : VisualizerObjectSource +{ + private static NamedPipeClient? PipeClient { get; set; } + private static void Send(Vector3Model vector3Model) + { + PipeClient ??= new NamedPipeClient("testPipe"); + PipeClient.SetMessageAsync($"Hello from {nameof(Vector3ObjectSource)}").GetAwaiter().GetResult(); + } + public Vector3ObjectSource() + { + Debug.WriteLine("new Vector3ObjectSource"); + } + public override void GetData(object target, Stream outgoingData) + { + Vector3Model vector3Model = new(); + switch (target) + { + case Vector3 vector3: + vector3Model.Vector3 = vector3.ToString(); + break; + case IEnumerable vector3List: + vector3Model.Vector3 = vector3List.Last().ToString(); + break; + case Quaternion quaternion: + vector3Model.Quaternion = quaternion.ToString(); + break; + } + + Send(vector3Model); + SerializeAsJson(outgoingData, vector3Model); + } +} \ No newline at end of file diff --git a/Vector3Visualizer/Vector3VisualizerSource/Vector3VisualizerSource.csproj b/Vector3VisualizerSource/Vector3VisualizerSource.csproj similarity index 100% rename from Vector3Visualizer/Vector3VisualizerSource/Vector3VisualizerSource.csproj rename to Vector3VisualizerSource/Vector3VisualizerSource.csproj diff --git a/Vector3Visualizer/Vecor3Visualizer.slnx b/VisualizerExtensionExample.slnx similarity index 64% rename from Vector3Visualizer/Vecor3Visualizer.slnx rename to VisualizerExtensionExample.slnx index 795fcd9..cb77de7 100644 --- a/Vector3Visualizer/Vecor3Visualizer.slnx +++ b/VisualizerExtensionExample.slnx @@ -1,9 +1,9 @@ - - - - - - - - - + + + + + + + + +