C# 使用互斥体运行应用程序的单个实例

C# 使用互斥体运行应用程序的单个实例,c#,mutex,C#,Mutex,为了只允许运行应用程序的单个实例,我使用互斥。代码如下所示。这样做对吗?代码中有什么缺陷吗 当用户第二次尝试打开应用程序时,如何显示已经运行的应用程序。目前(在下面的代码中),我只是显示另一个实例已经在运行的消息 static void Main(string[] args) { Mutex _mut = null; try { _mut = Mutex.OpenExisting(AppDomain.Cur

为了只允许运行应用程序的单个实例,我使用互斥。代码如下所示。这样做对吗?代码中有什么缺陷吗

当用户第二次尝试打开应用程序时,如何显示已经运行的应用程序。目前(在下面的代码中),我只是显示另一个实例已经在运行的消息

    static void Main(string[] args)
    {
        Mutex _mut = null;

        try
        {
            _mut = Mutex.OpenExisting(AppDomain.CurrentDomain.FriendlyName);
        }
        catch
        {
             //handler to be written
        }

        if (_mut == null)
        {
            _mut = new Mutex(false, AppDomain.CurrentDomain.FriendlyName);
        }
        else
        {
            _mut.Close();
            MessageBox.Show("Instance already running");

        }            
    }
看看


这篇文章有一个链接:其中解释了互斥的用法。

我曾经这样做过一次,希望它能帮助:

bool createdNew;

Mutex m = new Mutex(true, "myApp", out createdNew);

if (!createdNew)
{
    // myApp is already running...
    MessageBox.Show("myApp is already running!", "Multiple Instances");
    return;
}

还有这个

查看上显示的代码示例

简而言之,您使用重载互斥对象
ctor(bool,string,out bool)
,它通过out参数告诉您是否获得了命名互斥对象的所有权。如果您是第一个实例,那么在调用ctor之后,这个out参数将包含true——在这种情况下,您将照常进行。如果此参数为false,则表示另一个实例已获得所有权/正在运行,在这种情况下,您将显示一条错误消息“另一个实例已在运行”。然后正常退出

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

    GC.Collect();                
    Application.Run(new Form1());
  }
}
来源:

我用这个:

    private static Mutex _mutex;

    private static bool IsSingleInstance()
    {
        _mutex = new Mutex(false, _mutexName);

        // keep the mutex reference alive until the normal 
        //termination of the program
        GC.KeepAlive(_mutex);

        try
        {
            return _mutex.WaitOne(0, false);
        }
        catch (AbandonedMutexException)
        {
            // if one thread acquires a Mutex object 
            //that another thread has abandoned 
            //by exiting without releasing it

            _mutex.ReleaseMutex();
            return _mutex.WaitOne(0, false);
        }
    }


    public Form1()
    {
        if (!isSingleInstance())
        {
            MessageBox.Show("Instance already running");
            this.Close();
            return;
        }

        //program body here
    }

    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        if (_mutex != null)
        {
            _mutex.ReleaseMutex();
        }
    }    

使用具有超时和安全设置的应用程序。我使用了我的自定义类:

private class SingleAppMutexControl : IDisposable
    {
        private readonly Mutex _mutex;
        private readonly bool _hasHandle;

        public SingleAppMutexControl(string appGuid, int waitmillisecondsTimeout = 5000)
        {
            bool createdNew;
            var allowEveryoneRule = new MutexAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null),
                MutexRights.FullControl, AccessControlType.Allow);
            var securitySettings = new MutexSecurity();
            securitySettings.AddAccessRule(allowEveryoneRule);
            _mutex = new Mutex(false, "Global\\" + appGuid, out createdNew, securitySettings);
            _hasHandle = false;
            try
            {
                _hasHandle = _mutex.WaitOne(waitmillisecondsTimeout, false);
                if (_hasHandle == false)
                    throw new System.TimeoutException();
            }
            catch (AbandonedMutexException)
            {
                _hasHandle = true;
            }
        }

        public void Dispose()
        {
            if (_mutex != null)
            {
                if (_hasHandle)
                    _mutex.ReleaseMutex();
                _mutex.Dispose();
            }
        }
    }
并使用它:

    private static void Main(string[] args)
    {
        try
        {
            const string appguid = "{xxxxxxxx-xxxxxxxx}";
            using (new SingleAppMutexControl(appguid))
            {

                Console.ReadLine();
            }
        }
        catch (System.TimeoutException)
        {
            Log.Warn("Application already runned");
        }
        catch (Exception ex)
        {
            Log.Fatal(ex, "Fatal Error on running");
        }
    }

请务必阅读以下内容:此代码不安全或不正确…'“全局”使其成为计算机的全局,而不是运行中的用户。因此,在服务器环境或终端服务中,一次只能有一个用户运行它。我认为大多数用户期望一个实例对他们来说意味着一个实例。这段代码既不安全也不正确:我希望这是安全和正确的。它非常简单,可以很容易地写,几乎没有任何想法,所有lol.+1给你们两个,尽管如此。@SamSaffron-您是说只有在多个用户可能请求互斥的情况下才是不安全和不正确的,还是在只有一个用户请求互斥的情况下才是不安全和不正确的?我不同意Sam的评论(以及反对票)。代码不使用互斥同步。相反,互斥锁仅用于确定是否已由另一个进程创建,并且在进程终止(包括异常终止)时将被销毁。我会认为它是安全和正确的,直到看到一个解释为什么它是不正确的。问题可能是一个恶意应用程序在不同的会话中获取互斥锁并运行两次进程。前者是破坏,后者包含在问题中(“用户试图第二次打开应用程序”)。这应该放在我的C#应用程序的哪个功能中?