예제 #1
0
        /// <summary>
        /// Sends a message to the first instance of the application.
        /// </summary>
        /// <param name="message">The message to send to the first instance of the application. The message must be serializable.</param>
        /// <exception cref="System.InvalidOperationException">The object was constructed with the SingleInstanceTracker(string name) constructor overload, or with the SingleInstanceTracker(string name, SingleInstanceEnforcerRetriever enforcerRetriever) cosntructor overload, with enforcerRetriever set to null.</exception>
        /// <exception cref="SingleInstancing.SingleInstancingException">The SingleInstanceInteractor has failed to send the message to the first application instance. The first instance might have terminated.</exception>
        public void SendMessageToFirstInstance(object message)
        {
            #if IPC_SUPPORTS
            if (fIpcChannel == null)
            {
                throw new InvalidOperationException("The object was constructed with the SingleInstanceTracker(string name) constructor overload, or with the SingleInstanceTracker(string name, SingleInstanceEnforcerRetriever enforcerRetriever) constructor overload, with enforcerRetriever set to null, thus you cannot send messages to the first instance.");
            }

            try {
                fProxy.Enforcer.OnMessageReceived(new MessageEventArgs(message));
            } catch (Exception ex) {
                throw new SingleInstancingException("Failed to send message to the first instance of the application. The first instance might have terminated.", ex);
            }
            #else
            try {
                string[] args = message as string[];
                if (args.Length == 0 || string.IsNullOrEmpty(args[0]))
                {
                    IpcFake.Send(AppMessage.RestoreWindow, 0, false);
                }
                else
                {
                    IpcFake.SendMessage(IpcFake.CmdSendArgs, args);
                }
            } catch (Exception ex) {
                Logger.LogWrite("SingleInstanceTracker.SendMessageToFirstInstance.2(): " + ex.Message);
            }
            #endif
        }
예제 #2
0
        /// <summary>
        /// Releases all unmanaged resources used by the object, and potentially releases managed resources.
        /// </summary>
        /// <param name="disposing">true to dispose of managed resources; otherwise false.</param>
        protected virtual void Dispose(bool disposing)
        {
            if (!fDisposed)
            {
                if (disposing)
                {
                    #if IPC_SUPPORTS
                    if (fSingleInstanceMutex != null)
                    {
                        fSingleInstanceMutex.Close();
                        fSingleInstanceMutex = null;
                    }

                    if (fIpcChannel != null)
                    {
                        ChannelServices.UnregisterChannel(fIpcChannel);
                        fIpcChannel = null;
                    }
                    #else
                    IpcFake.StopServer();
                    IpcFake.ReleaseAllMutexes();
                    #endif
                }

                fDisposed = true;
            }
        }
예제 #3
0
        public void Test_IpcFake_SafeSerialize()
        {
            Assert.Throws(typeof(ArgumentNullException), () => { IpcFake.SafeSerialize(null); });
            Assert.Throws(typeof(ArgumentNullException), () => { IpcFake.SafeDeserialize(null); });

            string[] args = new string[] { "testA", "testB" };
            string   temp = IpcFake.SafeSerialize(args);

            string[] res = IpcFake.SafeDeserialize(temp);
            Assert.AreEqual(args[0], res[0]);
            Assert.AreEqual(args[1], res[1]);
        }
예제 #4
0
        public static bool CreateMutex(string strName, bool bInitiallyOwned)
        {
            string strPath = IpcFake.GetMutexPath(strName);

            try
            {
                if (File.Exists(strPath))
                {
                    byte[] pbEnc = File.ReadAllBytes(strPath);

                    if (pbEnc.Length == 12)
                    {
                        long     lTime = BitConverter.ToInt64(pbEnc, 0);
                        DateTime dt    = DateTime.FromBinary(lTime);

                        if ((DateTime.UtcNow - dt).TotalSeconds < GmpMutexValidSecs)
                        {
                            int pid = BitConverter.ToInt32(pbEnc, 8);
                            try
                            {
                                Process.GetProcessById(pid); // Throws if process is not running
                                return(false);               // Actively owned by other process
                            }
                            catch (Exception) { }
                        }

                        // Release the old mutex since process is not running
                        ReleaseMutex(strName);
                    }
                    else
                    {
                        Debug.Assert(false);
                    }
                }
            }
            catch (Exception)
            {
                Debug.Assert(false);
            }

            try {
                WriteMutexFilePriv(strPath);
            } catch (Exception) {
                Debug.Assert(false);
            }

            fMutexes.Add(new KeyValuePair <string, string>(strName, strPath));
            return(true);
        }
예제 #5
0
        public void Test_IpcFake()
        {
            IpcFake.StartServer(GetSingleInstanceEnforcer());

            Assert.AreEqual(true, IpcFake.CreateMutex("test", true));
            IpcFake.RefreshMutexes();

            Assert.AreEqual(false, IpcFake.CreateMutex("test", true));
            IpcFake.RefreshMutexes();

            Assert.Throws(typeof(ArgumentNullException), () => { IpcFake.SendMessage(null); });

            IpcFake.SendMessage(IpcFake.CmdSendArgs, new string[] { "testArgX" });

            IpcFake.StopServer();
            IpcFake.ReleaseAllMutexes();
        }
예제 #6
0
        /// <summary>
        /// Instantiates a new SingleInstanceTracker object.
        /// When using this constructor overload and enforcerRetriever is null, the SingleInstanceTracker object can only be used to determine whether the application is already running.
        /// </summary>
        /// <param name="name">The unique name used to identify the application.</param>
        /// <param name="enforcerRetriever">The method which would be used to retrieve an ISingleInstanceEnforcer object when instantiating the new object.</param>
        /// <exception cref="System.ArgumentNullException">name is null or empty.</exception>
        /// <exception cref="SingleInstancing.SingleInstancingException">A general error occured while trying to instantiate the SingleInstanceInteractor. See InnerException for more details.</exception>
        public SingleInstanceTracker(string name, SingleInstanceEnforcerRetriever enforcerRetriever)
        {
            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException("name", @"name cannot be null or empty.");
            }

            try
            {
                // Do not attempt to construct the IPC channel if there is no need for messages
                if (enforcerRetriever != null)
                {
                    #if IPC_SUPPORTS
                    fSingleInstanceMutex = new Mutex(true, name, out fIsFirstInstance);

                    const string proxyObjectName = "SingleInstanceProxy";
                    string       proxyUri        = "ipc://" + name + "/" + proxyObjectName;

                    // If no previous instance was found, create a server channel which will provide the proxy to the first created instance
                    if (fIsFirstInstance)
                    {
                        // Create an IPC server channel to listen for SingleInstanceProxy object requests
                        fIpcChannel = new IpcServerChannel(name);
                        // Register the channel and get it ready for use
                        ChannelServices.RegisterChannel(fIpcChannel, false);
                        // Register the service which gets the SingleInstanceProxy object, so it can be accessible by IPC client channels
                        RemotingConfiguration.RegisterWellKnownServiceType(typeof(SingleInstanceProxy), proxyObjectName, WellKnownObjectMode.Singleton);

                        // Attempt to retrieve the enforcer from the delegated method
                        ISingleInstanceEnforcer enforcer = enforcerRetriever();
                        // Validate that an enforcer object was returned
                        if (enforcer == null)
                        {
                            throw new InvalidOperationException("The method delegated by the enforcerRetriever argument returned null. The method must return an ISingleInstanceEnforcer object.");
                        }

                        // Create the first proxy object
                        fProxy = new SingleInstanceProxy(enforcer);
                        // Publish the first proxy object so IPC clients requesting a proxy would receive a reference to it
                        RemotingServices.Marshal(fProxy, proxyObjectName);
                    }
                    else
                    {
                        // Create an IPC client channel to request the existing SingleInstanceProxy object.
                        fIpcChannel = new IpcClientChannel();
                        // Register the channel and get it ready for use
                        ChannelServices.RegisterChannel(fIpcChannel, false);

                        // Retreive a reference to the proxy object which will be later used to send messages
                        fProxy = (SingleInstanceProxy)Activator.GetObject(typeof(SingleInstanceProxy), proxyUri);

                        // Notify the first instance of the application that a new instance was created
                        fProxy.Enforcer.OnNewInstanceCreated(new EventArgs());
                    }
                    #else
                    fIsFirstInstance = IpcFake.CreateMutex(name, true);

                    if (fIsFirstInstance)
                    {
                        // Attempt to retrieve the enforcer from the delegated method
                        ISingleInstanceEnforcer enforcer = enforcerRetriever();
                        // Validate that an enforcer object was returned
                        if (enforcer == null)
                        {
                            throw new InvalidOperationException("The method delegated by the enforcerRetriever argument returned null. The method must return an ISingleInstanceEnforcer object.");
                        }

                        // Create the first proxy object
                        fProxy = new SingleInstanceProxy(enforcer);

                        IpcFake.StartServer(enforcer);
                    }
                    else
                    {
                    }
                    #endif
                }
            }
            catch (Exception ex)
            {
                throw new SingleInstancingException("Failed to instantiate a new SingleInstanceTracker object. See InnerException for more details.", ex);
            }
        }
예제 #7
0
        public static void SendMessage(string cmd, string[] args)
        {
            IpcParamEx ipcMsg = new IpcParamEx(cmd, IpcFake.SafeSerialize(args));

            IpcFake.SendMessage(ipcMsg);
        }