Централизованное взаимодействие процессов
[SIZE="1"][COLOR="#c0c0c0"](варианты–в порядке субъективной оптимальности)[/COLOR][/SIZE]
0.Служба–наверное,самый лучший(в общем) вариант,но немного не для меня.Со службами я как-то не работал,да и это будет лишний процесс(ведь процесс–это вам не одна DLL,а как минимум 3 модуля–он сам+Kernel32+NTDLL)
1.Загрузка одной копии DLL через AppInitDLLs.Реализацию себе представляю так:в DLLMain создаётся мьютекс,при ошибке–самовыгруз(т.е. одна копия уже есть)
2.Загрузка DLL через Winlogon\Notify.Это даже лучше,чем п.1–не надо контролировать уникальность+я получаю подписку на всякие там логоны/запуски заставок и проч.(это будет логироваться)
Собственно,вот 1й вопрос–как организовать серверную часть
2й вопрос–как наладить взаимодействие клиентов с сервером,ибо единовременно к серверу может быть подключено >1 клиента(из механизмов IPC знаю пипки,майлслоты,но не знаю,насколько они кросспользовательские)?
Собственно,пока вроде всё.Остальные вопросы появятся позже:)
Что есть сервер? Что есть клиенты? И в чем суть их взаимодействия?
Может быть.Или я плохо описа́л
Сервер–DLL(или служба,если Phodopus меня таки уговорит:)),которая выполняет все операции–хранит данные,ведёт логи,следит за событиями и проч.Разумеется,сервер должен быть 1
Клиенты представляют собой программу,которая запускается для каждого пользователя.Они с сервером взаимодействуют путём,допустим,пайпов(вроде самый лучший механизм),т.е. просто шлют ему команды и,если надо,отображают результат.Например,пользователь 1 хочет передать пользователю 2 какую-то информацию.Клиент п. 1 делает запрос серверу на сохранение этой информации.Затем клиент п. 2 при запуске спрашивает сервер на предмет,а не оставлял ли кто ему заметок,на что сервер радостно возвращает инфу,оставленную клиентом п. 1
Как-то так:)
Если в организации всего хозяйства - то создаешь многопоточный сервер. Служба/не служба, сокет/пайп - это уж от твоих задач зависит. Я делал в обычном exe с именованными пайпами - меня по задачам устраивало. Создашь пул потоков клиентов, свяжешь с ними какие-то идентификаторы и некое хранилище данных.
Далее придумаешь протокол взаимодействия клиента с сервером. Например, по запросу клиента сервер выдает ему идентификаторы всех подключенных клиентов (чтоб знать, кому вообще можно отправлять данные). Затем клиент посылает данные на сервер + идентификатор клиента-получателя. Сервер принимает данные от одного клиента и посылает другому (либо сам и сразу, либо ждет запроса от второго клиента - опять же по задачам)
Как-то так, в общем ;)
По поводу 2го вопроса–есть ли способ организовать взаимодействие один-ко-многим?Ибо,например,сокеты поддерживают только 1-к-1
• Запуск цепочки программ с завершением работы по окончании их выполнения
• Напоминания о событиях(календарь)
• Список программ для быстрого запуска(с акселераторами)
• Передача оповещений между пользователями
• Автозапуск:выполнить системное действие по умолчанию(ShellExecute),только открыть,ничего не делать
Собственно,описанное мной взаимодействие требуется только для одного из пунктов(впрочем,функционал будет расширяться;можно ещё хранение настроек сервером сделать,пусть он этим заведует)–передачи оповещений
С механизмом взаимодействия >-< разобрался–сервер будет загружаться через WinLogon notification package,взаимодействие с ним–через пайпы
За это время я даже чуть сдвинулся с места,в аттаче выложены результаты труда(разумеется,стадия ещё жутко начальная,но что поделать)–решение для VS 2005
И сразу возникает вопрос:как это отлаживать?Ведь отладить я смогу только клиента(в смысле,отредактирова код-скомпилировал-запустил).Как быть с отладкой серверной части?
И сразу возникает вопрос:как это отлаживать?
Ответ есть у MSDN:)
Только exeшник службы debug-версия должен быть, чтоб отладочные символы присутствовали.
Хм, нуда... как сказал мсдн:
[quote=MSDN]
при подключении к процессу WinLogon и последующей остановке отладки произойдет остановка системы, поскольку она не может работать без данного процесса.
[/quote]
Тогда имхо только вести очень жирный лог :)
Запустив в виртуальной машинке.
Ramon:вот тоже на досуге об этом подумал.И даже вспомнил,что в VMWare есть сеть,а в VS–Remote debugger.Огорчает лишь то,что сеть я не знаю как правильно настроить,а уж как работать с RDbg–тем более.Буду рад советам в этом направлении
Зачем такое требование (работа под WinLogon-ом) откуда такая необходимость возникла?
Судя по всему задача решается банальным ком-сервером в виде сервиса.
А возникла–потому что я избрал такой путь.Загрузка с одним из первых процессов в системе,DLL(а не .exe) и т.п.
Дык, если не изучать, то придется изобретать собственный протокол взаимодействия клиентов и сервиса.
Выбор способа нужно уметь объяснить. Сейчас ты поимел проблемы с отладкой, а в конечном счете - с безопасностью решения как такового, т.к. winlogon сильно привилегированный системный процесс:
1) возможность прямой коммуникации с ним из любой пользовательской сессии - это потенциальная брешь в безопасности (привелегии сервиса можно настроить, да и нарушить протокол COM сложнее)
2) поломка в коде библиотеки ведет к краху процесса, что влечет за собой немедленный перезагруз системы (с сервисом такого не произойдет, он просто перезапустится)
[quote=MSDN]
GINA DLLs and Winlogon notification packages are ignored in Windows Vista
[/quote] :)))
Но ему все равно :D
Да,знаю.И да,всё равно:)(дальше XP я и не планировал…пока)
hardcase:
Вообще,я думал над своим протоколом–не такой он сложный будет,я думаю(и строить буду на пайпах,ага;ну это отдельный разговор)
Протокол подразумевает под собой разграничение прав,поэтому брешь прорвать будет не так просто.А привилегии службы–это какие,например?
Про поломку в коде библиотеки да,знал.В общем-то,я уже почти переубедился на счёт служб,поэтому изложу свои т.зр. так,чтоб поспорить:)
Преимущества WLNP:
• одна DLL(а не целый процесс с присобаченными к нему DLL) на всю систему
• грузится раньше клиентов,а выгружается после их выгрузки(в смысле,при завершении работы)
• отсутствует внешнее управление DLL(т.е. её не остановят,если вдруг кого-то припрёт)
• функционально реализованная подписка на события logon/logoff,startup/shutdown и проч.(не знаю,как с этим у служб)
• этот же модуль используется клиентом,т.к. в нём содержатся общие функции.Иначе придётся либо писать DLL,либо реализовывать функционал в клиенте и в сервере(см. п. 1)
Преимущества службы:
• описанные тобой
• можно управлять(тоже плюс,с одной стороны)
• механизм служб поддерживается почти без изменений и после XP,в отличие от WLNP
• ещё какие-то,но всё позабыл(перед сном размышлял:))
Вот так.Интересно поспорить по этим пунктам
Да,знаю.И да,всё равно:)(дальше XP я и не планировал…пока)
Каков смысл писать софт под устаревшую операционную систему? Тем более что однажды ты поставишь семерку и все перестанет работать ;)
Вообще,я думал над своим протоколом–не такой он сложный будет,я думаю(и строить буду на пайпах,ага;ну это отдельный разговор)
И что, пайпы автоматически решают проблему, скажем, переполнения буфера?
Банально запуск от некоторого пользователя.
Преимущества WLNP:
• одна DLL(а не целый процесс с присобаченными к нему DLL) на всю систему
Не аргумент. DLL и так грузятся единожды и проецируются в память процессов.
• грузится раньше клиентов,а выгружается после их выгрузки(в смысле,при завершении работы)
Запуск сервиса может быть при первом обращении клиента, так что для клиента будет все равно - запустилась служба сейчас или же при старте системы.
• отсутствует внешнее управление DLL(т.е. её не остановят,если вдруг кого-то припрёт)
Для служб это тоже решается.
• функционально реализованная подписка на события logon/logoff,startup/shutdown и проч.(не знаю,как с этим у служб)
Точно также решается.
• этот же модуль используется клиентом,т.к. в нём содержатся общие функции.Иначе придётся либо писать DLL,либо реализовывать функционал в клиенте и в сервере(см. п. 1)
Это вообще инвариантно любому техническому решению (статические либы в нативном коде, общие сборки в управляемом).
Итого: приемуществ у WLNP вообще нет, минус огромен - это устаревшая технология.
А в COM это решено?
Вообще,проблема переполнения буфера устраняется ручками
Однако,это лишние накладные расходы–создавать пользователя для службы,логиниться в нём(не,я понимаю,что это всё почти автоматом,но всё же)…Пусть служба будет как все
Я с этим уже ознакомился.Но сравни–1 DLL в роли сервера+клиент(ы) или 1 DLL+exe в роли сервера+клиент(ы).Есть всё же разница
Не может:) Потому что сервер ещё кое-что должен будет протоколировать,вне зависимости от клиентов.Им он только по запросу будет выдавать
Как?:)
Про уведомления прочитал,ага.Просто тогда не в курсе был
Ой ли?Я ведь правильно понимаю,что статическая библиотека→увеличение размера сервера и клиента?
Ну,плюсы-то,может,и есть.Но в целом согласен
[COLOR="#c0c0c0"](прошу не забывать,что это лишь технический спор,ставящий своей целью моё окончательное и бесповоротное просвещение ☺)[/COLOR]
COM вызовы строготипизированы.
Эта проблема устраняется автоматически отказом от ручного разбора буферов и введением строгой статической типизации.
Это делается единожды при развертывании системы.
Для одного сервиса разницы нет никакой.
Запускаешь сервис при старте системы всего делов-то.
Можно и динамическую использовать. Поинт в том, что написать код, размером превышающий хотя бы страндартную библиотеку - это надо постараться.
А нафига создавать пользователя,если он потом не используется?:) Профиль-то при запуске службы грузится каждый раз,так что…
Конечно,может быть,я чего-то не понимаю,но разве может быть DLL,загруженная процессом(WinLogon в данном случа),больше,чем целый процесс(новый!)+DLL?
Об этом я как бы догадался:)
О какой стандартной библиотеке речь?И как она сюда привязана?
Профиль может и не загружаться. Если тебе не нужен пользователь, то не создаешь.
А что, код в DLL не выделяет память? :)
Стандартной библиотеки языка который используешь. Я к тому, что экономить память (дисковую и оперативную) нужно лишь там, где это действительно необходимо.
А что,выделяет?:D
Я к тому,что догрузка одного модуля всё же меньше требует,чем целый процесс(с ещё одним модулем ☺),не?
Сказывается тяжёлое прошлой человека из моей подписи;)
А стандартную библиотеку я не использую.Отвязался от CRT,такие дела
Оказывается,не всё так плохо:сначала я вспомнил про DebugBreak,потом поискал по словам «DebugBreak services» и о чудо!–нашёл статью про отладку служб.Думаю,вариант с реестром можно отмести как более затратный по времени,и просто вставить DebugBreak где-нибудь в начале
Все гораздо проще. exe-шник службы для работы в режиме службы просто запускать с отдельным ключем (устанавливать).
Не совсем понял.У меня уже в сервере(службе) реализована установка по запросу(т.е. при передаче ключа install через командную строку).В клиенте будет возможность при отсутсвии службы в системе запустить сервер,тем самым установив его
Так что не совсем понятно,к чему это.Отлаживать службу,запущенную не как службу?
Именно.
А чем не устраивает вариант с DebugBreak?
Это смотря как писать :)
Это неудобно. Гораздо удобнее запускать из студии сразу и клиента и сервер одновременно - оба под отладчиком.
Согласен,что это самый удобный вариант.Но…как тогда писа́ть?:)
Полезный код отдельно - сервисная обвязка отдельно.
Неужели ты руками пишешь этот бесполезный код (сервисной обвяхзки)?
А где его взять-то?Не втупую ж с MSDN скатать,вдруг ошибки.Ну и свою инициализацию там придётся пихнуть же
Во всех нормальных средах разработки всегда есть шаблон виндового сервиса. C++ не использую потому не знаю.
Касательно .NET, то код тут выглядит крайне примитивно (без кода инсталляции):
namespace WindowsService1
{
static class Program
{
static void Main()
{
ServiceBase.Run(new ServiceBase[]
{
new Service1()
});
}
}
public class Service1 : ServiceBase
{
public Service1()
{
ServiceName = "Service1";
}
protected override void OnStart(string[] args)
{
}
protected override void OnStop()
{
}
}
}
Соответственно вынесение серверной логики становится тривиальным.
Я просто не понимаю где тут могут быть сложности :) И почему они тут могут возникнуть.
Ладно,уже оффтоп пошёл.До следующего вопроса ☺