@gmikhail94

C#. Как реализовать межпроцессорное взаимодействие?

Подскажите, как сделать чтобы при повторном запуске программы с аргументами командной строки открывалось не новое окно, а старое, и чтобы туда передавались параметры?
Сейчас я сделал однооконность через Mutex:
bool isNewInstance = false;
var mutex = new Mutex(true, Assembly.GetEntryAssembly().GetName().Name, out isNewInstance);
if (!isNewInstance)
{
    Application.Current.Shutdown();
}

Но не знаю как правильно реализовать передачу данных в ранее запущенное приложение.
  • Вопрос задан
  • 2092 просмотра
Решения вопроса 1
teoadal
@teoadal
.NET + AS3
Я использую вот такой украденный где-то код. Он контролирует, что приложение создано, работает, а если запускается ещё одно такое же - сообщает об этом.
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);
        }
    }
}


Соответственно, программа, когда запускаемся (у меня WPF приложение), на нем висит слушатель события запуска. Если процесс уже существует - забираем из него коммандную строку и убиваем процесс.

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);          // если ещё ни одного окна не создано, создаем его пустое.
        }


Не очень прозрачно (давно хотел переделать, но руки не доходили), но разобраться можно. Соответственно, RunCommand и CreateNewWindow методы вам нужно реализовать самому.
Ответ написан
Пригласить эксперта
Ответы на вопрос 3
lasalas
@lasalas
.NET Architect
Через WCF/NetNamedPipeBinding или COM.
Но лучше не извращаться, если есть возможность.
Ответ написан
Комментировать
newross
@newross
Product owner
Любым из этих способов: Sockets, TCP, Named Pipes, MSMQ.
В запущенном экземпляре должен висеть сервер, в которой сможете отправить аргументы перед закрытием нового экземпляра.
Ответ написан
Комментировать
Neuroware
@Neuroware
Программист в свободное от работы время
DDE
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы