2008-09-18 82 views

回答

118

使用互斥鎖。上面使用GetProcessByName的例子之一有許多警告。下面是關於這個問題的好文章:

http://odetocode.com/Blogs/scott/archive/2004/08/20/401.aspx

[STAThread] 
static void Main() 
{ 
    using(Mutex mutex = new Mutex(false, "Global\\" + appGuid)) 
    { 
     if(!mutex.WaitOne(0, false)) 
     { 
     MessageBox.Show("Instance already running"); 
     return; 
     } 

     Application.Run(new Form1()); 
    } 
} 

private static string appGuid = "c0a76b5a-12ab-45c5-b9d9-d693faa6e7b9"; 
8

Hanselman有a post關於使用WinFormsApplicationBase類從Microsoft.VisualBasic程序集來做到這一點。

+0

我已經使用了幾年,但我現在希望更改爲基於互斥的解決方案。我有客戶報告這個問題,我懷疑它使用Remoting來做到這一點。 – 2009-06-18 08:28:43

1

通常它與一個名爲互斥完成(使用新的mutex(「你的應用程序名」,真正的),並檢查返回值),但也有一定的支撐班Microsoft.VisualBasic程序。 dll即can do it for you

17
if (Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).Length > 1) 
{ 
    AppLog.Write("Application XXXX already running. Only one instance of this application is allowed", AppLog.LogMessageType.Warn); 
    return; 
} 
+1

我認爲應該看到這個:http://odetocode.com/blogs/scott/archive/2004/08/20/the-misunderstood-mutex.aspx – SubmarineX 2014-04-30 08:26:35

+0

@SubmarineX你如何確定這篇文章是正確的?它仍然是互斥之間的爭議和http://www.codeproject.com/Articles/4975/Easily-Create-A-Single-Instance-Application – 2014-07-23 07:48:49

+0

驚人只需完美 感謝您的時間和精力 – 2015-04-20 08:52:19

4

使用Visual Studio 2005或2008年,當你創建一個項目的可執行文件,在「應用程序」面板中的屬性窗口中有一個名爲複選框「做單實例應用程序」,可以激活轉換該應用程序在單個實例應用程序上。

這裏是我正在談論的窗口的捕獲: enter image description here 這是一個Visual Studio 2008的Windows應用程序項目。

+3

我查找了你提到的這個複選框,對於我的C#/ WPF應用程序,並沒有任何。 – HappyNomad 2010-01-05 16:14:41

+3

我沒有在我的VS 2008 C#/ WinForms應用程序的屬性中看到它。 – 2010-09-20 18:25:08

+0

也不在VS2005中。他必須提到舊的VB工作室。 – nawfal 2011-08-24 14:38:22

6

這聽起來像有一些迄今已提出3種基本技術。

  1. 從Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase類派生並將IsSingleInstance屬性設置爲true。 (我相信這裏的一個警告是,這將不適用於WPF應用程序,是嗎?)
  2. 使用一個已命名的互斥鎖並檢查它是否已被創建。
  3. 獲取正在運行的進程的列表並比較進程的名稱。 (這要求您的進程名稱相對於給定用戶計算機上運行的任何其他進程是唯一的。)

我錯過了任何注意事項?

15

以下是您需要確保只有一個實例正在運行的代碼。這是使用命名互斥體的方法。

public class Program 
{ 
    static System.Threading.Mutex singleton = new Mutex(true, "My App Name"); 

    static void Main(string[] args) 
    { 
     if (!singleton.WaitOne(TimeSpan.Zero, true)) 
     { 
      //there is already another instance running! 
      Application.Exit(); 
     } 
    } 
} 
4

使用VB.NET! 編號:真的;)使用Microsoft.VisualBasic.ApplicationServices

;

從VB.Net的WindowsFormsApplicationBase爲您提供了一個「SingleInstace」屬性,這決定了其他情況下,讓只有一個實例運行。

1
[STAThread] 
static void Main()     // args are OK here, of course 
{ 
    bool ok; 
    m = new System.Threading.Mutex(true, "YourNameHere", out ok); 

    if (! ok) 
    { 
     MessageBox.Show("Another instance is already running."); 
     return; 
    } 

    Application.Run(new Form1()); // or whatever was there 

    GC.KeepAlive(m);    // important! 
} 

來源:Ensuring a single instance of .NET Application

和:Single Instance Application Mutex

相同的答案@Smink並與一捻@Imjustpondering:

Jon Skeet's FAQ on C#找出原因GC.KeepAlive重要

2

這是對於VB.Net

代碼
Private Shared Sub Main() 
    Using mutex As New Mutex(False, appGuid) 
     If Not mutex.WaitOne(0, False) Then 
       MessageBox.Show("Instance already running", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error) 
      Return 
     End If 

     Application.Run(New Form1()) 
    End Using 
End Sub 

這是代碼爲C#

private static void Main() 
{ 
    using (Mutex mutex = new Mutex(false, appGuid)) { 
     if (!mutex.WaitOne(0, false)) { 
      MessageBox.Show("Instance already running", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error); 
      return; 
     } 

     Application.Run(new Form1()); 
    } 
} 
1

(注:這是一個有趣的解決方案!它的工作原理,但使用不好的GDI +的設計來實現這一點。)

將圖像與您的應用程序並加載它在啓動時。保持它直到應用程序退出。用戶無法啓動第二個實例。 (當然互斥方案是乾淨多了)

private static Bitmap randomName = new Bitmap("my_image.jpg"); 
5

我在這裏嘗試了所有的解決方案,並沒有在我的C#.net 4.0項目的工作。希望可以幫到這裏有人爲我工作的解決方案:

private static string appGuid = "WRITE AN UNIQUE GUID HERE"; 
private static Mutex mutex; 

當你需要檢查,如果應用程序已經在運行:

bool mutexCreated; 
mutex = new Mutex(true, "Global\\" + appGuid, out mutexCreated); 
if (mutexCreated) 
    mutex.ReleaseMutex(); 

if (!mutexCreated) 
{ 
    //App is already running, close this! 
    Environment.Exit(0); //i used this because its a console app 
} 

我需要關閉

作爲主類變量其他只有一些條件,這對我的目的很好運作

1

這對我純粹的C#工作。 try/catch是在循環過程中可能列表中的一個進程退出的時候。

using System.Diagnostics; 
.... 
[STAThread] 
static void Main() 
{ 
... 
     int procCount = 0; 
     foreach (Process pp in Process.GetProcesses()) 
     { 
      try 
      { 
       if (String.Compare(pp.MainModule.FileName, Application.ExecutablePath, true) == 0) 
       { 
        procCount++;       
        if(procCount > 1) { 
         Application.Exit(); 
         return; 
        } 
       } 
      } 
      catch { } 
     } 
     Application.Run(new Form1()); 
} 
2

在嘗試了多個解決方案後,我問了這個問題。我結束了使用的例子爲WPF這裏:http://www.c-sharpcorner.com/UploadFile/f9f215/how-to-restrict-the-application-to-just-one-instance/

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

    protected override void OnStartup(StartupEventArgs e) 
    { 
     const string appName = "MyAppName"; 
     bool createdNew; 

     _mutex = new Mutex(true, appName, out createdNew); 

     if (!createdNew) 
     { 
      //app is already running! Exiting the application 
      Application.Current.Shutdown(); 
     } 

    }   
} 

在App.xaml中:

x:Class="*YourNameSpace*.App" 
StartupUri="MainWindow.xaml" 
Startup="App_Startup" 
3

1 - 創建程序的參考。CS - >

using System.Diagnostics; 

2 - 投入void Main()作爲代碼的第一行 - >

if (Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).Length >1) 
       return; 

就是這樣。

2

只需使用StreamWriter,這個怎麼樣?

System.IO.File.StreamWriter OpenFlag = null; //globally 

try 
{ 
    OpenFlag = new StreamWriter(Path.GetTempPath() + "OpenedIfRunning"); 
} 
catch (System.IO.IOException) //file in use 
{ 
    Environment.Exit(0); 
} 
0

一定限制應用程序的單一實例時要考慮安全性:

爲文章全文: https://blogs.msdn.microsoft.com/oldnewthing/20060620-13/?p=30813

我們使用一個名爲互斥用一個固定的名字來檢測 是否有另一個副本o f程序正在運行。但這也意味着攻擊者可以先創建互斥鎖,從而阻止我們的程序 運行!我怎樣才能防止這種類型的拒絕服務攻擊 ?

...

如果攻擊者在作爲 程序相同的安全上下文中運行的(或將要)在運行,那麼就沒有什麼可以做。 無論您想要確定您的程序的另一個副本 是否正在運行,「攻擊者」都可以模仿它。 由於它在正確的安全上下文中運行,因此它可以執行任何「真實」程序可以執行的操作。

...

顯然你不能保護自己的 相同的安全權限運行攻擊者,但你仍然可以保護自己免受 無特權的攻擊者在其它的安全權限運行。

嘗試在你的互斥量設置DACL,這裏的.NET方式: https://msdn.microsoft.com/en-us/library/system.security.accesscontrol.mutexsecurity(v=vs.110).aspx