2010-08-23 2 views
6

Я написал программу в C# Теперь я хотел бы знать, что является правильным способом предотвратить запуск программы, если она уже запущена?препятствовать запуску приложения C# из нескольких экземпляров

так что если он уже запущен и дважды щелкните по нему, он не запустится, поскольку он уже запущен.

Я могу это сделать, но я думал о стандартном и правильном пути.

+1

Дубликат http://stackoverflow.com/questions/3211529/net-4-single-application-instance –

ответ

10

Рекомендуемый способ сделать это с помощью системы взаимной блокировки.

bool createdNew; 
using(var mutex = new System.Threading.Mutex(true, "MyAppName", out createdNew)) 
{ 
    if (createdNew) 
     // first instance 
     Application.Run(); 
    else 
     MessageBox.Show("There is already an instace running"); 
} 

Первый параметр мьютекс CTOR говорит это, чтобы дать создать общесистемный семафор для этого потока. Если Mutex уже существует, он возвращает false через третий параметр.

Обновление
Куда это положить? Я бы поместил это в program.cs. Если вы поместите его в form_load, вам нужно сохранить мьютекс на время жизни приложения (иметь мьютекс в качестве члена в форме) и вручную отпустить его в форме разгрузки.
Чем раньше вы это называете, тем лучше, прежде чем другое приложение откроет соединения с БД и т. Д. И до того, как будут созданы ресурсы для форм/контролей и т. Д.

+2

Я не думаю, что это * рекомендованный способ *, если он уже инкапсулирован в [WindowsFormsApplicationBase] (http://msdn.microsoft.com/en-us/library/microsoft.visualbasic .applicationservices.windowsformsapplicationbase.issingleinstance.aspx) – Oliver

+0

это выглядит классно, но http://msdn.microsoft.com/en-us/library/system.threading.mutex%28v=VS.80%29.aspx (Внимание! заброшенный мьютекс указывает на серьезную ошибку в коде.Когда поток выходит без освобождения мьютекса, структуры данных, защищенные мьютексом, могут не находиться в согласованном состоянии. Следующий поток для запроса права собственности на мьютекс может справиться с этим исключением и продолжить, если целостность структур данных может быть проверена.), а как насчет этого? Я использую .NET v2 –

+0

@Oliver: Thats в пространстве имен VB, это вопрос C#. –

4

Быстрый способ, который я сделал в одном из приложений. Вы можете посмотреть список запущенных процессов, чтобы узнать, запущено ли текущее приложение и не запускать приложение снова.

Process[] lprcTestApp = Process.GetProcessesByName("TestApplication"); 
if (lprcTestApp.Length > 0) 
{ 
     // The TestApplication is already running, don't run it again 
} 
+0

И его правильный способ ... – RameshVel

+0

Это не справится, если кто-то создал приложение с тем же именем файла, что и другое приложение. –

+0

Я думал точно в этом –

2

Я думаю, что перечисление списка процессов потенциально может быть медленным. Вы также можете создать Mutex, используя класс System.Threading.Mutex, и проверить, уже ли он создан при запуске процесса. Однако это потребует вызова в системный код Win32, поэтому он не будет полностью агностическим для платформы.

0

Если ваше приложение создает/потребляет файлы, то лучше регистрировать системный коммуникационный механизм (например, удаленная или конечная точка WCF или даже сокет). Затем, если второй экземпляр приложения запускается из двойного щелчка по одному из ваших файлов, вы можете отправить информацию о файле в исполняемый экземпляр.

В противном случае, если это автономная программа, то, как говорили другие, Mutex или Semaphore будут одинаково хорошо работать на сервере.

0

решение в приложении Windows Form Запретить снова запустить приложение (повторно открыть приложение).

1- первый Добавить класс RunAlready.cs

2-вызов метода processIsRunning() с именем процесса из RunAlready.cs в программе.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"); 

     } 
    } 
} 

класс 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; 
    } 
} 
} 
Смежные вопросы