2011-02-08 3 views
1

Хорошо, короткая короткая история У меня есть служба Windows, которая обрабатывает Win32_VolumeChangeEvent и регистрирует поступления USB-дисков в журнал событий и в базу данных SQL. Дополнительным компонентом этого является скрытый пользовательский интерфейс (WinForms), который загружается в сеансе пользователя при входе в систему - это всплывающее окно с напоминанием пользователям политики компании о USB-ключах и т. Д. AFAIK, это был лучший способ, поскольку услуги не могут более продолжительный запуск в интерактивном режиме.C# Пропускание через IPC

Anywho ... архитектурно, v1 этой маленькой вещи работал с компонентом пользовательского интерфейса, обрабатывающим сообщения WndProc для вставки устройства, затем передавал идентификатор устройства через IPC (именованные каналы) службе, которая обрабатывала бы методы WMI/запись в журнале событий (поскольку не все пользователи имеют права локального администратора). Это имело недостаток элемента интерфейса, который был убит процессом и больше не обнаруживал вставки устройства.

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

Я исследовал Google и здесь, ища идеи о событиях по IPC, поэтому я могу просто подписаться на событие из компонента пользовательского интерфейса и запустить его внутри службы, но я не нахожу много, что выпрыгивает как полезный. Я также ограничен .net2, поэтому WCF не работает (хотя я не боюсь p/invoke, если вы хотите пойти таким образом).

So. Как бы вы это сделали? Ссылки, мысли, промахи, псевдокод, фактический код ... все оценили. Я пытаюсь придерживаться того, что, по моему мнению, является лучшей практикой, хотя я также думаю, что программирование - это немного форма искусства, и моя лучшая практика может быть чужой ужасной историей.

Так что, что бы вы сделали? Дайте мне знать, если мне нужно уточнить :)

+1

Это было бы относительно легко с WCF. Почему вы ограничены .NET 2? Вы знаете, что .NET 3.0 и 3.5 являются суперсетями .NET 2, а не отдельными версиями и не меняют основные сборки? –

+0

У нас нет хорошего покрытия на стороне клиента .net 3 устанавливает, тогда как у нас почти полное покрытие .net 2 устанавливает. Нажатие .net3 на данный момент не является вариантом. – dotalchemy

ответ

3

В старые добрые времена программирования Windows API мы иногда использовали RegisterWindowMessage для регистрации уникального идентификатора сообщения, которое (предположительно) только в нашем окне знало, как обращаться. Мы могли бы затем запустить это окно из другого приложения, вызвав PostMessage с дескриптором окна HWND_BROADCAST, а параметр msg - это уникальное значение сообщения. Это отлично работает, если все, что вы хотите разделить между процессами, может вписываться в два значения DWORD (wparam и lparam). Совместное использование большего количества данных может быть выполнено, если вы выделяете глобальную память и передаете ссылку в качестве одного из параметров.

Это должно быть возможно с помощью .NET. Конечно, нет проблем с вызовом PostMessage. Что касается обработки сообщения в коде пользовательского интерфейса, вам необходимо переопределить форму WndProc. См. Пример How do I send/receive windows messages between VB6 and c#?.

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

Вы можете пойти по названному маршруту событий и использовать разделяемую память (файл с отображением памяти) для совместного использования состояния.

Или вы можете настроить розетки, названные трубы, TcpListener/TcpClient или даже UdpClient. Все должны работать с разной степенью сложности и/или надежностью.

+1

Хорошие варианты. К сожалению, PostMessage и др. Не будут пересекать границу Session0 и подпадают под все виды оспатринга Windows, когда дело доходит до отправки сообщений между уровнями. Я снова исследую названные события и сокеты. На этот раз отметили оба ответа и примем их после дальнейшего просмотра. – dotalchemy

+1

Ты дал мне много хорошего, о чем нужно подумать. В конечном счете, я вернул его к основам и захватил WndProc в пользовательском интерфейсе (как и в v1) с отметкой времени, чтобы избежать множественных всплывающих окон, когда Windows делает свою небольшую заметку о потоке сообщений и реализовала их по существу как два отдельных приложения. Он служит своей цели. Тем не менее, сегодня вы провели увлекательное путешествие, играя с разными идеями и глядя на другой код. Спасибо за предложение! – dotalchemy

1

Единственная идея, которая приходит мне на ум - это периодически проверять состояние приложения UI и перезапускать его, если он был убит. Кажется, что нет стандартного модуля, который запускался бы в сеансе пользователя и позволял службе отправлять уведомления этому модулю. Существуют сторонние решения, но их можно убить (не говоря о том, что они должны быть установлены для использования).

Обновление: после повторного чтения вопроса, я думаю, что, возможно, ваш пользовательский интерфейс не получает сообщений Windows, поэтому вам нужен другой механизм. Почему бы не создать объект синхронизации Semaphore в службе и ждать его в процессе пользовательского интерфейса (в отдельном потоке)?

+0

Позвольте мне уточнить - у меня уже есть компонент пользовательского интерфейса, это отдельный проект WinForms, который компилируется и работает отлично. Запуск его снова не является проблемой, так как служба все равно будет регистрировать поступления устройств. Проблема в том, что пользовательский интерфейс (если он работает) реагирует на вставку. – dotalchemy

+0

@dotalchemy теперь я смущен. Вы написали: «Это имело недостаток элемента пользовательского интерфейса, который был убит процессом и больше не обнаруживал вставки устройств». И ваш комментарий отрицает цитируемое заявление. –

+0

Это был недостаток версии 1, поэтому я переписал ее, чтобы служба обрабатывала приход устройства, и пользовательский интерфейс требуется исключительно для отображения всплывающего сообщения. – dotalchemy

Смежные вопросы