防止我的Windows应用程序多次运行

问题描述 投票:0回答:3

我有一个在 Visual Studio 中构建的 Windows 应用程序,它将部署到具有多个用户的其他 PC,并且我想防止我的应用程序多次运行,有什么方法可以以编程方式阻止它?或者其他方式?

c# visual-studio-2010 visual-studio-2019
3个回答
2
投票

您可以使用命名互斥体来实现此目的。命名(!)互斥体是系统范围的同步对象。我在我的项目中使用以下类(稍微简化)。它在构造函数中创建一个最初无主的互斥锁,并在对象生命周期内将其存储在成员字段中。

public class SingleInstance : IDisposable
{
  private System.Threading.Mutex  _mutex;
  
  // Private default constructor to suppress uncontrolled instantiation.
  private SingleInstance(){}
  
  public SingleInstance(string mutexName)
  {
    if(string.IsNullOrWhiteSpace(mutexName))
      throw new ArgumentNullException("mutexName");
    
    _mutex = new Mutex(false, mutexName);         
  }

  ~SingleInstance()
  {
    Dispose(false);
  }
    
  public bool IsRunning
  {
    get
    {
      // requests ownership of the mutex and returns true if succeeded
      return !_mutex.WaitOne(1, true);
    }    
  }

  public void Dispose()
  {
    GC.SuppressFinalize(this);
    Dispose(true);
  }

  protected virtual void Dispose(bool disposing)
  {
    try
    {
      if(_mutex != null)
        _mutex.Close();
    }
    catch(Exception ex)
    {
      Debug.WriteLine(ex);
    }
    finally
    {
      _mutex = null;
    }
  }
}

此示例展示了如何在程序中使用它。

static class Program
{
   static SingleInstance _myInstance = null;

   [STAThread]
   static void Main()
   {
     // ...

     try
     {
       // Create and keep instance reference until program exit
       _myInstance = new SingleInstance("MyUniqueProgramName");

       // By calling this property, this program instance requests ownership 
       // of the wrapped named mutex. The first program instance gets and keeps it 
       // until program exit. All other program instances cannot take mutex
       // ownership and exit here.
       if(_myInstance.IsRunning)
       {
         // You can show a message box, switch to the other program instance etc. here

         // Exit the program, another program instance is already running
         return;
       }

       // Run your app

     }
     finally
     {
       // Dispose the wrapper object and release mutex ownership, if owned
       _myInstance.Dispose();
     }
   }
}

0
投票

我发现互斥体方法效果很好,但前提是您位于一个用户会话中(或者是否有一种方法可以使其跨会话?)。如果你想检查其他用户会话上运行的实例,只要你能确定进程的名称是唯一的,通过进程名称检查对我来说很有效。

private bool IsAnotherInstanceAlreadyRunning()
{
     var thisAppProcesses = Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName);
     return thisAppProcesses.Length > 1;
}

当然,通过在初始化代码中进行此检查,您可以执行任何所需操作来实际阻止应用程序启动。也许会弹出一个窗口“应用程序的实例已在运行。正在退出...”让用户知道发生了什么,然后关闭新的应用程序实例。


-1
投票

您可以使用此代码片段检查实例是否正在运行,并可以提醒用户另一个实例正在运行

   static bool IsRunning()
{
    return Process.GetProcesses().Count(p => p.ProcessName.Contains(Assembly.GetExecutingAssembly().FullName.Split(',')[0]) && !p.Modules[0].FileName.Contains("vshost")) > 1;
}
© www.soinside.com 2019 - 2024. All rights reserved.