2009-06-10 3 views
0

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

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

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

ответ

3

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

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

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

0

similar question [в соответствии с ответами там, вы на правильном пути]

+0

Похоже, но вопрос о двух экземпляров одного и того же приложения. –

+0

Я стою исправлен (хотя это та же концепция). – laginimaineb

7

K. Скотт Аллен имеет a good write up с использованием Mutex для этой цели и проблемы, с которыми вы столкнетесь с GC.

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

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

EDIT: Измененной строка символов, чтобы использовать сбежавший обратный слэш вместо @, SO подсветке синтаксиса не нравится дословная строка.

+0

Зачем нужен GC.Collect(); ? – tanascius

+0

О, я считаю, что он демонстрировал, что даже если GC собрался в этот момент, мьютекс все равно не будет удален (и, следовательно, выпущен) - я отредактирую, чтобы избежать путаницы. Спасибо что подметил это. –

+0

Хорошая запись о подобной (но другой) проблеме. –

0

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

+0

Я отклонил этот подход, так как нам нужно будет использовать изменчивое имя процесса, поэтому он будет более хрупким, чем альтернативы. –

1

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

Надеется, что это помогает ...

+0

Спасибо Roel, за исключением случаев, когда служба не работает, этот подход становится более сложным, чем просто проверка Mutex. –

+0

У этого есть возможное преимущество, что, когда служба запустилась, создала мьютекс и впоследствии получила некоторый урон, оставив ее невосприимчивой, ваше приложение WinForms быстро узнает плохие новости. Сравните с ping, где пингер действительно не заботится о том, почему pingee не работает. –

2

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

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

+0

Nice идея. 12345 –