InitialInstanceActivator

SingleTon

  1 //  InitialInstanceActivator.cs
  2 //  Inspired by Mike Woodring
  3 //  Copyright (c) 2003, Chris Sells
  4 //  Notes:
  5 //  -Uses Application.UserAppDataPath to pick a unique string composed
  6 //   of the app name, the app version and the user name. This
  7 //  gets us a unique mutex name, channel name and port number for each
  8 //   user running each app of a specific version.
  9 //  Usage:
 10 /*
 11TODO: Reference the System.Runtime.Remoting assembly
 12using SellsBrothers;
 13
 14static void Main(string[] args) {
 15  // Check for initial instance, registering callback to consume args from other instances
 16  // Main form will be activated automatically
 17  OtherInstanceCallback callback = new OtherInstanceCallback(OnOtherInstance);
 18  if( InitialInstanceActivator.Activate(mainForm, callback, args) ) return;
 19  
 20  // Check for initial instance w/o registering a callback
 21  // Main form will still be activated automatically
 22  if( InitialInstanceActivator.Activate(mainForm) ) return;
 23
 24  // Check for initial instance, registering callback to consume args from other instances
 25  // Main form from ApplicationContext will be activated automatically
 26  OtherInstanceCallback callback = new OtherInstanceCallback(OnOtherInstance);
 27  if( InitialInstanceActivator.Activate(context, callback, args) ) return;
 28
 29  TODO: Run application
 30}
 31
 32// Called from other instances
 33static void OnOtherInstance(string[] args) {
 34  TODO: Handle args from other instance
 35}
 36*/

 37
 38 using  System;
 39 using  System.Windows.Forms;
 40 using  System.Threading;
 41 using  System.Runtime.Remoting;
 42 using  System.Runtime.Remoting.Lifetime;
 43 using  System.Runtime.Remoting.Channels;
 44 using  System.Runtime.Remoting.Channels.Tcp;
 45
 46 namespace  SellsBrothers  {
 47  // Signature of method to call when another instance is detected
 48  public delegate void OtherInstanceCallback(string[] args);
 49
 50  public class InitialInstanceActivator {
 51    public static int Port {
 52      get {
 53        // Pick a port based on an application-specific string
 54        // that also falls into an exceptable range
 55        return Math.Abs(ChannelName.GetHashCode()/2)%(short.MaxValue - 1024+ 1024;
 56      }

 57    }

 58
 59    public static string ChannelName {
 60      get {
 61        return Application.UserAppDataPath.ToLower().Replace(@"/""_");
 62      }

 63    }

 64
 65    public static string MutexName {
 66      get {
 67        return ChannelName;
 68      }

 69    }

 70
 71    public static bool Activate(Form mainForm) {
 72      return Activate(new ApplicationContext(mainForm), nullnull);
 73    }

 74
 75    public static bool Activate(Form mainForm, OtherInstanceCallback callback, string[] args) {
 76      return Activate(new ApplicationContext(mainForm), callback, args);
 77    }

 78
 79    public static bool Activate(ApplicationContext context, OtherInstanceCallback callback, string[] args) {
 80      // Check for existing instance
 81      bool firstInstance = false;
 82      Mutex mutex = new Mutex(true, MutexName, out firstInstance);
 83
 84      if!firstInstance ) {
 85        // Open remoting channel exposed from initial instance
 86        string url = string.Format("tcp://localhost:{0}/{1}", Port, ChannelName);
 87        MainFormActivator activator = (MainFormActivator)RemotingServices.Connect(typeof(MainFormActivator), url);
 88
 89        // Send arguments to initial instance and exit this one
 90        activator.OnOtherInstance(args);
 91        return true;
 92      }

 93
 94      // Expose remoting channel to accept arguments from other instances
 95      ChannelServices.RegisterChannel(new TcpChannel(Port));
 96      RemotingServices.Marshal(new MainFormActivator(context, callback), ChannelName);
 97      return false;
 98    }

 99
100    public class MainFormActivator : MarshalByRefObject {
101      public MainFormActivator(ApplicationContext context, OtherInstanceCallback callback) {
102        this.context = context;
103        this.callback = callback;
104      }

105
106      public override object InitializeLifetimeService() {
107        // We want an infinite lifetime as far as the
108        // remoting infrastructure is concerned
109        // (Thanks for Mike Woodring for pointing this out)
110        ILease lease = (ILease)base.InitializeLifetimeService();
111        lease.InitialLeaseTime = TimeSpan.Zero;
112        return(lease);
113      }

114
115      public void OnOtherInstance(string[] args) {
116        // Transition to the UI thread
117        ifthis.context.MainForm.InvokeRequired ) {
118          OtherInstanceCallback callback = new OtherInstanceCallback(OnOtherInstance);
119          this.context.MainForm.Invoke(callback, new object[] { args });
120          return;
121        }

122
123        // Let the UI thread know about the other instance
124        ifthis.callback != null ) this.callback(args);
125
126        // Activate the main form
127        context.MainForm.Activate();
128      }

129
130      ApplicationContext context;
131      OtherInstanceCallback callback;
132    }

133  }

134}

135
136
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值