Уведомление приложения из сервиса
От: tryAnother  
Дата: 22.01.24 09:35
Оценка: 5 (1)
Добрый день.
Есть windows сервис который должен уведомлять десктопные приложения о смене своего статуса.
Раньше использовались передача сообщений через:
RegisterWindowMessage, EnumWindows, PostMessage.
Но в новых версиях Windows была введена разная безопасность, сервисы и приложения разнести по разным уровням и сообщения перестали доходить.
После пересылка была сделана через mailslot, она работала нормально.
Но теперь потребовалось чтобы несколько приложений получало статус, а mailslot с нужным именем можно создать только один, соответственно и только одно приложение получает сообщения.

Вопрос: какой механизм лучше использовать для рассылки от сервиса нескольким приложениям маленьких сообщений?
Re: Уведомление приложения из сервиса
От: qaz77  
Дата: 22.01.24 13:37
Оценка: +1 -1
Здравствуйте, tryAnother, Вы писали:

A>RegisterWindowMessage, EnumWindows, PostMessage.

A>Но в новых версиях Windows была введена разная безопасность, сервисы и приложения разнести по разным уровням и сообщения перестали доходить.

Есть же и функции для подавления этой изоляции: ChangeWindowMessageFilter/ChangeWindowMessageFilterEx.
Re: Уведомление приложения из сервиса
От: Pavel Dvorkin Россия  
Дата: 22.01.24 14:36
Оценка: 3 (2)
Здравствуйте, tryAnother, Вы писали:

A>Вопрос: какой механизм лучше использовать для рассылки от сервиса нескольким приложениям маленьких сообщений?


pipes, sockets

Полный список IPC тут

https://learn.microsoft.com/ru-ru/windows/win32/ipc/interprocess-communications

Буфер обмена
COM
Копирование данных
DDE
Сопоставление файлов
Mailslots
Каналы
RPC
Сокеты Windows
With best regards
Pavel Dvorkin
Re[2]: Уведомление приложения из сервиса
От: tryAnother  
Дата: 23.01.24 08:03
Оценка:
Здравствуйте, qaz77, Вы писали:

Q>Есть же и функции для подавления этой изоляции: ChangeWindowMessageFilter/ChangeWindowMessageFilterEx.


По описанию то, что нужно, но так сразу не заработало, и ошибок не возвращает.
Буду дальше разбираться.
Re[2]: Уведомление приложения из сервиса
От: tryAnother  
Дата: 23.01.24 08:39
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>pipes, sockets


pipes работают 1-1, а мне нужно от одного ко многим

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

Можно было бы задать динамический выбор порта (bind(0)), но как передать его клиентам.

PD>Полный список IPC тут


я с ним знаком, не ясно что использовать для данного конкретного случая

PD>Буфер обмена

PD>Копирование данных
PD>DDE
PD>COM

как это все использовать из сервиса в моем случае?

PD>Сопоставление файлов


В этом варианте потребуется периодический опрос из приложений и синхронизация доступа?
Возможно вариант, но не очень красивый.
Изоляция процессов тут не помешает?

PD>Mailslots

PD>Каналы

не работают в режиме от одного ко многим

PD>RPC


Не сталкивался с RPC, но судя по описанию тоже не очень подходящий вариант, для получения статуса клиентам нужно постоянно опрашивать сервис.

PD>Сокеты Windows


остается этот, или периодический опрос, или делать TCP сервер c сессиями на каждого клиента
Re[3]: Уведомление приложения из сервиса
От: Pavel Dvorkin Россия  
Дата: 23.01.24 09:17
Оценка: +1
Здравствуйте, tryAnother, Вы писали:

A>pipes работают 1-1, а мне нужно от одного ко многим


Ну не совсем.

The simplest pipe server creates a single instance of a pipe, connects to a single client, communicates with the client, disconnects from the client, closes the pipe handle, and terminates. However, it is more common for a pipe server to communicate with multiple pipe clients. A pipe server could use a single pipe instance to connect with multiple pipe clients by connecting to and disconnecting from each client in sequence, but performance would be poor. The pipe server must create multiple pipe instances to efficiently handle multiple clients simultaneously.

Например, SQL Server на локальной машине может взаимодействовать с локальными же клиентами через pipe (с удаленными только через сокеты). А он сервис, и клиентов может быть очень много.

https://learn.microsoft.com/en-us/windows/win32/ipc/named-pipe-instances

A>sockets да, этот вариант я рассматривал, тут потребуется написать небольшой сервер, который обслуживает подключения клиентов


Придется.

A>имеется небольшая проблема с выбором порта, он должен быть статический, чтобы и сервис и приложения имели к нему доступ,


Или указать его в настройках сервиса, в реестре.

>но может оказаться кем то уже занят в системе (проблема маловероятная конечно).


Теоретически может, но если брать из старшей половины, то вряд ли.



A>Можно было бы задать динамический выбор порта (bind(0)), но как передать его клиентам.


Через реестр.

PD>>Полный список IPC тут


A>я с ним знаком, не ясно что использовать для данного конкретного случая


PD>>Буфер обмена

PD>>Копирование данных
PD>>DDE
PD>>COM

A>как это все использовать из сервиса в моем случае?


Буфер обмена — едва ли. Не уверен, что он вообще не привязан в window station, а сервис и приложение работают на разных window station. Кроме того, его может изменить любая программа , тот же Paint загонит туда картинку.

Копирование данных — довольно просто в теории, WM_COPYDATA . Но не уверен, что пройдет между разными window station. Не пробовал.

COM — не для этого случая, слишком много работы



PD>>Сопоставление файлов


A>В этом варианте потребуется периодический опрос из приложений и синхронизация доступа?


Или Event, сигнализирующий, что данные изменились.

A>Возможно вариант, но не очень красивый.

A>Изоляция процессов тут не помешает?

Не в курсе.

PD>>Mailslots

PD>>Каналы

A>не работают в режиме от одного ко многим


PD>>RPC


A>Не сталкивался с RPC, но судя по описанию тоже не очень подходящий вариант, для получения статуса клиентам нужно постоянно опрашивать сервис.


Слишком тяжелая артиллерия.

PD>>Сокеты Windows


A>остается этот, или периодический опрос, или делать TCP сервер c сессиями на каждого клиента
With best regards
Pavel Dvorkin
Re[4]: Уведомление приложения из сервиса
От: m2user  
Дата: 23.01.24 11:59
Оценка:
A>>Можно было бы задать динамический выбор порта (bind(0)), но как передать его клиентам.

PD>Через реестр.


Если задача состоит только в том, чтобы сообщить текущий статус сервиса (без истории) то его и можно записывать в некий заранее определенный ключ реестра.
А заинтересованые приложения будут оттуда читать (периодически или через RegNotifyChangeKeyValue).
Re[5]: Уведомление приложения из сервиса
От: Pavel Dvorkin Россия  
Дата: 23.01.24 12:08
Оценка:
Здравствуйте, m2user, Вы писали:



PD>>Через реестр.


M>Если задача состоит только в том, чтобы сообщить текущий статус сервиса (без истории) то его и можно записывать в некий заранее определенный ключ реестра.

M>А заинтересованые приложения будут оттуда читать (периодически или через RegNotifyChangeKeyValue).

Как вариант сойдет, но не очень хорошее решение. Не для этого реестр.
Можно ведь тогда и просто через некоторый файл и FindFirstChangeNotification или ReadDirectoryChangesW. Тоже решение.

А настоящий IPC — лучше все-таки pipe или socket.

Вот ряд примеров для сокетов

https://www.google.com/search?q=socket+server+c%2B%2B+simple&sca_esv=600731789&sxsrf=ACQVn09LL75AJG0dC32EL74o22K7sjsZPg%3A1706011482357&source=hp&ei=WquvZbiGFKTFwPAPj_SnoAw&iflsig=ANes7DEAAAAAZa-5atp928Gc9OlXtgHGHKL0lJB6xbaj&udm=&ved=0ahUKEwi4m4yDvPODAxWkIhAIHQ_6CcQQ4dUDCA0&uact=5&oq=socket+server+c%2B%2B+simple&gs_lp=Egdnd3Mtd2l6Ihhzb2NrZXQgc2VydmVyIGMrKyBzaW1wbGUyBhAAGBYYHkj5Q1AAWItCcAB4AJABAJgBlwGgAb4XqgEEMC4yNLgBA8gBAPgBAcICChAjGIAEGIoFGCfCAgQQIxgnwgILEAAYgAQYsQMYgwHCAhEQLhiABBixAxiDARjHARjRA8ICDhAuGIAEGLEDGMcBGNEDwgILEC4YgAQYsQMYgwHCAggQABiABBixA8ICBRAAGIAEwgIOEC4YgAQYigUYsQMYgwHCAgoQABiABBjLARgKwgIIEAAYgAQYywHCAggQABgWGB4YDw&sclient=gws-wiz
With best regards
Pavel Dvorkin
Re[6]: Уведомление приложения из сервиса
От: m2user  
Дата: 23.01.24 14:16
Оценка: +1
PD>Как вариант сойдет, но не очень хорошее решение. Не для этого реестр.
PD>Можно ведь тогда и просто через некоторый файл и FindFirstChangeNotification или ReadDirectoryChangesW. Тоже решение.

Да, и файл тоже. Но файл может быть заблокирован некоторым процессом, в отличие от registry key/value.

PD>А настоящий IPC — лучше все-таки pipe или socket.


Из этих двух вариантов, думаю, pipe будет проще, т.к. поддерживает message режим, помимо stream режима.
Re[7]: Уведомление приложения из сервиса
От: Pavel Dvorkin Россия  
Дата: 23.01.24 15:20
Оценка:
Здравствуйте, m2user, Вы писали:

M>Да, и файл тоже. Но файл может быть заблокирован некоторым процессом, в отличие от registry key/value.


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

PD>>А настоящий IPC — лучше все-таки pipe или socket.


M>Из этих двух вариантов, думаю, pipe будет проще, т.к. поддерживает message режим, помимо stream режима.


Да, если речь идет о небольших сообщениях, то message mode, видимо, подойдет лучше всего.

Но почитай про права доступа. Сервис и приложение работают на разных window station. К тому же сервис, скорее всего, запущен не от юзера, а от Local System (хотя можно и от юзера). Так что, возможно, придется кое-что в этом плане настраивать.
With best regards
Pavel Dvorkin
Re[3]: Уведомление приложения из сервиса
От: пффф  
Дата: 27.02.24 19:33
Оценка:
Здравствуйте, tryAnother, Вы писали:

PD>>pipes, sockets


A>pipes работают 1-1, а мне нужно от одного ко многим


Нет. ConnectNamedPipe работает практически также, как connect для сокетов, при этом создаётся для данного клиента отдельное соединение.
Re[6]: Уведомление приложения из сервиса
От: flаt  
Дата: 26.03.24 19:23
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:


PD>>>Через реестр.


M>>Если задача состоит только в том, чтобы сообщить текущий статус сервиса (без истории) то его и можно записывать в некий заранее определенный ключ реестра.

M>>А заинтересованые приложения будут оттуда читать (периодически или через RegNotifyChangeKeyValue).

PD>Как вариант сойдет, но не очень хорошее решение. Не для этого реестр.


Тем не менее, performance counters именно в реестр пишутся, например.
Re[7]: Уведомление приложения из сервиса
От: rudzuk  
Дата: 26.03.24 20:31
Оценка: 8 (1) +2
Здравствуйте, flаt, Вы писали:

f> PD>Как вариант сойдет, но не очень хорошее решение. Не для этого реестр.


f> Тем не менее, performance counters именно в реестр пишутся, например.


Нет, перфкаунтеры в реестр не пишутся. Перфкаунтеры читаются из hkey_performance_data, но это фейковый раздел, данные которого формируются путем опроса dll'ек зарегистрированных в качестве источников данных о производительности.
avalon/3.0.2
Re[8]: Уведомление приложения из сервиса
От: Pavel Dvorkin Россия  
Дата: 27.03.24 02:45
Оценка:
Здравствуйте, rudzuk, Вы писали:

f>> Тем не менее, performance counters именно в реестр пишутся, например.


R>Нет, перфкаунтеры в реестр не пишутся. Перфкаунтеры читаются из hkey_performance_data, но это фейковый раздел, данные которого формируются путем опроса dll'ек зарегистрированных в качестве источников данных о производительности.


Ну и кроме того, это данные для неопределенного круга потребителей, а не для взаимодействия процессов
With best regards
Pavel Dvorkin
Re[7]: Уведомление приложения из сервиса
От: Pavel Dvorkin Россия  
Дата: 27.03.24 02:51
Оценка: +1
Здравствуйте, flаt, Вы писали:

F>Тем не менее, performance counters именно в реестр пишутся, например.


Данные в реестре либо должны быть осмысленными даже при выключенной машине, либо должны исчезать при ее выключении.

А тут получится, что при выключении (или крахе) в реестре окажется не пойми что.
With best regards
Pavel Dvorkin
Re[8]: Уведомление приложения из сервиса
От: flаt  
Дата: 31.03.24 19:46
Оценка:
Здравствуйте, rudzuk, Вы писали:

R>Нет, перфкаунтеры в реестр не пишутся. Перфкаунтеры читаются из hkey_performance_data, но это фейковый раздел, данные которого формируются путем опроса dll'ек зарегистрированных в качестве источников данных о производительности.


Performance data is not actually stored in the registry. Calling the registry functions causes the system to collect the data from the appropriate performance data provider.


Надо же, век учись.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.