Главная > C# (Csharp) > C# - запуск только одной копии программы

C# - запуск только одной копии программы

Недавно пришлось решить вопрос запуска только одной копии программы на C#. Вопрос решил успешно, используя Mutex. Собственно велосипед изобретать не стал и воспользовался готовым кодом, который нашел здесь. Сначала создаем класс (который я успешно использовал уже в нескольких проектах):


public class SingleInstance
{
private bool firstInstance = false;

public bool FirstInstance
{
get { return firstInstance; }
}

public SingleInstance()
{
Mutex mutex=null;
try
{
//Пытаемся получить мутекс, если он уже существует
mutex = Mutex.OpenExisting("ИмяНашегоПриложения");
}
catch (WaitHandleCannotBeOpenedException e)
{
//Если получили ошибку - мутекс не существует
firstInstance = true;
}

//Если null - создаем новый мутекс
if (mutex == null)
{
mutex = new Mutex(false, "ИмяНашегоПриложения");

//Чтобы сборщик мусора не удалил наш мутекс делаем так:
GC.KeepAlive(mutex);
}
}
}

После чего изменяем Program.cs:

[STAThread]
static void Main()
{
SingleInstance single = new SingleInstance();

if (single.FirstInstance)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
}

Код не дает запускать несколько копий программы, которая написана на C#. Тестировал под XP, Vista с различными SP - работает отлично.
Такой вот простой вспомагательный класс решает одну важную задачу. Спасибо.

admin C# (Csharp) , ,

  1. 11 Август 2008 в 13:02 | #1

    А если названия исполнительных файлов поменять - все равно работает? Т.е. один запустился с одинм названием, а другой с другим?

  2. 13 Август 2008 в 10:56 | #2

    Да, работает даже если файлы переименовать.

  3. Alexey Nayda
    26 Август 2008 в 22:53 | #3

    Чтобы все было совсем хорошо, тебе еще нужно унаследовать класс твоего прложения от SingleInstance.

  4. 1 Сентябрь 2008 в 11:36 | #4

    почему не перенести создание мьютекса в тот же кетч WaitHandleCannotBeOpenedException, а чтобы сборщик мусора его даже не пытался убить вынести Mutex mutex из локальной области конструктора в переменные класса?
    Собственно эту же переменную можно использовать как замена ненужному boolу.
    к примеру так:
    public bool FirstInstance
    {
    get {
    if(mutex!=null) return false;
    else return true;
    }
    }

  5. 3 Сентябрь 2008 в 20:26 | #5

    Кстати, метод не работает если программа запускается на сервере терминалов. Если логиниться в несколько сессий под одним и тем же пользователем - программа успешно стартует в любой из сессий.
    А жаль…

  6. 4 Сентябрь 2008 в 15:53 | #6

    Вопрос с терминальным сервером решаемый, нужно добавлять префикс Global\ к именам объектов синхронизации.
    Свой вариант велосипеда запостил в блоге.

  7. 4 Сентябрь 2008 в 20:29 | #7

    Ага, спасибо. Завтра попробую :)
    Просто есть задача гонять на сервере бот-почтовик и хочется чтобы две его копии случайно не запускались в разных сессиях.

  8. 6 Сентябрь 2008 в 17:25 | #8

    Спасибо, за ссылку… тоже мне было
    срочно нужно.

  9. 10 Октябрь 2008 в 23:09 | #9

    Хм. Недавно опубликовал в своем блоге (bitonic.wordpress.com) примерно то же самое - работа с мьютексом, только на С++. Мой пример короче, хотя признаю, что твой/ваш техничнее :-)

  10. Tantal
    11 Ноябрь 2008 в 18:56 | #10

    Тема с…к нераскрыта.

    Во многих случаях необходимо передать параметры коммандной строки первому экземпляру или активировать это окно. В данном случае - первый экземпляр программы даже не узнает о попытке запуска второй копии. Решается все при помощи семафора, а не мьютекса.

  1. Пока что нет уведомлений.