2011-01-11 9 views
0

別のアプリケーションのウィンドウが表示されている場合は、そのウィンドウを表示します。具体的には、ユーザーがもう一度起動しようとすると、既に起動されているアプリケーションのメインウィンドウを表示する必要があります。私は既にアプリケーションの起動を重複して監視しています。 hereのようにしようとしましたが失敗しました。リモーティングを使用することを考えていますが、この場合はWindows APIを気にする必要はありませんが、これはベストプラクティスではないことを理解しています。別のフォームを表示

+0

実際に_your_ applicationをシングルインスタンスにしたいのですか?もしそうなら、すでにStackOverflowに関するよくある質問がたくさんあります。 – Reddog

+0

.NETで既にサポートされています:http://social.msdn.microsoft.com/forums/en-US/winforms/thread/7c6e0d56-d942 -46f5-b27a-d627e60eebbe/ –

+0

クール、リンクありがとう! –

答えて

0

私はすでにremotingを使用して実装していますが、空き時間が増えるとこれを行う他の方法も検討します。ここで私はそれをやった方法は次のとおりです。私たちが持っているフォームクラスで :

 public Main() 
    { 
     InitializeComponent();    
     this.ShowFromFormShower = new FormShower.ShowFromFormShowerDelegate(this.ShowFromFormShower1); 
     FormShower.Register(this); 
    } 

    private void ShowFromFormShower1() 
    {    
     this.Show(); 
     this.WindowState = FormWindowState.Normal; 
     this.BringToFront();    
    } 
    public PKW.FormShower.ShowFromFormShowerDelegate ShowFromFormShower; 

また、リモートクラスを作成する必要があります

だから、
public class FormShower : MarshalByRefObject 
{  
    /// <summary> 
    /// For remote calls. 
    /// </summary> 
    public void Show() 
    { 
     if (FormShower.m == null) 
      throw new ApplicationException("Could not use remoting to show Main form because the reference is not set in the FormShower class."); 
     else 
      FormShower.m.Invoke(FormShower.m.ShowFromFormShower); 
    } 
    private const int PortNumber = 12312; 
    private static Main m = null; 
    public delegate void ShowFromFormShowerDelegate(); 
    internal static void Register(Main m) 
    { 
     if (m == null) throw new ArgumentNullException("m"); 
     FormShower.m = m; 
     ChannelServices.RegisterChannel(new TcpChannel(FormShower.PortNumber), false);    
     RemotingConfiguration.RegisterActivatedServiceType(typeof(FormShower)); 
    } 
    internal static void CallShow() 
    { 
     TcpClientChannel c = new TcpClientChannel(); 
     ChannelServices.RegisterChannel(c, false); 
     RemotingConfiguration.RegisterActivatedClientType(typeof(FormShower), "tcp://localhost:"+PortNumber.ToString()); 
     FormShower fs = new FormShower(); 
     fs.Show(); 
    } 
} 

ユーザーがアプリケーションをもう一度起動しようとすると、アプリケーションがFormShower.CallShowメソッドを起動します。

0

これはかなりハックされた方法です。私はあなたのアプリの最初のコピーを通知するために名前付きパイプ(System.IO.Pipes)を使用することをお勧めします。最初のコピーは、信号を受信すると、ウィンドウ自体をアクティブにします。また、アクセス許可の心配もありません。

0

もう1つの簡単な方法は、.NETでSystem.Threading.EventWaitHandleクラスとして表されるWindowsイベントを使用することです。

アプリケーション内にスレッドを作成します。名前付きイベントを待つだけです。イベントが通知されると、このスレッドはForm.BeginInvokeを使用してメインウィンドウを表示し、イベントで待機するように戻ります。

アプリケーションの新しいインスタンスから、イベントを通知するだけで済みます。

これは、パイプを使用するより少し少ない作業を必要とします。

いずれの方法(パイプ、ウィンドウ、またはイベントを使用して)でも、常にアクセス権を処理する必要があることに注意してください。

たとえば、UACが有効で、既存のアプリケーションインスタンスが管理者として実行されている場合、適切なアクセス許可を設定しない限り、新しいインスタンスがウィンドウを表示するメッセージを送信できないことがあります。あなたの方法が何であれ、パイプやイベントに)事前に

関連する問題