2011-03-21 68 views
14

我試圖使用互斥體方法僅允許我的應用程序的一個實例運行。那就是 - 我只需要一臺機器上所有用戶的最多一個實例。我已閱讀了有關此問題的其他各種線索,並且解決方案似乎很直接,但在測試中我無法讓第二個實例無法運行。這裏是我的代碼...單個應用程序實例不工作的WPF互斥體

public partial class App : Application 
{ 
    protected override void OnStartup(StartupEventArgs e) 
    { 
     // check that there is only one instance of the control panel running... 
     bool createdNew = true; 
     using (Mutex instanceMutex = new Mutex(true, @"Global\ControlPanel", out createdNew)) 
     { 
      if (!createdNew) 
      { 
       Application.Current.Shutdown(); 
       return; 
      } 
     } 

     base.OnStartup(e); 
    } 
} 

回答

29

你也配置在同一方法的互斥體,所以互斥只活的方法的持續時間。將互斥鎖存儲在靜態字段中,並在應用程序的持續時間內保持活動狀態。

+0

+1。雅打敗了我;) – 2011-03-21 10:27:57

+2

謝謝@威廉範Rumpt(和@OJ)。這樣可行。我錯誤地認爲互斥體真的是幕後的事情,更多的是在系統層面,而互斥對象實例並不重要。我已經在下面包括了我的新代碼以供將來參考... – flobadob 2011-03-21 11:11:28

+0

@OJ:很高興能夠在「獲勝」方面進行更改:) – 2011-03-21 11:14:12

4

您在創建並測試它之後立即銷燬互斥鎖​​。您需要保持Mutex引用在應用程序的整個生命週期中保持活動狀態。

使互斥鎖成爲您的應用程序類的成員/字段。 應用程序關閉時釋放互斥鎖。

25

這是我擁有的@Willem麪包車Rumpt(和@OJ)給出了答案新代碼...

public partial class App : Application 
{ 
    private Mutex _instanceMutex = null; 

    protected override void OnStartup(StartupEventArgs e) 
    { 
     // check that there is only one instance of the control panel running... 
     bool createdNew; 
     _instanceMutex = new Mutex(true, @"Global\ControlPanel", out createdNew); 
     if (!createdNew) 
     { 
      _instanceMutex = null; 
      Application.Current.Shutdown(); 
      return; 
     } 

     base.OnStartup(e); 
    } 

    protected override void OnExit(ExitEventArgs e) 
    {   
     if(_instanceMutex != null) 
      _instanceMutex.ReleaseMutex(); 
     base.OnExit(e); 
    } 
} 
1

我可以提出一個更清潔的方式也引入重寫的有用的概念WPF應用程序中的主要方法。另外,如果使用你的解決方案來看看任務管理器,你會注意到新實例實際上達到了執行狀態(你可以在任務列表中看到一個新的進程),然後突然關閉。以下文章中提出的方法也可以避免這種缺陷。 http://blog.clauskonrad.net/2011/04/wpf-how-to-make-your-application-single.html

0

我這樣做,從這個鏈接只是增加給定類和一行在你App.Xaml.cs http://wpfsingleinstance.codeplex.com/

public partial class App : Application  
{ 
    protected override void OnStartup(StartupEventArgs e) 
    { 
     WpfSingleInstance.Make(); //added this is the function of that class 
     base.OnStartup(e); 
    } 
} 
1

我被告知要落實已經開發WPF這種互斥方法我們擁有的應用程序。周圍的工作的問題與使用OnStart()的覆蓋,我發現在

App.g.cs 

該文件位於

obj\x86\debug\ 

,幷包含main()功能,所以你只要簡單地把這塊代碼在你的主要功能。

bool isOnlyInstance = false; 
Mutex m = new Mutex(true, @"WpfSingleInstanceApplication", out isOnlyInstance); 
if (!isOnlyInstance) 
{ 
    MessageBox.Show("Another Instance of the application is already running.", 
        "Alert", 
        MessageBoxButton.OK, 
        MessageBoxImage.Exclamation); 
    return; 
} 
GC.KeepAlive(m); 

但對於這一點,你需要你的App.xaml集的BUILD ACTION保持到ApplicationDefinition

注意:這可能不是最好的辦法,因爲我是一個初學者。 (請告訴我,如果有什麼東西我應該改變)

2

由於擴展樣本:

public static class Extension 
{ 
    private static Mutex mutex; 

    public static bool IsOneTimeLaunch(this Application application, string uniqueName = null) 
    { 
     var applicationName = Path.GetFileName(Assembly.GetEntryAssembly().GetName().Name); 
     uniqueName = uniqueName ?? string.Format("{0}_{1}_{2}", 
      Environment.MachineName, 
      Environment.UserName, 
      applicationName); 

     application.Exit += (sender, e) => mutex.Dispose(); 
     bool isOneTimeLaunch; 
     mutex = new Mutex(true, uniqueName, out isOneTimeLaunch); 
     return isOneTimeLaunch; 
    } 
} 

App類:

protected override void OnStartup(StartupEventArgs e) 
    { 
     if (this.IsOneTimeLaunch()) 
     { 
      base.OnStartup(e); 
     } 
     else 
     { 
      this.Shutdown(); 
     } 
    } 
+0

對於每位用戶的uniqueName +1。 – slavoo 2014-11-12 17:05:32

相關問題