2011-09-19 49 views
1

我有一个应该只能在单个实例中运行的webform(c#)应用程序。同样重要的是,如果应用程序再次启动(点击应用程序图标),那么新参数应该被转发到当前实例,但现在应用程序将被启动。Winform应用程序的单例,但提供参数?

我ofcouse谷歌的问题,并发现这一点:http://www.sanity-free.com/143/csharp_dotnet_single_instance_application.html

这是我如何设定它为止:

public class MyApp : ApplicationContext 
{ 
     private static MyApp _instance; 
     private static Mutex _mutex = new Mutex(true, "{8F6F0AC4-B9A1-45fd-A8CF-72F04E6BDE8F}"); 

     [STAThread] 
     public static void Main(string[] args) 
     { 
      MyParams params; 

      params = ExtractParams(args); 

      if (_mutex.WaitOne(TimeSpan.Zero, true)) 
      { 
        _instance = new MyAppp(params); 
        Application.Run(_instance); 
      } 
      else 
      { 
        _instance.SetParameters(params); 
      } 
     } 
} 

的问题,这是我第二次尝试启动该程序我会得到一个异常,在其他_instance为空?

我在这里做错了什么?

回答

1

在这种情况下,它是一个进程间通信(IPC),因此_instance不会感知。如果你想拥有IPC,里有一些方法可以做到:插座,namepiped,消息...

我认为2种方法适合:

  1. 获得通过的进程名之前的过程 - >调用P/Invoke EnumWindows方法来获取主窗口句柄。发送带有ID的消息之前已经使用RegisterWindowMessage进行了注册,以传递参数。
  2. 创建一个namedpipe服务器来侦听新进程的参数。
+0

我要和sugestions 2一起去,它似乎现在工作得很好。 – Banshee

2

.NET程序集Microsoft.VisualBasic.dll包含一个名为WindowsFormsApplicationBase的类。这个也可以被C#应用程序使用,并且有一个名为IsSingleInstance的属性,它可以被设置为实现所需的行为。

在第一次应用程序启动时,您可以注册一个事件处理函数以便进一步启动应用程序。从事件参数中,您可以提取每个附加启动的命令行参数。

查看示例here

+0

斯蒂芬>谢谢,我看了一下这一点,我们选用的其他方式(不VisualBasic.dll)becouse它没有feelt权利包括在C#应用程序的VisialBasic.dll文件?但玛比我们没有选择了吗? – Banshee

+0

+1个不错的例子,我以前从未发现过。但是再一次,我从来没有实现一个单一的实例应用程序lol –

+0

@SnowJim:那么你的方法是一个好的开始,你需要找到一种方法将参数传递给正在运行的实例。 – Stephan

相关问题