Подтвердить что ты не робот

Запуск одного экземпляра приложения с помощью Mutex

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

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

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

        }            
    }
4b9b3361

Ответ 1

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

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;
}

Ответ 2

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

Ответ 4

Проверьте образец кода, показанный на на этой странице

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

Ответ 5

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

    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();
        }
    }    

Ответ 6

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

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