728x90
자료출처 : http://blog.naver.com/ansysda

동일한 프로그램을 한번만 실행할 수 있도록 합니다.

static void Main()
{
   System.Diagnostics.Process[] myProc = System.Diagnostics.Process.GetProcessesByName("WindowsApplication10");  
   // 여기서 Mulpumi는 프로젝트 속성의 프로젝트 이름
           
   if(myProc.Length < 2)
   {
       Application.Run(new Form1());        
   }
   else
   {
       MessageBox.Show("이미 실행중입니다.");
       Application.Exit();      
   }
}

또 다른 방법

프로세스간 동기화 개체인Mutex 클래스를 이용하면 현재의 프로세스가 최초 실행된 프로세스인지를 판별할 수 있습니다. Mutex 객체를 생성시 초기 소유권을 부여 하도록 하며 3번째 아웃풋 파라미터의 값으로 소유권이 부여되었는지를 판단합니다. 메인 메서드에 대한 소스는 아래와 같습니다.

/// <summary>

/// 해당 응용 프로그램의 주 진입점입니다.

/// </summary>

[STAThread]

static void Main()

{

      bool createdNew;

      Mutex mutex = new Mutex(true, Application.ProductName, out createdNew);

      if (createdNew)

      {

              Application.Run( new Form1());

      }

}

프로그램을 실행할 때 이미 실행되어 있는 프로그램이면 활성화를 시켜주어야 할 때가 있습니다. 해당 프로세스의 윈도우를 활성화시켜주는 방법이 닷넷 프레임워크에는 존재하지 않습니다. Win32 API 함수를 플랫폼 호출하여야 합니다. 아래의 소스처럼 inner class로 만듭니다.

internal class NativeMethods

{

      /// <summary>

      /// The SetForegroundWindow function puts the thread that created the specified window

      /// into the foreground and activates the window. Keyboard input is directed to the window,

      /// and various visual cues are changed for the user. The system assigns a slightly higher

      /// priority to the thread that created the foreground window than it does to other threads.

      /// </summary>

      [DllImport("user32.dll")]

      internal static extern

              bool SetForegroundWindow(IntPtr hWnd);

      /// <summary>

      /// The ShowWindowAsync function sets the show state of a window created by a different thread.

      /// </summary>

      [DllImport("user32.dll")]

      internal static extern

              bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);

      /// <summary>

      /// The IsIconic function determines whether the specified window is minimized (iconic).

      /// </summary>

      [DllImport("user32.dll")]

      internal static extern

              bool IsIconic(IntPtr hWnd);

      // Activates and displays the window. If the window is minimized or maximized, the system

      // restores it to its original size and position. An application should specify this flag

      // when restoring a minimized window.

      internal static int SW_RESTORE = 9;

}

메인 메서드를 아래와 같이 수정합니다. 두 번째 인스턴스가 실행되는 시점에서 해당 프로그램 명에 대한 프로세스는 2개가 있으며, 그 중 현재의 프로세스 아이디와 같지 않은 프로세스가 최초 실행된 프로세스입니다. 그 프로세스가 아이콘화(최소화) 되어 있는지를 검사(IsIconic 메서드)해서 아이콘화 되어 있으면 비동기로 해당 윈도우를 활성화(ShowWindowAsync 메서드)시켜야 합니다. 그리고 z order의 맨 앞으로 보내도록(SetForegroundWindow 메서드) 합니다.

/// <summary>

/// 해당 응용 프로그램의 주 진입점입니다.

/// </summary>

[STAThread]

static void Main()

{

      bool createdNew;

      Mutex mutex = new Mutex(true, Application.ProductName, out createdNew);

      if (createdNew)

      {

              Application.Run( new Form1());

      }

      else

      {

              Process[] viewProcesses =

                      Process.GetProcessesByName(Application.ProductName);

              if (viewProcesses != null && viewProcesses.Length == 2)

              {

                      Process view = viewProcesses[0].Id == Process.GetCurrentProcess().Id ?

                            viewProcesses[1] : viewProcesses[0];

                      IntPtr hWnd = view.MainWindowHandle;

                      if (NativeMethods.IsIconic(hWnd))

                      {

                            NativeMethods.ShowWindowAsync(hWnd, NativeMethods.SW_RESTORE);

                      }

                      NativeMethods.SetForegroundWindow(hWnd);

              }

      }

}

이상으로 Mutex 클래스와 Process 클래스, 그리고 몇몇 API 함수를 이용해서 하나의 인스턴스만 실행되도록 하고 두 번째 실행 시에는 해당 프로그램이 활성화되도록 하는 방법을 살펴보았습니다.

- taihikim


+ Recent posts