I'm rewriting an old application that used .Net Remoting to control a second application. The rewrite involves changing from VB to C# (so apologies for the mixed languages in this post) and targeting core rather than a framework. Core doesn't support .Net Remoting and the advise seems to be to use Anonymous Pipes. I'm not familiar with either of these so it's a bit of a baptism of fire. I've been following the example here and have got it sending a simple string from one app to the other.
Here's my server app code:-
c# Code:
public void StartAquatorXV(string exePath, int port) { mAquatorXVPipe = new AnonymousPipeServerStream(PipeDirection.Out, HandleInheritability.Inheritable); ProcessStartInfo psi = new ProcessStartInfo(exePath, $"/anonymousPipe:{mAquatorXVPipe.GetClientHandleAsString()}"); psi.UseShellExecute = false; mProcess = Process.Start(psi); mAquatorXVPipe.DisposeLocalCopyOfClientHandle(); mProcess.WaitForInputIdle(); mAquatorXVWriter = new StreamWriter(mAquatorXVPipe); mAquatorXVWriter.AutoFlush = true; mAquatorXVWriter.WriteLine("SYNC"); mAquatorXVPipe.WaitForPipeDrain(); mAquatorXVWriter.WriteLine("Test"); }
Here's the client app code:-
C# Code:
PipeStream mAquatorServerPipe; StreamReader mAquatorServerReader; public static void ListenForAquatorServer(StreamReader reader) { string input; while ((input = reader.ReadLine()) != null) { Console.WriteLine(input); } } public void SetUpClientPipe(string serverHandle) { mAquatorServerPipe = new AnonymousPipeClientStream(PipeDirection.In, serverHandle); mAquatorServerReader = new StreamReader(mAquatorServerPipe); string input; do { input = mAquatorServerReader.ReadLine(); } while (!input.StartsWith("SYNC")); Thread listener = new Thread(() => ListenForAquatorServer(mAquatorServerReader)); listener.Start(); }
Note, all the examples I could find dispose of the pipes and streams as soon as they're used which doesn't work for me, I need the client app to continue running but be able to interrupt it to send messages so I'm keeping those objects alive and will explicitly dispose of them on shutdown.
My next problem is that I'd like to be able to communicate with the client app in a strongly typed fashion. The original app used to do this to get an interface to work against:-
VB.Net Code:
' Start AquatorXV, tell it to listen on the designated port, and wait for it to be ready Dim psi As ProcessStartInfo = New ProcessStartInfo(location, $"/remoting:{port}") psi.UseShellExecute = False m_process = Process.Start(psi) m_process.WaitForInputIdle() ' Create the one remote AquatorXVInterfaces object If m_channel Is Nothing Then m_channel = New TcpChannel() ChannelServices.RegisterChannel(m_channel, True) End If Dim url As String = $"tcp://localhost:{port}/OSS.AquatorXV.Server" Dim o As Object = Activator.GetObject(Type.GetType("AquatorXVInterfaces.IServer, AquatorXVInterfaces"), url) '<<<This is the bit I need to mimic m_aquatorXV = CType(o, AquatorXVInterfaces.IServer)
So if I understand that right it uses Activator.GetObject to retrieve the client application from the uri and then cast it to a known interface to get strong typing. I'm looking for an equivalent of that which will work in Core using Anonymous Pipes. Is that possible or am I going to have to couch all the communication in untyped strings?




Reply With Quote