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