Надежно обнаруживает, что другое из моих приложений работает

У меня есть два приложения, приложение WinForms и служба Windows, которые будут работать на одном компьютере. Я хочу, чтобы приложение WinForms надежно определяло, когда служба запущена. Я полностью контролирую разработку и реализацию обоих приложений.

Моя первая мысль - использовать Mutex, создается Службой и обнаруживается приложением WinForms.

Есть дизайн получше?


person Ed Guiness    schedule 10.06.2009    source источник


Ответы (5)


Mutex - это то, что вам нужно. Это намного менее хрупко, чем использование имен процессов и т. Д.

Однако вам нужно убедиться, что Mutex не собирает мусор. В случае службы (которая управляется событиями, а не имеет «основной» метод, который выполняется до завершения), наиболее разумный способ сделать это, вероятно, - поместить его в статическую переменную.

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

person Jon Skeet    schedule 10.06.2009

К. Скотт Аллен написал хороший отзыв о использование Mutex для этой цели и проблемы, с которыми вы столкнетесь с GC.

Если я хочу, чтобы во всех сеансах на машине работал только один экземпляр приложения, я могу поместить названный мьютекс в глобальное пространство имен с префиксом «Global \».

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

РЕДАКТИРОВАТЬ: изменен строковый литерал для использования экранированной обратной косой черты вместо @, подсветке синтаксиса SO не понравилась дословная строка.

person Matt Brindley    schedule 10.06.2009
comment
Зачем нужен GC.Collect (); ? - person tanascius; 10.06.2009
comment
О, я полагаю, он демонстрировал, что даже если сборщик мусора будет собран в этот момент, мьютекс все равно не будет удален (и, следовательно, освобожден) - я отредактирую, чтобы избежать путаницы. Спасибо что подметил это. - person Matt Brindley; 10.06.2009

Вы можете использовать Mutex, но вы также можете использовать вместо него класс ServiceController. Это позволит вам узнать, установлена ​​ли служба, и если она установлена, но не запущена, запустите ее, если применимо.

http://msdn.microsoft.com/en-us/library/system.serviceprocess.servicecontroller_members.aspx

person samjudson    schedule 10.06.2009

Вы можете реализовать в сервисе некоторую функциональность «Проверка подключения». Я не знаю, сработает ли это для ваших требований. При запуске winforms вы можете позвонить в службу, чтобы узнать, работает ли она. Вы можете предоставить сервис с помощью простого контракта WCF.

Надеюсь это поможет...

person RoelF    schedule 10.06.2009
comment
Спасибо, Роэл, за исключением случаев, когда служба не работает, этот подход становится более сложным, чем простая проверка мьютекса. - person Ed Guiness; 10.06.2009
comment
Возможное преимущество заключается в том, что когда служба запущена, создала мьютекс и впоследствии понесет некоторый ущерб, оставив его без ответа, ваше приложение WinForms быстро узнает плохие новости. Сравните с пингом, когда пингеру все равно, почему пингер не работает. - person Thomas L Holaday; 10.06.2009

В качестве альтернативы ваше приложение WinForms может проверить список запущенных служб, чтобы узнать, запущена ли служба.

person Thomas L Holaday    schedule 10.06.2009
comment
Я отказался от этого подхода, поскольку нам нужно было бы использовать изменчивое имя процесса, поэтому он был бы более хрупким, чем альтернативы. - person Ed Guiness; 10.06.2009