/// <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); } }