Exemple #1
0
        /// <summary>
        /// Creates <see cref="System.Threading.Semaphore"/> to start remoting.
        /// </summary>
        /// <param name="name">Name</param>
        /// <param name="args">Arguments to another instance</param>
        /// <returns>
        /// <para>success: True if no other instance exists and this instance successfully creates</para>
        /// <para>response: Response from another instance if that instance exists and returns an response</para>
        /// </returns>
        public (bool success, object response) Create(string name, string[] args)
        {
            if (string.IsNullOrWhiteSpace(name))
            {
                throw new ArgumentNullException(nameof(name));
            }

            // Determine Semaphore name and IPC port name.
            var          semaphoreName = $"semaphore-{name}";
            var          ipcPortName   = $"port-{name}";
            const string ipcUri        = "space";

            _semaphore = new Semaphore(1, 1, semaphoreName, out bool createdNew);
            if (createdNew)
            {
                try
                {
                    // Instantiate a server channel and register it.
                    _server = new IpcServerChannel(ipcPortName);
                    ChannelServices.RegisterChannel(_server, true);

                    // Instantiate a remoting object and publish it.
                    _space = new RemotingSpace();
                    RemotingServices.Marshal(_space, ipcUri, typeof(RemotingSpace));
                }
                catch (RemotingException ex)
                {
                    Debug.WriteLine("Failed to start remoting as server." + Environment.NewLine
                                    + ex);
                }
                return(success : true, null);
            }
            else
            {
                object response = null;
                try
                {
                    // Instantiate a client channel and register it.
                    var client = new IpcClientChannel();
                    ChannelServices.RegisterChannel(client, true);

                    // Set a proxy for a remoting object instantiated by another instance.
                    var ipcPath = $"ipc://{ipcPortName}/{ipcUri}";
                    _space = Activator.GetObject(typeof(RemotingSpace), ipcPath) as RemotingSpace;

                    // Request that instance to take an action. If it is older version, RemotingException
                    // will be thrown because the remoting object has no such method.
                    response = _space?.Request(args);
                }
                catch (RemotingException ex)
                {
                    Debug.WriteLine("Failed to start remoting as client." + Environment.NewLine
                                    + ex);
                }
                return(success : false, response);
            }
        }
        /// <summary>
        /// Creates semaphore to start remoting.
        /// </summary>
        /// <returns>True if no other instance there and this instance instantiated remoting server</returns>
        public bool Create(string title)
        {
            if (string.IsNullOrWhiteSpace(title))
            {
                throw new ArgumentNullException(nameof(title));
            }

            // Determine Semaphore name and IPC port name using assembly title.
            var          semaphoreName = $"semaphore-{title}";
            var          ipcPortName   = $"port-{title}";
            const string ipcUri        = "space";

            _semaphore = new Semaphore(1, 1, semaphoreName, out bool createdNew);
            if (createdNew)
            {
                try
                {
                    // Instantiate a server channel and register it.
                    _server = new IpcServerChannel(ipcPortName);
                    ChannelServices.RegisterChannel(_server, true);

                    // Instantiate a remoting object and publish it.
                    _space = new RemotingSpace();
                    RemotingServices.Marshal(_space, ipcUri, typeof(RemotingSpace));
                }
                catch (RemotingException ex)
                {
                    Debug.WriteLine("Failed to start remoting." + Environment.NewLine
                                    + ex);
                }
                return(true);
            }
            else
            {
                try
                {
                    // Instantiate a client channel and register it.
                    var client = new IpcClientChannel();
                    ChannelServices.RegisterChannel(client, true);

                    // Set a proxy for remote object.
                    var ipcPath = $"ipc://{ipcPortName}/{ipcUri}";
                    _space = Activator.GetObject(typeof(RemotingSpace), ipcPath) as RemotingSpace;

                    // Raise event.
                    _space?.RaiseShowRequested();
                }
                catch (RemotingException ex)
                {
                    Debug.WriteLine("Failed to start remoting." + Environment.NewLine
                                    + ex);
                }
                return(false);
            }
        }