在.NET中防止给定应用程序的多个实例?

C. *_* 76 121 .net c#

在.NET中,防止应用程序的多个实例同时运行的最佳方法是什么?如果没有"最佳"技术,每种解决方案需要考虑哪些注意事项?

小智 148

使用互斥锁.上面使用GetProcessByName的一个例子有很多警告.这是一篇关于这个主题的好文章:

http://odetocode.com/Blogs/scott/archive/2004/08/20/401.aspx

[STAThread]
static void Main() 
{
   using(Mutex mutex = new Mutex(false, "Global\\" + appGuid))
   {
      if(!mutex.WaitOne(0, false))
      {
         MessageBox.Show("Instance already running");
         return;
      }

      Application.Run(new Form1());
   }
}

private static string appGuid = "c0a76b5a-12ab-45c5-b9d9-d693faa6e7b9";
Run Code Online (Sandbox Code Playgroud)

  • 这是一个稍微填好的版本,带有一些好的评论:http://stackoverflow.com/questions/229565/what-is-a-good-pattern-for-using-a-global-mutex-in-c/ 229567 (8认同)
  • 为了在版本控制或更改应用程序 guid 时更好地控制,您可以使用:`string appGuid = ((GuidAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(GuidAttribute), true)[0]).Value;`这将获得执行程序集的 guid (5认同)
  • @ClarkKent:只是一个随机字符串,以便Mutex名称不会与另一个应用程序中的名称冲突. (2认同)
  • 我花了一段时间才意识到,只有当实例运行时互斥锁就存在时,上面的代码才有效。我删除了 using 块并将互斥变量更改为静态(或在 vb.net 中共享)。之后一切都按预期进行。 (2认同)

小智 19

if (Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).Length > 1)
{
  AppLog.Write("Application XXXX already running. Only one instance of this application is allowed", AppLog.LogMessageType.Warn);
  return;
}
Run Code Online (Sandbox Code Playgroud)

  • -1 虽然这是快速解决方案,但也很容易绕过 a.exe 可以重命名为 b.exe 并且两者都会运行。+ 其他情况,这根本无法按预期工作。谨慎使用! (2认同)

Sei*_*bar 18

以下是确保只运行一个实例所需的代码.这是使用命名互斥锁的方法.

public class Program
{
    static System.Threading.Mutex singleton = new Mutex(true, "My App Name");

    static void Main(string[] args)
    {
        if (!singleton.WaitOne(TimeSpan.Zero, true))
        {
            //there is already another instance running!
            Application.Exit();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 对于WPF应用程序,使用Application.Current.Shutdown(); 这种方法就像一个魅力.谢谢水龟. (2认同)

bdu*_*kes 7

Hanselman有一篇关于使用Microsoft.VisualBasic程序集中的WinFormsApplicationBase类的帖子.


Kas*_*sen 7

在尝试了多种解决方案后,我的问题出现了。我最终在这里使用了WPF的示例:http ://www.c-sharpcorner.com/UploadFile/f9f215/how-to-restrict-the-application-to-just-one-instance/

public partial class App : Application  
{  
    private static Mutex _mutex = null;  

    protected override void OnStartup(StartupEventArgs e)  
    {  
        const string appName = "MyAppName";  
        bool createdNew;  

        _mutex = new Mutex(true, appName, out createdNew);  

        if (!createdNew)  
        {  
            //app is already running! Exiting the application  
            Application.Current.Shutdown();  
        }  

    }          
}  
Run Code Online (Sandbox Code Playgroud)

在 App.xaml 中:

x:Class="*YourNameSpace*.App"
StartupUri="MainWindow.xaml"
Startup="App_Startup"
Run Code Online (Sandbox Code Playgroud)


小智 6

1 - 在 program.cs 中创建一个引用 ->

using System.Diagnostics;
Run Code Online (Sandbox Code Playgroud)

2 -void Main()作为第一行代码放入->

 if (Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).Length >1)
                return;
Run Code Online (Sandbox Code Playgroud)

就是这样。

  • 它使用进程的名称。如果名称重复,则会生成错误标志。在任何其他情况下,它都比互斥体更干净 (3认同)

C. *_* 76 5

听起来到目前为止已经提出了3种基本技术.

  1. 从Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase类派生,并将IsSingleInstance属性设置为true.(我相信这里需要注意的是,这不适用于WPF应用程序,不是吗?)
  2. 使用命名的互斥锁并检查它是否已创建.
  3. 获取正在运行的进程列表并比较进程的名称.(这有一点需要注意,要求您的进程名称相对于在给定用户的计算机上运行的任何其他进程是唯一的.)

我错过了任何警告?

  • 我不认为3是非常有效的.我投票支持Mutex,多次使用它没有问题.我从来没有使用过第1项,因为当你在c#中时,我不确定它是多么苍白. (3认同)
  • 选项1仍适用于WPF,它只是稍微涉及一些.http://msdn.microsoft.com/en-us/library/ms771662.aspx (2认同)

Hyp*_*peZ 5

我在这里尝试了所有解决方案,但在我的 C# .net 4.0 项目中没有任何效果。希望能帮助这里的人找到对我有用的解决方案:

作为主类变量:

private static string appGuid = "WRITE AN UNIQUE GUID HERE";
private static Mutex mutex;
Run Code Online (Sandbox Code Playgroud)

当您需要检查应用程序是否已在运行时:

bool mutexCreated;
mutex = new Mutex(true, "Global\\" + appGuid, out mutexCreated);
if (mutexCreated)
    mutex.ReleaseMutex();

if (!mutexCreated)
{
    //App is already running, close this!
    Environment.Exit(0); //i used this because its a console app
}
Run Code Online (Sandbox Code Playgroud)

我只需要在某些条件下关闭其他实例,这对我的目的很有效

  • 您不需要实际获取互斥锁并释放它。您需要知道的是另一个应用程序是否已经创建了该对象(即其内核引用计数>=1)。 (2认同)