Подтвердить что ты не робот

Как ограничить программу одним экземпляром

У меня есть консольное приложение на С#, и я хочу ограничить мое приложение одновременным запуском только одного экземпляра. Как достичь этого в С#?

4b9b3361

Ответ 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
    }
}