/// <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 { singleInstanceMutex = new Mutex(true, name, out isFirstInstance); // Do not attempt to construct the IPC channel if there is no need for messages if (enforcerRetriever != null) { 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 (isFirstInstance) { // Create an IPC server channel to listen for SingleInstanceProxy object requests ipcChannel = new IpcServerChannel(name); // Register the channel and get it ready for use ChannelServices.RegisterChannel(ipcChannel, 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 proxy = new SingleInstanceProxy(enforcer); // Publish the first proxy object so IPC clients requesting a proxy would receive a reference to it RemotingServices.Marshal(proxy, proxyObjectName); } else { // Create an IPC client channel to request the existing SingleInstanceProxy object. ipcChannel = new IpcClientChannel(); // Register the channel and get it ready for use ChannelServices.RegisterChannel(ipcChannel, false); // Retreive a reference to the proxy object which will be later used to send messages proxy = (SingleInstanceProxy)Activator.GetObject(typeof(SingleInstanceProxy), proxyUri); // Notify the first instance of the application that a new instance was created // proxy.Enforcer.OnNewInstanceCreated(new EventArgs()); } } } catch (Exception ex) { throw new SingleInstancingException("Failed to instantiate a new SingleInstanceTracker object. See InnerException for more details.", ex); } }
/// <summary> /// Instantiates a new SingleInstanceProxy object. /// </summary> /// <param name="enforcer">The enforcer (first instance of the application) which will receive messages from the new instances of the application.</param> /// <exception cref="System.ArgumentNullException">enforcer is null.</exception> public SingleInstanceProxy(ISingleInstanceEnforcer enforcer) { if (enforcer == null) throw new ArgumentNullException("enforcer", "enforcer cannot be null."); this.enforcer = enforcer; }
public static void StartServer(ISingleInstanceEnforcer enforcer) { StopServer(); fEnforcer = enforcer; EnsurePaths(); try { fFileWatcher = new FileSystemWatcher(GetIpcPath(), fMsgFileName); fFileWatcher.IncludeSubdirectories = false; fFileWatcher.NotifyFilter = (NotifyFilters.CreationTime | NotifyFilters.LastWrite); fFileWatcher.Created += OnFileEvents; fFileWatcher.Changed += OnFileEvents; fFileWatcher.EnableRaisingEvents = true; } catch (Exception ex) { // Access denied Logger.LogWrite("IpcFake.StartServer(): " + ex.Message); } }