2009. 3. 31. 15:20
WPF, Silverlight
프로그램이 중복 실행되는 것을 막는 가장 일반적인 방법은 Mutex를 사용하여 프로세스를 확인하는 방법입니다.
C#에서 사용되는 방법은 msdn에도 Mutex의 예제로 아래와 같이 나와 있습니다.
msdn에 나온 Mutex의 기본 사용법을 보시고 싶으신 분은 아래 소스를 펼쳐 보시면 됩니다.
C#에서 사용되는 방법은 msdn에도 Mutex의 예제로 아래와 같이 나와 있습니다.
msdn에 나온 Mutex의 기본 사용법을 보시고 싶으신 분은 아래 소스를 펼쳐 보시면 됩니다.
01.// This example shows how a named mutex is used to signal between
02.// processes or threads.
03.// Run this program from two (or more) command windows. Each process
04.// creates a Mutex object that represents the named mutex "MyMutex".
05.// The named mutex is a system object whose lifetime is bounded by the
06.// lifetimes of the Mutex objects that represent it. The named mutex
07.// is created when the first process creates its local Mutex; in this
08.// example, the named mutex is owned by the first process. The named
09.// mutex is destroyed when all the Mutex objects that represent it
10.// have been released.
11.// The second process (and any subsequent process) waits for earlier
12.// processes to release the named mutex.
13.using System;
14.using System.Threading;
15.public class Test
16.{
17. public static void Main()
18. {
19. // Set this variable to false if you do not want to request
20. // initial ownership of the named mutex.
21. bool requestInitialOwnership = true;
22. bool mutexWasCreated;
23. // Request initial ownership of the named mutex by passing
24. // true for the first parameter. Only one system object named
25. // "MyMutex" can exist; the local Mutex object represents
26. // this system object. If "MyMutex" is created by this call,
27. // then mutexWasCreated contains true; otherwise, it contains
28. // false.
29. Mutex m = new Mutex(requestInitialOwnership,
30. "MyMutex",
31. out mutexWasCreated);
32. // This thread owns the mutex only if it both requested
33. // initial ownership and created the named mutex. Otherwise,
34. // it can request the named mutex by calling WaitOne.
35. if (!(requestInitialOwnership && mutexWasCreated))
36. {
37. Console.WriteLine("Waiting for the named mutex.");
38. m.WaitOne();
39. }
40. // Once the process has gained control of the named mutex,
41. // hold onto it until the user presses ENTER.
42. Console.WriteLine("This process owns the named mutex. " +
43. "Press ENTER to release the mutex and exit.");
44. Console.ReadLine();
45. // Call ReleaseMutex to allow other threads to gain control
46. // of the named mutex. If you keep a reference to the local
47. // Mutex, you can call WaitOne to request control of the
48. // named mutex.
49. m.ReleaseMutex();
50. }
51.}
하지만 WPF에서 위에 방법을 App.xaml.cs 에 적용시켜도 원하는 데로 동작하지 않습니다.
그래서 오늘은 WPF에서 사용할 수 있는 방법을 올려드리겠습니다.
아래 예제는 뮤텍스를 사용한 중복 방지 소스를 구글링해서 힘들게 찾은 소스입니다.
제가 잘 동작하는 것은 확인 하였습니다. 이 밖에 다른 예제 소스도 보여드리겠습니다만 아래 예제를 쓰시는 것이 가장 좋습니다.
01.using System;
02.using System.Threading;
03.using System.Windows;
04.namespace WpfKorea
05.{
06. /// <summary>
07. /// Interaction logic for App.xaml
08. /// </summary>
09. public partial class App : Application
10. {
11. Mutex mutex = null;
12. protected override void OnStartup(StartupEventArgs e)
13. {
14. string mutexName = "wpfkorea.com";
15. try
16. {
17. mutex = new Mutex(false, mutexName);
18. }
19. catch (Exception ex)
20. {
21. MessageBox.Show( ex.Message + "\n\n" + ex.StackTrace + "\n\n" + "Application Exiting…", "Exception thrown");
22. Application.Current.Shutdown();
23. }
24. if (mutex.WaitOne(0, false))
25. {
26. base.OnStartup(e);
27. }
28. else
29. {
30. MessageBox.Show("Application already startet.", "Error", MessageBoxButton.OK, MessageBoxImage.Information);
31. Application.Current.Shutdown();
32. }
33. }
34. }
35.}
02.using System.Threading;
03.using System.Windows;
04.namespace WpfKorea
05.{
06. /// <summary>
07. /// Interaction logic for App.xaml
08. /// </summary>
09. public partial class App : Application
10. {
11. Mutex mutex = null;
12. protected override void OnStartup(StartupEventArgs e)
13. {
14. string mutexName = "wpfkorea.com";
15. try
16. {
17. mutex = new Mutex(false, mutexName);
18. }
19. catch (Exception ex)
20. {
21. MessageBox.Show( ex.Message + "\n\n" + ex.StackTrace + "\n\n" + "Application Exiting…", "Exception thrown");
22. Application.Current.Shutdown();
23. }
24. if (mutex.WaitOne(0, false))
25. {
26. base.OnStartup(e);
27. }
28. else
29. {
30. MessageBox.Show("Application already startet.", "Error", MessageBoxButton.OK, MessageBoxImage.Information);
31. Application.Current.Shutdown();
32. }
33. }
34. }
35.}
위에 예제는 OnStartUp이벤트와 Mutex의 WaitOne을 이용하여 중복방지를 구현하였습니다.
그럼 이번에는 약간 다른 방법으로 구현해 보겠습니다.
이 방법은 WPF 초기화를 C# 코드로 직접 구현하는 방식입니다.
01.private static bool isNew;
02.[System.STAThreadAttribute()]
03.public static void Main()
04.{
05. using (Mutex m = new Mutex(true, "ThisIsTheStringMutexValueThatMustBeUnique", out isNew))
06. {
07. if (isNew)
08. {
09. MyWPFApplication.App app = new MyWPFApplication.App();
10. app.InitializeComponent();
11. app.Run();
12. }
13. else
14. {
15. MessageBox.Show("MyWPFApplication is already running!", "MyWPFApplication", MessageBoxButton.OK, MessageBoxImage.Information, MessageBoxResult.OK);
16. }
17. }
18.}
02.[System.STAThreadAttribute()]
03.public static void Main()
04.{
05. using (Mutex m = new Mutex(true, "ThisIsTheStringMutexValueThatMustBeUnique", out isNew))
06. {
07. if (isNew)
08. {
09. MyWPFApplication.App app = new MyWPFApplication.App();
10. app.InitializeComponent();
11. app.Run();
12. }
13. else
14. {
15. MessageBox.Show("MyWPFApplication is already running!", "MyWPFApplication", MessageBoxButton.OK, MessageBoxImage.Information, MessageBoxResult.OK);
16. }
17. }
18.}
이 방법을 사용하면 App.xaml의 Build Action 속성을 ApplicationDefinition 에서 Page로 변경해 주어야 합니다.
WPF가 구성해주는 진입점을 직접 작성하셔야 하므로 여러가지로 귀찮은 일이 생길 수 있을 거 같습니다.
마지막으로 소개해 드릴 방법은 프로세서의 네임 중복을 체크하는 방법입니다.
이 방법은 잘 동작하지만 실행파일의 이름을 바꾸기만 해도 쉽게 중복 실행이 가능해 집니다.
이런 방법들을 사용하시면 WPF에서 중복방지를 구현하실수 있습니다.
길게 읽지 않으시고 첫번째 소개해 드린 방법을 사용하시면 됩니다.
나머지는 참고만 하셔도 될 것 같습니다.
출처 : http://wpfkorea.com/?document_srl=3047#0

