M
M
Michael2015-06-09 17:40:27
WPF
Michael, 2015-06-09 17:40:27

C#. How to implement interprocessor communication?

Tell me how to make it so that when the program is restarted with command line arguments, not a new window opens, but an old one, and that parameters are passed there?
Now I've made single-window through Mutex:

bool isNewInstance = false;
var mutex = new Mutex(true, Assembly.GetEntryAssembly().GetName().Name, out isNewInstance);
if (!isNewInstance)
{
    Application.Current.Shutdown();
}

But I don’t know how to properly implement data transfer to a previously launched application.

Answer the question

In order to leave comments, you need to log in

4 answer(s)
C
Cyril, 2015-06-10
@gmikhail94

I'm using this code stolen from somewhere. It controls that the application is created, works, and if another one of the same is launched, it reports about it.

using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
using System.Threading;

namespace Pressmark.Service
{
    [Serializable]
    class SingletonController : MarshalByRefObject
    {
        private const string ControllerName = "PressMarkInstance";
        private static TcpChannel _mTcpChannel = null;
        private static Mutex _mMutex = null;

        public delegate void ReceiveDelegate(string[] args);

        static private ReceiveDelegate _mReceive = null;
        static public ReceiveDelegate Receiver
        {
            get { return _mReceive; }
            set { _mReceive = value; }
        }


        public static bool IamFirst(ReceiveDelegate r)
        {
            if (IamFirst())
            {
                Receiver += r;
                return true;
            }
            else
            {
                return false;
            }
        }

        public static bool IamFirst()
        {
            _mMutex = new Mutex(false, "PressMarkInstance");

            if (_mMutex.WaitOne(1, true))
            {
                //We locked it! We are the first instance!!!    
                CreateInstanceChannel();
                return true;
            }

            //Not the first instance!!!
            _mMutex.Close();
            _mMutex = null;
            return false;
        }

        private static void CreateInstanceChannel()
        {
            _mTcpChannel = new TcpChannel(1234);
            ChannelServices.RegisterChannel(_mTcpChannel, false);
            RemotingConfiguration.RegisterWellKnownServiceType(typeof(SingletonController), ControllerName,
                WellKnownObjectMode.SingleCall);
        }

        public static void Cleanup()
        {
            if (_mMutex != null)
            {
                _mMutex.Close();
            }

            if (_mTcpChannel != null)
            {
                _mTcpChannel.StopListening(null);
            }

            _mMutex = null;
            _mTcpChannel = null;
        }

        public static void Send(string[] s)
        {
            TcpChannel channel = new TcpChannel();
            ChannelServices.RegisterChannel(channel, false);
            SingletonController ctrl = (SingletonController)Activator.GetObject(typeof(SingletonController), "tcp://localhost:1234/" + ControllerName);
            ctrl.Receive(s);
        }

        public void Receive(string[] s)
        {
            if (_mReceive != null) _mReceive(s);
        }
    }
}

Accordingly, when the program is launched (I have a WPF application), a launch event listener hangs on it. If the process already exists, we take the command line from it and kill the process.
private void App_OnStartup(object sender, StartupEventArgs e)
        {
            if (!SingletonController.IamFirst(RunCommand))
            {
                var args = e.Args;
                if (args.Length == 0) args = new[] { "newwindow" };            // если мы просто пытаемся открыть новый документ, а сервис уже запущен
                SingletonController.Send(args);
                Current.Shutdown();
                return;
            }

            RunCommand(e.Args);
            if (OpenedDocuments.Count == 0) CreateNewWindow(null);          // если ещё ни одного окна не создано, создаем его пустое.
        }

Not very transparent (I wanted to redo it for a long time, but my hands did not reach), but you can figure it out. Accordingly, you need to implement the RunCommand and CreateNewWindow methods yourself.

A
Andrey Lastochkin, 2015-06-09
@lasalas

Via WCF/NetNamedPipeBinding or COM.
But it is better not to pervert, if possible.

A
Artem Voronov, 2015-06-09
@newross

Any of these methods: Sockets, TCP, Named Pipes, MSMQ.
The running instance should have a server hanging in which you can send arguments before closing the new instance.

V
Vitaly Pukhov, 2015-06-10
@Neuroware

DDE

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question