简体   繁体   中英

What is the easiest way for two separate C# .Net apps to talk to each other on the same computer

I would like my two applications to be able to send strings to each other and depending on the string " do something<\/em> ".

There are several mechanisms for this - probably the easiest to use is named pipes. I have not used it, but I understand the Windows Communication Foundation (WCF) is easy to use as well.

There are a bunch of articles on CodePoject about WCF :)

An advantage of using WCF is that it would let easily move your processes to different systems. (should that be practical for your scenario).

一种方法是使用.NET Remoting IpcChannel类在同一台机器上的不同进程之间进行通信。

To what extent do they really, really need to be different applications?

Could you have two separate projects which you launch from a third project, on different threads?

static void Main()
{
    new Thread(Project1.Program.Main).Start();
    new Thread(Project2.Program.Main).Start();
}

At that point you could use static variables (in a fourth project, referenced by both of the first two projects) to set up a shared communication channel between the two of them. You could have two producer/consumer queues (look half way down the page), one for each direction, for example. (You'd want to make the queue just use strings, or make a generic one and then use ProducerConsumer<string> for example. If you can use the .NET 4.0 beta, you could use a BlockingCollection<string> .)

That would be extremely hacky - and without the isolation of even different AppDomain s you could see some interesting effects in terms of static variables accessed from both "applications" but that's effectively what you're trying to achieve.

You should in no way take this implementation idea anywhere near production code - but for the situation you're describing, it sounds like "simple to implement" is the most important point.

Just in case the project hierarchy doesn't make sense, here's a graphical representation

        Launcher
       /        \
      /          \
   App 1       App 2
      \          /
       \        /
        \      /
      Shared stuff

(To make it even simpler you could actually just use one project, and make its main method launch two different threads using methods within the same project. The idea of it being two applications is all smoke and mirrors by this point anyway. On the other hand, it might make it easier to think about the different apps by separating the projects.)

WCF is a good way to good, even if once you start delving into it then it can become complicated.

You'd define a simple contract that accepts a string, then implement the contract in each application, doing whatever you want when the string arrives. Within an application you can self host the service, meaning the application itself hosts the service - so you don't need IIS. Host them on known ports, add a web service reference in each solution and away you go.

There are a lot of very easy ways for apps to communicate in very simplistic ways. I think some of the easiest would be the following

  • Named Pipe
  • Local Sockets
  • Shared Memory

The easiest approach I can think of is creating a file that the other process checks for.

A more "advanced" and "sensible" way would be to use sockets and localhost.

And if I would want to actually implement it I would try and learn about proper IPC.

The best and most interesting way to do this is the Named Pipe that I did and I was completely satisfied

  class Client
{
    static void Main(string[] args)
    {
        using (var pipe = new NamedPipeClientStream("localhost", "FtechPipe", PipeDirection.InOut))
        {
            if (ServerCheck())
                pipe.Connect(5000);
            pipe.ReadMode = PipeTransmissionMode.Message;
            do
            {
                try
                {
                    Console.Write("Type Something> ");
                    var input = Console.ReadLine();
                    if (String.IsNullOrEmpty(input)) continue;
                    byte[] bytes = Encoding.Default.GetBytes(input);
                    pipe.Write(bytes, 0, bytes.Length);
                    var result = ReadMessage(pipe);
                    string me = Encoding.UTF8.GetString(result);
                    Console.WriteLine(me);
                    Console.WriteLine();
                }
                catch (IOException pipedEx)
                {
                    try
                    {
                        //inja bayad motmaeen beshi agent up hastesh 
                        //age ip nabood upesh kon 
                        //dobanre connect sho
                        pipe.Connect(5000);
                    }
                    catch (TimeoutException pipeTimeoutEx)
                    {

                    }

                }
            } while (true);
        }
    }

    private static bool ServerCheck()
    {
        var allProcesses = Process.GetProcesses();
        if (string.IsNullOrEmpty(allProcesses.Where(a => a.ProcessName == "Client.exe").FirstOrDefault()?.ToString()))
        {
            System.Diagnostics.Process.Start(@"C:\Client.exe");
            return true;
        }
        else
            return false;
    }
    private static byte[] ReadMessage(PipeStream pipe)
    {
        byte[] buffer = new byte[1024];
        using (var ms = new MemoryStream())
        {
            do
            {
                var readBytes = pipe.Read(buffer, 0, buffer.Length);
                ms.Write(buffer, 0, readBytes);
            }
            while (!pipe.IsMessageComplete);

            return ms.ToArray();
        }
    }
}


 class Server
{
    static void Main(string[] args)
    {

        using (var pipe = new NamedPipeServerStream(
            "FtechPipe", 
            PipeDirection.InOut, 
            NamedPipeServerStream.MaxAllowedServerInstances, 
            PipeTransmissionMode.Message))
        {
            Console.WriteLine("[*] Waiting for client connection...");
            pipe.WaitForConnection();
            Console.WriteLine("[*] Client connected.");
            while (true)
            {
                var messageBytes = ReadMessage(pipe);
                var line = Encoding.UTF8.GetString(messageBytes);
                Console.WriteLine("[*] Received: {0}", line);
                try
                {  
                    var response = Encoding.UTF8.GetBytes("Hello ");
                    pipe.Write(response, 0, response.Length);
                }
                catch (Exception ex)
                {
                    //Console.WriteLine(ex);
                    pipe.Disconnect();
                    Console.WriteLine("Disaconnected");
                    Console.WriteLine("[*] Waiting for client connection...");

                    //vaghti ke pipe Broke mishe yani ertebat ghat shode va bayad agent motmaeen beshe terminal up hast ya kheir
                    pipe.WaitForConnection();
                    Console.WriteLine("[*] Client connected.");
                }
            }
        }
    }

    private static byte[] ReadMessage(PipeStream pipe)
    {
        byte[] buffer = new byte[1024];
        using (var ms = new MemoryStream())
        {
            do
            {
                var readBytes = pipe.Read(buffer, 0, buffer.Length);
                ms.Write(buffer, 0, readBytes);
            }
            while (!pipe.IsMessageComplete);

            return ms.ToArray();
        }
    }
}

我会选择插座。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM