如何将程序限制为单个实例

san*_*ngh 35 c#

我在C#中有一个控制台应用程序,我想限制我的应用程序一次只运行一个实例.我如何在C#中实现这一目标?

SwD*_*n81 47

我会使用Mutex

  static void Main()
  {
     string mutex_id = "MY_APP";
     using (Mutex mutex = new Mutex(false, mutex_id))
     {
        if (!mutex.WaitOne(0, false))
        {
           MessageBox.Show("Instance Already Running!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);
           return;
        }
        // Do stuff
     }
  }
Run Code Online (Sandbox Code Playgroud)


Ran*_*Ran 33

如果您决定使用Mutex用于此目的,您应该注意一些陷阱:

  • 如果要将应用程序限制为每台计算机一个实例(即每个登录用户不是一个实例),那么您将需要以互斥锁名称开头的前缀Global\.如果不添加此前缀,操作系统将为每个用户创建一个不同的互斥锁实例.

  • 如果您在启用了UAC的Windows Vista或更高版本的计算机上运行,​​并且当前的应用程序实例有可能以管理员身份运行,则下一个实例将无法检测到它,您将获得权限异常.为避免这种情况,您需要在创建Mutex时为其指定一组不同的权限.

  • 好的陷阱.另一个是,如果你正在运行两个互相讨厌的程序,其中一个程序可能会尝试通过取出另一个程序的命名互斥锁并从不释放它来对用户发起拒绝服务攻击. (6认同)
  • 很好......但是我怀疑这是值得保护的,因为一个"邪恶的"程序,一旦你相信它应该运行它,无论如何都会弄乱其他程序,并且不需要互斥锁.例如,它可以杀死其他进程,破坏其他程序的已安装文件,更改其快捷方式或完全卸载它... (3认同)

Mad*_*uja 19

有很多方法,例如 -

  • 如果进程名已存在,则在启动之前枚举进程列表并拒绝启动.
  • 在启动时创建互斥锁并检查互斥锁是否已存在.
  • 通过单例类启动程序.

每个都演示如下:

http://iridescence.no/post/CreatingaSingleInstanceApplicationinC.aspx
http://www.codeproject.com/KB/cs/restricting_instances.aspx
http://www.codeproject.com/KB/cs/singleinstance.aspx

每个都有其优点和缺点.但我相信创建互斥锁是最好的选择.