Запустите один экземпляр приложения, используя Mutex - PullRequest
22 голосов
/ 04 мая 2009

Чтобы разрешить запуск только одного экземпляра приложения, я использую мьютекс. Код приведен ниже. Это правильный способ сделать это? Есть ли недостатки в коде?

Как показать уже запущенное приложение, когда пользователь пытается открыть приложение во второй раз. В настоящее время (в коде ниже) я просто отображаю сообщение, что другой экземпляр уже запущен.

    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");

        }            
    }

Ответы [ 7 ]

14 голосов
/ 04 мая 2009

Я сделал это один раз, надеюсь, это поможет:

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;
}
7 голосов
/ 04 мая 2009
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());
  }
}

Источник: http://odetocode.com/Blogs/scott/archive/2004/08/20/401.aspx

3 голосов
/ 27 декабря 2012

Я использую это:

    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();
        }
    }    
1 голос
/ 28 июля 2015

Используйте приложение с настройками тайм-аута и безопасности. Я использовал свой пользовательский класс:

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");
        }
    }
1 голос
/ 04 мая 2009

Ознакомьтесь с примером кода, показанным на этой странице

Короче говоря, вы используете перегрузку Mutex ctor(bool, string, out bool), которая сообщает через выходной параметр, получили ли вы право собственности на Named Mutex. Если вы первый экземпляр, этот параметр out будет содержать true после вызова ctor - в этом случае вы продолжите как обычно. Если этот параметр имеет значение false, это означает, что другой экземпляр уже получил право собственности / работает, и в этом случае отображается сообщение об ошибке «Другой экземпляр уже запущен». а затем выйдите изящно.

1 голос
/ 04 мая 2009

Посмотрите на этот вопрос

Есть ссылка на эту статью: неправильно понятый мьютекс , где объясняется использование мьютекса.

...