2009-03-30 14 views
4

私はその時点で1つのインスタンスしか実行できないようにするWindows Formsアプリケーションを持っています。私はMutexを使ってSingletonを実装しました。アプリケーションは、コマンドラインから起動可能でなければなりません(パラメータあり/なし)。アプリケーションはスクリプトによって開始および終了されます。ユーザーはそれに対して何も行動できません。シングルインスタンスのWindowsフォームアプリケーションとその参照を取得する方法?

したがって、アプリケーションの目的は、単純な "インジケータ"アプリケーションであり、エンドユーザーのためのいくつかの視覚的およびグラフィカルな情報を表示するだけです。エンドユーザーは何もすることはできません、それを見てください。それは、視覚的でグラフィカルな外観が比較的容易に実行できるため(これは最上位、ボーダレスなど)、Windowsフォームアプリケーションです。

簡単に言えば、 exitコマンドラインパラメータを使用して同じアプリケーションを実行しようとすると、現在実行中のアプリケーションを終了するにはどうすればよいですか?

bool quit = (args.Length > 0 && args[0] == "quit") ? true : false; 
using (Mutex mutex = new Mutex(false, sExeName)) 
{ 
    if (!mutex.WaitOne(0, true)) 
    { 
     if (quit) 
     { 
      // This is the tricky part? 
      // How can I get reference to "previous" launced 
      // Windows Forms application and call it's Exit() method. 
     } 
    } 
    else 
    { 
     if (!quit) 
     { 
      Application.EnableVisualStyles(); 
      Application.SetCompatibleTextRenderingDefault(false); 
      Application.Run(new Form1()); 
     } 
    } 
} 

答えて

6

.NETフレームワークは、このための非常に良い汎用ソリューションを提供します。このMSDN magazine articleの下部を確認してください。 StartupNextInstanceHandler()イベントハンドラを使用して、実行中のインスタンスに任意のコマンド(「quit」など)を渡します。

+1

Microsoftは別のリンクを破壊しました。彼らはこれまでに学ぶだろうか? –

+1

https://blogs.msdn.microsoft.com/tyler_whitney/2005/11/28/single-instance-applications-and-c/ –

+0

これは 'Microsoft.VisualBasic'なしで行うことができますか? –

5

これは複雑なことではありませんか?既存のインスタンスを閉じて新しいインスタンスを開始するのではなく、既存のインスタンスを再アクティブ化できるだけではありませんか?いずれの方法でも、以下のコードを丸めると、どうやったらどうなるかについてのアイデアが得られるはずです...?

[STAThread] 
static void Main() 
{ 
    var me = Process.GetCurrentProcess(); 
    var otherMe = Process.GetProcessesByName(me.ProcessName).Where(p => p.Id != me.Id).FirstOrDefault(); 

    if (otherMe != null) 
    { 
     otherMe.Kill(); 
    } 
    else 
    { 
     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     Application.Run(new Form1()); 
    } 
} 

アプリのインスタンスである場合:これは、おそらくリファインしたいやや迅速かつ汚いソリューションです。このhere

+0

を参照してくださいだと思います! Inside 'if(otherProcess!= null)'を入れました: 'MessageBox.Show( "Application already running!"); thisProcess.Kill(); 'ありがとうございました –

1

について別の質問があり

Process thisProcess = Process.GetCurrentProcess(); 
     Process[] allProcesses = Process.GetProcessesByName(thisProcess.ProcessName); 
     Process otherProcess = null; 
     foreach (Process p in allProcesses) 
     { 
      if ((p.Id != thisProcess.Id) && (p.MainModule.FileName == thisProcess.MainModule.FileName)) 
      { 
       otherProcess = p; 
       break; 
      } 
     } 

     if (otherProcess != null) 
     { 
      //note IntPtr expected by API calls. 
      IntPtr hWnd = otherProcess.MainWindowHandle; 
      //restore if minimized 
      ShowWindow(hWnd ,1); 
      //bring to the front 
      SetForegroundWindow (hWnd); 
     } 
     else 
     { 
      //run your app here 
     } 

すでに開始されている場合、そのプロセスは強制終了されます。それ以外の場合、アプリは正常に開始します。

関連する問題