2013-02-27 22 views
13

Zainstalowałem moją aplikację WinForm C# przy użyciu instalacji ClickOnce. Wszystko działa dobrze (po wielu pracach) :), ale teraz mam do czynienia z problemem:Jak mogę zapobiec uruchamianiu mojej aplikacji wiele razy?

Zawsze, gdy klikam skrót aplikacji w menu Start, rozpoczyna się nowa instancja. Muszę tego uniknąć.

Co mogę zrobić, aby zapobiec wielokrotnym uruchomieniom?

+1

możliwy duplikat [Co to jest dobry wzór użycia globalnego Mutexa w C#?] (Stos http: // przelewowy.com/questions/229565/what-is-a-good-pattern-for-using-a-global-mutex-in-c) –

+1

możliwy duplikat [Zapobieganie wielu instancjom danej aplikacji w .NET?] (http: //stackoverflow.com/questions/93989/prevent-multiple-instances-of-a-given-app-in-net) – joce

Odpowiedz

25

Przy zameldowaniu starcie programu jeśli sam proces jest już uruchomiony:

using System.Diagnostics; 

static void Main(string[] args) 
{ 
    String thisprocessname = Process.GetCurrentProcess().ProcessName; 

    if (Process.GetProcesses().Count(p => p.ProcessName == thisprocessname) > 1) 
     return;   
} 
+1

Myślę, że powinienem to zobaczyć: http://odetocode.com/blogs/scott/archive/2004/08/20/the-misunderstood-mutex.aspx – SubmarineX

19

użyć tego kodu:

[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()); 
    } 
} 

od The Misunderstood Mutex

+0

Używałem innego kodu Mutex niż powyżej, który działał lokalnie, ale gdy zacząłem używać ClickOnce to didn nie działa. Powyższy kod działa dla mnie w ClickOnce – harag

+0

@harag - chętnie Ci pomogę :) Głosuj na odpowiedź proszę, czy było to dla ciebie przydatne – MikroDel

+1

Już się głosowałem :) – harag

1

Uruchamiając ci aplikację, główny zawsze wywołuje Application.Run(). Sprawdź w swojej metodzie STAThread-Main i przed testem Application.Run, czy są uruchomione instancje twojego .exe.

Process p = Process.GetProcesses(); 
//check for your .exe 

Zobacz tutaj: this.

-3

Korzystanie Mutex jest droga, ponieważ zgadywać nazwy procesu jest pełen wad i drobnostek. Sprawdź to naprawdę ładne illustration

+0

dlaczego dajesz taką samą odpowiedź, jak już podano rok przed ? http://stackoverflow.com/a/15115327/502950 – MikroDel

+1

Och, świetna odpowiedź! – user3195836

2

Są czasy, że **Mutex** nie działa w niektórych obszarach. Podobnie jak przy użyciu w aplikacji konsolowej. Próbowałem więc użyć zapytania WMI .

Spróbuj tego i zadziała.

 /// <summary> 
     /// The main entry point for the application. 
     /// </summary> 
     [STAThread] 
     static void Main() 
     { 
      if (!isStillRunning()) 
      { 
       Application.Run(new Form1()); 
      } 
      else { 
       MessageBox.Show("Previous process still running.", 
        "Application Halted", MessageBoxButtons.OK, MessageBoxIcon.Asterisk); 
       Application.Exit(); 
      }  
     } 

     //***Uses WMI Query 
     static bool isStillRunning() { 
      string processName = Process.GetCurrentProcess().MainModule.ModuleName; 
      ManagementObjectSearcher mos = new ManagementObjectSearcher(); 
      mos.Query.QueryString = @"SELECT * FROM Win32_Process WHERE Name = '" + processName + @"'"; 
      if (mos.Get().Count > 1) 
      { 
       return true; 
      } 
      else 
       return false; 
     } 

Mam nadzieję, że to pomaga.

Więcej informacji możesz napisz do mnie tutaj: [email protected], [email protected]

http://israelocbina.blogspot.com

0

co mam zawsze przy użyciu jest

bool checkSingleInstance() 
    { 
     string procName = Process.GetCurrentProcess().ProcessName; 
     // get the list of all processes by that name 

     Process[] processes = Process.GetProcessesByName(procName); 

     if (processes.Length > 1) 
     { 

      return true; 
     } 
     else 
     { 
      return false; 
     } 
    } 
0

rozwiązanie w postaci okien aplikacji Zablokuj ponownie uruchamianie aplikacji (otwórz ponownie aplikację).

1- najpierw dodać klasy RunAlready.cs

2-wywołania metody processIsRunning() z nazwa procesu z RunAlready.cs w Program.cs

Program.cs:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Threading.Tasks; 
using System.Windows.Forms; 

namespace Tirage.MainStand 
{ 
static class Program 
{ 

    /// <summary> 
    /// The main entry point for the application. 
    /// </summary> 
    [STAThread] 
    static void Main() 
    { 
     PublicClass.Class.RunAlready RunAPP = new PublicClass.Class.RunAlready(); 
     string outApp = RunAPP.processIsRunning("Tirage.MainStand"); 

     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     MainStand_FrmLogin fLogin = new MainStand_FrmLogin(); 
     if (outApp.Length == 0) 
     { 

      if (fLogin.ShowDialog() == DialogResult.OK) 
      { 
       Application.Run(new MainStand_masterFrm()); 

      } 
     } 
     else MessageBox.Show("Instance already running"); 

     } 
    } 
} 

klasę RunAlready:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 

namespace PublicClass.Class 
{ 
    public class RunAlready 
    { 
     public string processIsRunning(string process) 
     { 
     string xdescription = ""; 
     System.Diagnostics.Process[] processes = 
      System.Diagnostics.Process.GetProcessesByName(process); 
     foreach (System.Diagnostics.Process proc in processes) 
     { 
      var iddd = System.Diagnostics.Process.GetCurrentProcess().Id; 
      if (proc.Id != System.Diagnostics.Process.GetCurrentProcess().Id) 
      { 
       xdescription = "Application Run At time:" + proc.StartTime.ToString() + System.Environment.NewLine; 
       xdescription += "Current physical memory : " + proc.WorkingSet64.ToString() + System.Environment.NewLine; 
       xdescription += "Total processor time : " + proc.TotalProcessorTime.ToString() + System.Environment.NewLine; 
       xdescription += "Virtual memory size : " +   proc.VirtualMemorySize64.ToString() + System.Environment.NewLine; 
      } 
     } 


     return xdescription; 
    } 
} 
} 
Powiązane problemy