0

I have an EXE that I've created called logger which is a simple WinForms application. It has a richtextbox and that's pretty much it.

I then also have a suite of other applications. What I want to be able to do with these apps is to be able to get them to write output to the logger.exe I have full control over the code of all applications.

I understand I could do a process.start and specify arguments but I want these apps to be able to write to the richtextbox at will based on the methods being called within them.

I was hoping I could create an api in the logger.exe that would expose a method for appending the richtextbox.

Does anyone have any tips on how I might achieve this?

EDIT: This is what I have so far:

namespace ScreenLog
{
  [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant, InstanceContextMode = InstanceContextMode.Single)]
  public partial class Logger : Form, IFromClientToServerMessages
  {
      public Logger()
      {
          InitializeComponent();
      }

      public void DisplayTextOnServerAsFromThisClient(string text)
      {    
          LogConsole.AppendText(Environment.NewLine + text);
      }
  }
  [ServiceContract(SessionMode = SessionMode.Allowed)]
  public interface IFromClientToServerMessages
  {
      [OperationContract(IsOneWay = false)]
      void DisplayTextOnServerAsFromThisClient(string message);
  }
}
2
  • I always used a message passing library for stuff like this, open-mpi.org its very reliable and not too complex. If you just want a quick and easy solution you might want to just have a text file somewhere saved where one program writes into it and the other one checks every second or so if there is something in it and copys that Commented Nov 10, 2014 at 10:42
  • Hi Vajura, thanks for the suggestion I didn't think of doing the text file thing, that might work if I poll it every few ms. Probably not the most efficient but hey. I'll take a look at the messaging library. Commented Nov 10, 2014 at 10:49

1 Answer 1

2

As you might have already guessed you would need any of IPC(Inter Process Communication) mechanism to send messages between different processes(Applications). WCF is one of the option, You could implement a simple WCF service module which uses net.pipe binding. This service can be hosted in managed application. In your case this service can be hosted in your logger application.

Note: If you want to host a WCF application in a managed application, Particular managed application(Logger) should have admin privilege.

Implementation of Logger Form

partial class declaration

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant, InstanceContextMode = InstanceContextMode.Single)]
public partial class Logger: Form, IFromClientToServerMessages

Introduce Interface for communication

This interface should be added to a assembly which is accessible by both Logger application and any other application which sends message to logger.

[ServiceContract(SessionMode = SessionMode.Allowed)]
   public interface IFromClientToServerMessages
   {
       [OperationContract(IsOneWay = false)]
       void DisplayTextOnServerAsFromThisClient(string message);
   }

Implementing Interface

Add the following method implementation to your Logger form

public void DisplayTextOnServerAsFromThisClient(string text)
{
  //Add proper logic to set value to rich text box control.    
  richtextbox = text;
}

Hosting the WCF service in logger application

Invoke HostTheNetPipeService() within the constructor of Logger Form

private void HostTheNetPipeService()
{
  serverHost = new ServiceHost(this);
  serverHost.AddServiceEndpoint((typeof(IFromClientToServerMessages)), new NetNamedPipeBinding(), "net.pipe://127.0.0.1/Server");
  serverHost.Open();
}

Call the service from other applications to send message/text

private void SendMessageToLogger()
{
    using (ChannelFactory<IFromClientToServerMessages> factory = new ChannelFactory<IFromClientToServerMessages>(new NetNamedPipeBinding(), new EndpointAddress("net.pipe://localhost/Server")))
    {
       IFromClientToServerMessages clientToServerChannel = factory.CreateChannel();
                try
                {
                    clientToServerChannel.DisplayTextOnServerAsFromThisClient("Message to be displayed");
                }
                catch (Exception ex)
                {                   
                }
                finally
                {
                    CloseChannel((ICommunicationObject)clientToServerChannel);
                }
            }
        }

Closing the communication channel

private void CloseChannel(ICommunicationObject channel)
{
  try
  {
     channel.Close();
  }
  catch (Exception ex)
  {

  }
  finally
  {
     channel.Abort();
  }
}
Sign up to request clarification or add additional context in comments.

5 Comments

I'll give this a shot thanks for explaining it, Kurubaran, this would be my preferred method if I can get it to work. The user this runs under does have admin so that shouldn't be an issue.
@Jonkers Let me know if you come across any issue, I can help you out.
I'm not sure I get the whole part about how to hosting the WCF in my application. Im guessing when the WinForms app launches I want it to create a host under net.pipe://localhost/Server
@Jonkers Sorry missed that part, Added method to host the service into Logger form.
Ah it looks like its working now I think I just need to add some code to wait until the app is full started. I just did a test and it did actually output the text to the window! Its looking good so far, Thanks so much for helping!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.