У меня есть консольное приложение на С#, и я хочу ограничить мое приложение одновременным запуском только одного экземпляра. Как достичь этого в С#?
Как ограничить программу одним экземпляром
Ответ 1
Я бы использовал Mutex
static void Main()
{
string mutex_id = "MY_APP";
using (Mutex mutex = new Mutex(false, mutex_id))
{
if (!mutex.WaitOne(0, false))
{
MessageBox.Show("Instance Already Running!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);
return;
}
// Do stuff
}
}
Ответ 2
Если вы решили использовать Mutex для этой цели, есть некоторые подводные камни, о которых вы должны знать:
-
Если вы хотите ограничить приложение одним экземпляром на машину (т.е. Ни один из зарегистрированных пользователей), вам понадобится ваше имя мьютекса, чтобы начать с префикса
Global\
. Если вы не добавите этот префикс, другой экземпляр мьютекса будет создан ОС для каждого пользователя. -
Если вы работаете на компьютере с Windows Vista или более поздней версией с включенным UAC, и, если случайно текущий экземпляр приложения запущен в качестве администратора, то следующие экземпляры не смогут его обнаружить, и вы получите исключения для разрешения. Чтобы этого избежать, вам нужно указать другой набор разрешений для Mutex при его создании.
Ответ 3
Существует много способов, таких как
- Перечисление списка процессов перед запуском и отрицанием запуска, если имя процесса уже существует.
- Создание мьютекса при запуске и проверка наличия мьютекса уже существует.
- Запуск программы через одноэлементный класс.
Ниже приведена демонстрация ниже:
http://iridescence.no/post/CreatingaSingleInstanceApplicationinC.aspx
http://www.codeproject.com/KB/cs/restricting_instances.aspx
http://www.codeproject.com/KB/cs/singleinstance.aspx
У каждого есть свои плюсы и минусы. Но я считаю, что создание мьютекса - лучшее, на что можно пойти.
Ответ 4
Добавляем этот ответ, потому что предыдущие не работали над linux (проверенный ubuntu 14.0.4) с .net core1.1 и потому, что этот вопрос высок в результатах поиска. Изменение решения @MusuNaji, если это уже не было очевидно для вас.
private static bool AlreadyRunning()
{
Process[] processes = Process.GetProcesses();
Process currentProc = Process.GetCurrentProcess();
logger.LogDebug("Current proccess: {0}", currentProc.ProcessName);
foreach (Process process in processes)
{
if (currentProc.ProcessName == process.ProcessName && currentProc.Id != process.Id)
{
logger.LogInformation("Another instance of this process is already running: {pid}", process.Id);
return true;
}
}
return false;
}
Этот ответ также размещен на моем основном вопрос в ядре dotnet: Однопользовательское приложение dotnetcore cli для Linux
Ответ 5
вот решение, которое сработало для меня
private static bool AlreadyRunning()
{
Process[] processes = Process.GetProcesses();
Process currentProc = Process.GetCurrentProcess();
foreach (Process process in processes)
{
try
{
if (process.Modules[0].FileName == System.Reflection.Assembly.GetExecutingAssembly().Location
&& currentProc.Id != process.Id)
return true;
}
catch (Exception)
{
}
}
return false;
}
Затем я проверяю вывод этого метода при запуске программы.
Ответ 6
Самый прямой ответ для меня, показанный ниже, взятый из Madhur Ahuja, опубликовал ссылку (http://www.webskaper.no/wst/creatingasingleinstanceapplicationinc-aspx/) - воспроизведено здесь (проектные решения кода были скрыты от меня).
Важным моментом было сохранение мьютекса до завершения процесса (очевидно, я думаю).
bool createdNew;
using (Mutex mutex = new Mutex(true, "MyApplicationName", out createdNew))
{
if (createdNew) {
// process
}
else {
// in my case, quietly exit
}
}