30

実行中のアプリケーションのインスタンスを1つだけ許可するために、mutexを使用しています。コードを以下に示します。これは正しい方法ですか?コードに欠陥はありますか?

ユーザーが2回目にアプリケーションを開こうとしたときに、すでに実行中のアプリケーションを表示する方法。現在(以下のコードで)、別のインスタンスがすでに実行されているというメッセージを表示しています。

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

        }            
    }
4

7 に答える 7

19

私は一度この方法でそれをしました、私はそれが役立つことを願っています:

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;
}
于 2009-05-04T12:03:39.210 に答える
9
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

于 2009-05-04T12:17:57.193 に答える
3

私はこれを使用します:

    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();
        }
    }    
于 2012-12-27T07:14:03.187 に答える
1

この質問を見てください

この記事へのリンクがあります:ミューテックスの使用法が説明されている誤解されたミューテックス。

于 2009-05-04T12:03:27.790 に答える
1

このページに示されているコードサンプルを確認してください

ctor(bool, string, out bool)つまり、名前付きミューテックスの所有権を取得したかどうかをoutパラメーターで通知するオーバーロードミューテックスを使用します。あなたが最初のインスタンスである場合、ctorが呼び出された後、このout paramにはtrueが含まれます。この場合、通常どおり続行します。このパラメータがfalseの場合は、別のインスタンスがすでに所有権を取得しているか、実行中であることを意味します。この場合、「別のインスタンスはすでに実行中です」というエラーメッセージが表示されます。その後、正常に終了します。

于 2009-05-04T12:08:40.023 に答える
1

タイムアウトとセキュリティ設定でアプリを使用します。カスタムクラスを使用しました:

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");
        }
    }
于 2015-07-28T06:39:20.690 に答える