.NET 4单个应用程序实例

时间:2010-07-09 09:53:55

标签: .net

我经常编写仅支持一个实例的.net应用程序。以前我使用.net-remoting和现在的WCF来检测我的应用程序的实例是否正在运行并将焦点放在此实例上。

我的问题是,如果.net4有更好的解决方案可用于实现单实例应用程序(或者通常有更好的解决方案可用,因为在应用程序一开始就加载WCF或远程处理程序集有坏处绩效影响)

更新

感谢所有帖子。我最初的问题的答案似乎是“不,在.net 4 中实现单实例应用程序没有什么新东西”。

感谢所有附加信息,我将更改当前项目以使用Mutex提供所需的功能。我接受了Bob Moore的答案,因为它附带了最多的信息,但感谢所有发布有用信息的人。

4 个答案:

答案 0 :(得分:11)

传统的方法是使用互斥锁,例如

bool bNew = true; 
using (Mutex mutex = new Mutex(true, "MYAPP_0D36E4C9-399D-4b05-BDA3-EE059FB77E8D", out bNew))
{
   if (bNew)
   {
       // blah, blah,
       Application.Run(new MainForm());
   }
}

编辑:

我发现此代码在线调用SetForegroundWindow,因此您可以找到应用的其他实例并将其推进:

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetForegroundWindow(IntPtr hWnd);


Process me = Process.GetCurrentProcess();
foreach (Process process in Process.GetProcessesByName (me.ProcessName))
{
   if (process.Id != me.Id)
   {
      SetForegroundWindow (process.MainWindowHandle);
      break;
   }
}

请注意,在现代Windows实现中,您只能放弃前景。

答案 1 :(得分:2)

我使用MutexFindWindow来执行此操作。

关于您对其他答案的评论:
有关终端服务中本地和全局互斥锁的信息,follow this link

  

终端服务客户端进程   可以使用带有“全局”的对象名称   或显式的“Local \”前缀   在全局或中创建一个对象   会话名称空间。

这是我用来激活窗口的代码:

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool IsIconic(IntPtr hWnd);

[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
private const int SH_SHOW = 5;
private const int SH_RESTORE = 9;

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetForegroundWindow(IntPtr hWnd);

public void Activate(IntPtr hwnd)
{
    if (IsIconic(hwnd))
        ShowWindow(hwnd, SH_RESTORE);
    else
        ShowWindow(hwnd, SH_SHOW);

    SetForegroundWindow(hwnd);
}

答案 2 :(得分:2)

有一种更简单的方法 - 借助Microsoft.VisualBasic.ApplicationServices中的WindowsFormsApplicationBase类:

using System;
using System.Collections.Generic;

public class SingleInstanceApplicationWrapper :
Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase 
{
  public SingleInstanceApplicationWrapper()
  {
    IsSingleInstance = true;
  }

  private MyApp m_app;
  protected override bool OnStartup(Microsoft.VisualBasic.ApplicationServices.StartupEventArgs e)
  {
    // here we create our WPF application
    m_app = new MyApp();
    m_app.Run();
    return false;
  }

  protected override void OnStartupNextInstance(Microsoft.VisualBasic.ApplicationServices.StartupNextInstanceEventArgs e)
  {
    m_app.DispatchCommandLineParams(e.CommandLine);
  }
}

public class MyApp : System.Windows.Application
{
  protected override void OnStartup(System.Windows.StartupEventArgs e)
  {
    base.OnStartup(e);
    DispatchCommandLineParams(e.Args);
  }
  public void DispatchCommandLineParams(IEnumerable<string> cmdParams)
  {
    // process command line parameters
    Console.WriteLine(this.GetHashCode() + " - dispatched");
  }
}
public class Program
{
  [STAThread]
  public static void Main(string[] args)
  {
    var wrapper = new SingleInstanceApplicationWrapper();
    wrapper.Run(args);
  }
}

答案 3 :(得分:-2)

我建议使用Singleton-Pattern。 看看这个(VB.net的例子!):http://vbnotebookfor.net/2007/09/13/introduction-to-the-singleton-pattern-in-vbnet/

格尔茨