当前位置:  开发笔记 > 编程语言 > 正文

如何强制C#.net应用程序在Windows中只运行一个实例?

如何解决《如何强制C#.net应用程序在Windows中只运行一个实例?》经验,为你挑选了3个好方法。



1> Mitchel Sell..:

我更喜欢类似于以下的互斥解决方案.这样,如果应用程序已经加载,它会重新关注应用程序

using System.Threading;

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

/// 
/// The main entry point for the application.
/// 
[STAThread]
static void Main()
{
   bool createdNew = true;
   using (Mutex mutex = new Mutex(true, "MyApplicationName", out createdNew))
   {
      if (createdNew)
      {
         Application.EnableVisualStyles();
         Application.SetCompatibleTextRenderingDefault(false);
         Application.Run(new MainForm());
      }
      else
      {
         Process current = Process.GetCurrentProcess();
         foreach (Process process in Process.GetProcessesByName(current.ProcessName))
         {
            if (process.Id != current.Id)
            {
               SetForegroundWindow(process.MainWindowHandle);
               break;
            }
         }
      }
   }
}


关于以这种方式使用MainWindowHandle属性的一点FYI(正如我刚刚发现的那样):"如果关联的进程没有主窗口,*MainWindowHandle值为零*.对于具有的进程,值为*也为零*已被隐藏,即任务栏中不可见的进程.对于在任务栏最右侧的通知区域中显示为图标的进程,情况可能如此."
SetForegroundWindow不适合我.从来没有工作过,实际上.
如果您的应用程序可以最小化,您可能还想调用`ShowWindow(process.MainWindowHandle,SW_RESTORE)`来恢复它.http://stackoverflow.com/questions/4566632/maximize-another-process-window-in-net提供了详细信息.SW_RESTORE是9(来自http://msdn.microsoft.com/en-gb/library/windows/desktop/ms633548%28v=vs.85%29.aspx).

2> 小智..:

强制只运行.net(C#)中程序的一个实例,在program.cs文件中使用此代码:

public static Process PriorProcess()
    // Returns a System.Diagnostics.Process pointing to
    // a pre-existing process with the same name as the
    // current one, if any; or null if the current process
    // is unique.
    {
        Process curr = Process.GetCurrentProcess();
        Process[] procs = Process.GetProcessesByName(curr.ProcessName);
        foreach (Process p in procs)
        {
            if ((p.Id != curr.Id) &&
                (p.MainModule.FileName == curr.MainModule.FileName))
                return p;
        }
        return null;
    }

以及如下:

[STAThread]
    static void Main()
    {
        if (PriorProcess() != null)
        {

            MessageBox.Show("Another instance of the app is already running.");
            return;
        }
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form());
    }


好的,@ greenoldman,但是从什么时候用户/客户"调试"你的应用程序,然后选择与它一起运行第二个(二进制).与我在本网站上看到的许多基于Mutex的anwsers相比,这个答案相当不错.
这是不正确的方式.我可以在两个实例中运行你的程序 - 一个作为二进制启动,第二个从VS启动.
我知道这是多年以后但是如果有人发现这个像我做的那样:如果用户不是管理员(至少在Win7中),"Process.GetProcessesByName"将抛出异常.

3> Martin Plant..:

这是我在我的应用程序中使用的:

static void Main()
{
  bool mutexCreated = false;
  System.Threading.Mutex mutex = new System.Threading.Mutex( true, @"Local\slimCODE.slimKEYS.exe", out mutexCreated );

  if( !mutexCreated )
  {
    if( MessageBox.Show(
      "slimKEYS is already running. Hotkeys cannot be shared between different instances. Are you sure you wish to run this second instance?",
      "slimKEYS already running",
      MessageBoxButtons.YesNo,
      MessageBoxIcon.Question ) != DialogResult.Yes )
    {
      mutex.Close();
      return;
    }
  }

  // The usual stuff with Application.Run()

  mutex.Close();
}

推荐阅读
殉情放开那只小兔子
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有