2012-02-26 8 views
0

ミューテックスを使用して自分のプログラムの1つのインスタンスを強制するときに問題があります。ミューテックスを使用して強制的に1つのインスタンスを再起動するアプリケーション

私はウェブブラウザーコントロールを備えたwinformアプリケーションです。特定の条件が満たされていれば自動再スタートする必要があります。

私の問題は、アプリケーションを再起動すると、mutexは新しいインスタンスを開くことができます(これはいつも起こるとは限りません)。ブラウザにnavigateのような非同期メソッドがある可能性があります。

しかし、私はExitアプリケーションイベントでMutexをリリースします。

これは私のコードです:

static Mutex _mutex = new Mutex (false, "myprogramkey"); 

    [STAThread] 
    private static void Main() 
    { 
     Application.ApplicationExit += new EventHandler(Application_ApplicationExit); 
     if(_mutex.WaitOne(TimeSpan.FromSeconds(5), true)) 
     { 
      Application.EnableVisualStyles(); 
      Application.SetCompatibleTextRenderingDefault(false); 
      Application.Run(new RevolutionForm()); 
     } 

    else 
     { 
      MessageBox.Show("Error!"); 
     } 
    } 
     static void Application_ApplicationExit(object sender, EventArgs e) 
    { 
     _mutex.ReleaseMutex(); 
    } 

答えて

3

単一インスタンスのアプリケーションは、フレームワークで十分サポートされています。これは、オンザフライでの無効化、ここで必要なもの、別のインスタンスが開始されたときの通知の取得などの機能をサポートします。あなたは最初のインスタンスにフォーカスを当てるためにそれを使いたいでしょう。 Program.csコードを次のように書き直してください。

using System; 
using System.Windows.Forms; 
using Microsoft.VisualBasic.ApplicationServices; // NOTE: add reference to Microsoft.VisualBasic 

namespace WindowsFormsApplication1 { 
    class Program : WindowsFormsApplicationBase { 
     public Program() { 
      EnableVisualStyles = true; 
      MainForm = new Form1(); 
      IsSingleInstance = true; 
     } 
     public static void Main(string[] args) { 
      Instance = new Program(); 
      Instance.Run(args); 
     } 
     protected override void OnStartupNextInstance(StartupNextInstanceEventArgs eventArgs) { 
      // Nicety, focus the single instance. 
      Instance.MainForm.Activate(); 
     } 
     public static void Restart() { 
      // What you asked for. Use Program.Restart() in your code 
      Instance.IsSingleInstance = false; 
      Application.Restart(); 
     } 
     private static Program Instance; 
    } 
} 
+0

ありがとうございました! – user1107078

+0

こんにちは@Hans私はOPと同じ問題に直面しますが、私の場合、私の単一のインスタンスは 'ApplicationContext'から継承していますので、' Form'ではありません。 – meda

+0

質問ボタンをクリックする必要があります。 –

0

は、ミューテックスを管理するためのtry..finallyを使用してみてください。

私は通常、この方法を使用します。 Application.Restart()と組み合わせてうまく働いた。

private const string ApplicationMutexName = "<myprogramkey>"; 

    /// <summary> 
    /// The main entry point for the application. 
    /// </summary> 
    [STAThread] 
    public static void Main() 
    { 
     RunApplicationPreservingSingleInstance(); 
    } 

    private static void RunApplicationPreservingSingleInstance() 
    { 
     Mutex mutex = AcquireMutex(); 
     if (mutex == null) 
     { 
      return; 
     } 

     try 
     { 
      RunApplication(); 
     } 
     finally 
     { 
      mutex.ReleaseMutex(); 
     } 
    } 

    private static Mutex AcquireMutex() 
    { 
     Mutex appGlobalMutex = new Mutex(false, ApplicationMutexName); 
     if (!appGlobalMutex.WaitOne(3000)) 
     { 
      return null; 
     } 
     return appGlobalMutex; 
    } 

    private static void RunApplication() 
    { 
     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     Application.Run(new MainForm()); 
    } 
0

私はまさにあなたのケースで問題が発生したかわからないんだけど、いくつかの問題があるかもしれない:

あなたはおそらくで適切なクリーンアップの変化
  • を最大化するために、ミューテックスを閉じるためにtry finallyを使用する必要があります
    • 大文字小文字のクリーンアップに失敗した場合、Mutex.WaitOnetrueの代わりにAbandonedMutexExceptionです。この場合、あなたのコードはエラーボックスと共に終了し、そのまま続行できます。
    • あなたはミューテックスに5秒を与えています。シャットダウンが5秒以上かかると、次回の起動に失敗します。より良い選択肢は、シャットダウンを開始する前にmutexを解放することです。 (もちろん、Mutexはユーザーの便宜のためにのみ提供されています)。

    次の例では、アプリケーションを再起動するProgram.Restartを使用する必要があります。それ以外の場合は、時間窓がまだ問題になる可能性があります。

    static class Program 
    { 
        private static Mutex _mutex; 
    
        [STAThread] 
        static void Main() 
        { 
         _mutex = new Mutex(false, "myprogramkey"); 
         try 
         { 
          try 
          { 
           if (!_mutex.WaitOne(1)) 
           { 
            _mutex.Dispose(); 
            _mutex = null; 
            MessageBox.Show("Error!"); 
            return; 
           } 
          } 
          catch (AbandonedMutexException) { /* Mutex wasn't property released last time.*/ } 
    
          Application.EnableVisualStyles(); 
          Application.SetCompatibleTextRenderingDefault(false); 
          Application.Run(new Form1()); 
         } 
         finally 
         { 
          if (_mutex != null) 
          { 
           _mutex.ReleaseMutex(); 
           _mutex.Dispose(); 
          } 
         } 
        } 
    
        public static void Restart() 
        { 
         if (_mutex != null) 
         { 
          _mutex.ReleaseMutex(); 
          _mutex.Dispose(); 
          _mutex = null; 
          Application.Restart(); 
         } 
        } 
    } 
    
  • 関連する問題