2011-01-11 4 views
0

숨겨진 다른 응용 프로그램의 창을 표시하려고합니다. 더 구체적으로, 사용자가 다시 시작하려고하면 이미 시작된 응용 프로그램의 기본 창을 표시하려고합니다. 중복 된 응용 프로그램 시작에 대한 모니터링을 이미 구현했습니다. here와 같이하려고했으나 실패했습니다. remoting을 사용하여이를 수행한다고 생각하지만,이 경우 Windows API에 신경 쓸 필요는 없지만 이것이 최선의 방법은 아니라는 점을 이해합니다.다른 양식 표시

+0

실제로 _your_ 응용 프로그램이 단일 인스턴스가되기를 원하십니까? 그렇다면 이미 StackOverflow에 대한 비슷한 질문이 많이 있습니다. – Reddog

+0

.NET에서 이미 지원 : http://social.msdn.microsoft.com/forums/en-US/winforms/thread/7c6e0d56-d942 -46f5-b27a-d627e60eebbe/ –

+0

쿨, 링크 고마워! –

답변

0

나는 이미 리모팅을 사용하여 구현했지만 더 많은 자유 시간을 가질 때 다른 방법을 고려할 것이다. 여기에 내가했던 방법은 다음과 같습니다 폼 클래스에서 을 우리는 가지고 :

 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

또 다른 쉬운 방법은 .NET에서 System.Threading.EventWaitHandle 클래스로 표시되는 Windows 이벤트를 사용하는 것입니다.

응용 프로그램에서 스레드를 만들면 명명 된 이벤트를 기다리는 것입니다. 이벤트가 신호를 받으면이 스레드는 Form.BeginInvoke을 사용하여 기본 창이 나타나도록하고 다시 이벤트 대기를합니다.

응용 프로그램의 새 인스턴스에서 이벤트를 신호로 보내면됩니다.

파이프를 사용하는 것보다 약간의 작업이 필요합니다.

파이프, 창 또는 이벤트를 사용하여 항상 두 가지 방법으로 권한을 처리해야합니다.

예를 들어, UAC가 활성화되어 있고 기존 응용 프로그램 인스턴스가 admin으로 실행중인 경우 적절한 사용 권한을 설정하지 않은 경우 새 인스턴스에서 해당 창을 표시하라는 메시지를 보낼 수 없습니다 (예 : 당신의 방법이 무엇이든 상관없이 파이프 나 이벤트에서).