Search code examples
c#.netwpfpipeipc

Anonymous Pipes c# WPF


I am trying to achieve IPC with two WPF Application running on the same machine.I need to achieve something similar to Example using Winform. Can some one convert the below code to WPF/C# as you can see the delegate invoke is directly dependent on Winform Control,

if (theArgs.Length == 0)
        {
            this.Text = "Pipe Server";
            pipe = new AnonymousPipes("Server end of the pipe.", Application.ExecutablePath, "additionalArgs=your_own_command_line_args_here", delegate(String msg)
            {
                this.Invoke((MethodInvoker)delegate()
                {
                    this.lbTextIn.Items.Add(msg);
                });
            }, delegate()
            {
                // We're disconnected!
                try
                {
                    if (!this.IsDisposed)
                    {
                        this.Invoke((MethodInvoker)delegate()
                        {
                            this.lbTextIn.Items.Add("Client disconnected!");
                        });
                    }
                }
                catch (Exception) { }
            });
        }
        else
        {
            this.Text = "Pipe Client";
            pipe = new AnonymousPipes("Client end of the pipe.");
            pipe.ConnectToPipe(theArgs[0], delegate(String msg)
            {
                this.Invoke((MethodInvoker)delegate()
                {
                    lbTextIn.Items.Add(msg);
                });
            }, delegate()
            {
                // We're disconnected!
                this.Close();
            });
        }

The implementation of Wrapper class is below,

public class AnonymousPipes
{
    private String clientPath;
    private AnonymousPipeServerStream outGoingServerPipe;
    private AnonymousPipeServerStream inComingServerPipe;
    private PipeStream clientIn;
    private PipeStream clientOut;
    private Process pipeClient;
    private String incomingHandle;
    private String outgoingHandle;
    private StreamWriter ssw;
    private StreamWriter csw;
    private bool serverMode;
    private bool running;
    private CallBack callback;
    private DisconnectEvent disconnectEvent;
    private String msgError;
    private String name;

    public delegate void CallBack(String msg);
    public delegate void DisconnectEvent();
    public String ermsg;

    public bool isConnected()
    {
        return running;
    }

    public String GetPipeName()
    {
        return name;
    }

    public AnonymousPipes(String pipeName)
    {
        this.name = pipeName;
    }

    private String StartPipeServer()
    {
        serverMode = true;
        outGoingServerPipe = new AnonymousPipeServerStream(PipeDirection.Out, HandleInheritability.Inheritable);
        inComingServerPipe = new AnonymousPipeServerStream(PipeDirection.In, HandleInheritability.Inheritable);

        return outGoingServerPipe.GetClientHandleAsString() + ":::" + inComingServerPipe.GetClientHandleAsString();
    }

    public AnonymousPipes(String pipeName, String clientPath, String cmdLineArgs, CallBack callback,
        DisconnectEvent disconnectEvent)
    {
        String args;
        this.clientPath = clientPath;
        this.callback = callback;
        this.disconnectEvent = disconnectEvent;
        this.name = pipeName;
        this.running = true;

        serverMode = true;

        args = StartPipeServer() + " " + cmdLineArgs;

        try
        {
            pipeClient = new Process();
            pipeClient.StartInfo.FileName = clientPath;
            pipeClient.StartInfo.Arguments = args;
            pipeClient.StartInfo.UseShellExecute = false;
            pipeClient.Start();
        }
        catch (Exception ex)
        {
            ermsg = ex.Message;
            running = false;
            return;
        }

        outGoingServerPipe.DisposeLocalCopyOfClientHandle();
        inComingServerPipe.DisposeLocalCopyOfClientHandle();

        ssw = new StreamWriter(outGoingServerPipe);
        ssw.AutoFlush = true;
        ssw.WriteLine("SYNC");

        outGoingServerPipe.WaitForPipeDrain();

        new Thread(delegate ()
        {

            using (StreamReader isr = new StreamReader(inComingServerPipe))
            {
                String tmp;
                while (running && inComingServerPipe.IsConnected)
                {
                    tmp = isr.ReadLine();
                    if (tmp != null)
                    {
                        callback(tmp);
                    }
                }
            }

            running = false;
            disconnectEvent();

        }).Start();
    }

    public bool SendText(String msg)
    {
        return SendText(msg, ref msgError);
    }

    public bool SendText(String msg, ref String errMsg)
    {
        if (serverMode)
        {
            try
            {
                ssw.WriteLine(msg);
                outGoingServerPipe.WaitForPipeDrain();
                return true;
            }
            catch (Exception ex)
            {
                errMsg = ex.Message;
                return false;
            }
        }
        else
        {
            try
            {
                csw.WriteLine(msg);
                clientOut.WaitForPipeDrain();
            }
            catch (Exception) { }
            return true;
        }
    }

    public void ConnectToPipe(String clientHandles, CallBack callback, DisconnectEvent disconnectEvent)
    {
        String[] handles = System.Text.RegularExpressions.Regex.Split(clientHandles, ":::");
        this.incomingHandle = handles[0];
        this.outgoingHandle = handles[1];
        this.callback = callback;
        this.disconnectEvent = disconnectEvent;
        running = true;
        serverMode = false;

        new Thread(delegate ()
        {
            clientIn = new AnonymousPipeClientStream(PipeDirection.In, this.incomingHandle);
            clientOut = new AnonymousPipeClientStream(PipeDirection.Out, this.outgoingHandle);

            csw = new StreamWriter(clientOut);
            csw.AutoFlush = true;

            using (StreamReader sr = new StreamReader(clientIn))
            {
                string temp;

                do
                {
                    temp = sr.ReadLine();
                }
                while (!temp.StartsWith("SYNC") && running);

                while (running && clientIn.IsConnected)
                {
                    temp = sr.ReadLine();
                    if (temp != null) { callback(temp); }
                }

                running = false;
                disconnectEvent();
            }
        }).Start();
    }

    public void Close()
    {
        running = false;

        try
        {
            pipeClient.Close();
        }
        catch (Exception) { }

        try
        {
            outGoingServerPipe.Close();
        }
        catch (Exception) { }

        try
        {
            inComingServerPipe.Close();
        }
        catch (Exception) { }

        try
        {
            clientOut.Close();
        }
        catch (Exception) { }

        try
        {
            clientIn.Close();
        }
        catch (Exception) { }

        try
        {
            ssw.Close();
        }
        catch (Exception) { }

        try
        {
            csw.Close();
        }
        catch (Exception) { }
    }
}

Solution

  • Replace Invoke with Dispatcher.Invoke, e.g.:

    this.Dispatcher.Invoke(delegate ()
    {
        this.lbTextIn.Items.Add(msg);
    });