C# 使用 Mutex 运行应用程序的单个实例

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/819773/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 02:27:12  来源:igfitidea点击:

Run single instance of an application using Mutex

c#mutex

提问by blitzkriegz

In order to allow only a single instance of an application running I'm using mutex. The code is given below. Is this the right way to do it? Are there any flaws in the code?

为了只允许运行应用程序的单个实例,我正在使用互斥锁。代码如下。这是正确的方法吗?代码中是否有任何缺陷?

How to show the already running application when user tries to open the application the second time. At present (in the code below), I'm just displaying a message that another instance is already running.

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

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

        }            
    }

采纳答案by Peter D

I did it this way once, I hope it helps:

我这样做过一次,我希望它有帮助:

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

回答by tanascius

Have a look at this question

看看这个问题

There is a link to this article: the misunderstood mutexwhere the usage of a mutex is explained.

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

回答by Gishu

Check out the code sample shown on this page

查看此页面上显示的代码示例

In short, you use the overload Mutex ctor(bool, string, out bool)which tells you via an out parameter, whether you got ownership of the Named Mutex. If you're the first instance, this out param would contain true after the ctor is called - in which case you proceed as usual. If this param is false, it means another instance has already got ownership/is running, in which case you show an error message "Another instance is already running." and then exit gracefully.

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

回答by Milen

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

Source : http://odetocode.com/Blogs/scott/archive/2004/08/20/401.aspx

来源:http: //odetocode.com/Blogs/scott/archive/2004/08/20/401.aspx

回答by algreat

I use this:

我用这个:

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

回答by vivlav

Use app with timeout and security settings. I used my custom class:

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

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

and use it:

并使用它:

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