質問
実行中のアプリケーションの単一インスタンスのみを許可するために、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");
}
}
解決
一度この方法でやったので、それが役に立つことを願っています:
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;
}
他のヒント
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
これを使用します:
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();
}
}
この記事へのリンクがあります:誤解されたミューテックスミューテックスの使用法について説明しています。
このページ に記載されているコードサンプルをご覧ください。 p>
要するに、オーバーロードMutex ctor(bool、string、out bool)
を使用して、名前付きMutexの所有権を取得しているかどうかをoutパラメーターで通知します。あなたが最初のインスタンスである場合、このoutパラメータには、ctorが呼び出された後にtrueが含まれます。この場合、通常どおり続行します。このパラメーターがfalseの場合、別のインスタンスが既に所有権を取得している/実行中であることを意味します。この場合、エラーメッセージ「別のインスタンスが既に実行中です」を表示します。その後、正常に終了します。
タイムアウトとセキュリティ設定でアプリを使用します。カスタムクラスを使用しました:
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");
}
}
所属していません StackOverflow