Основная функция процесса: (w)main или (w)WinMain

октября 12 2009 by admin in Службы

Когда администратор хочет запустить службу, SCM определяет, запущен ли исполняемый файл, содержащий эту службу. Если нет, SCM его запускает. Основной поток процесса отвечает за инициализацию процесса в целом (инициализацию конкретной службы доллсна выполнять функция ServiceMain этой службы).
После инициализации процесса его основная функция должна связаться с SCM, который теперь управляет процессом. Для этого основная функция процесса должна прежде всего выделить и проинициализировать массив структур SERVICEJfABLE ENTRY.
SCM следит за работой службы. Например, порождая исполняемый модуль, SCM ожидает, когда основной поток исполняемого модуля обратиться к функции StartServiceCtrlDispatcher. Если обращения ней не происходит в течение 30 секунд, SCM считает, что исполняемый модуль работает некорректно, и вызывает функцию TerminateProcess для принудительного завершения процесса. Так что, если вашему процессу для инициализации требуется более 30 секунд, следует породить другой поток для его инициализации, а в основном потоке сразу вызвать StartServiceCtrlDispatcher. Заметьте, сейчас речь идет об инициализации всего процесса. Отдельные службы должны сами себя инициализировать собственными функциями ServiceMain.
StartServiceCtrlDispatcher не возвращает управление, пока не прекратят работу все службы, содержащиеся в исполняемом модуле. Пока работает хоть одна служба, SCM контролирует выполнение основного потока процесса. Обычно этот поток просто находится в состоянии ожидания, не расходуя процессорного времени. Если администратор пытается запустить другую службу, реализованную в том же исполняемом модуле, SCM не порождает нового экземпляра исполняемого модуля, а связывается с основным потоком существующего исполняемого модуля и вновь просматривает список служб, на этот раз в поисках службы, которую нужно запустить. Найдя ее, он порождает новый поток, выполняющий функцию ServiceMain соответствующей службы.
Чтобы определить, что порождать: новый процесс или новый поток существующего процесса службы, SCM производит точное сравнение строк, представляющих полный путь к имени исполняемого файла службы. Допустим, две службы содержаться в одном исполняемом файле MyServices.exe. Первая добавлена в базу данных SCM с указанием полного пути к исполняемому файлу "%windir9^\System32\ MySer-vice.exe", тогда как для второй указан путь "C:\WinNT\System32\ Му-Service.exe". Если запускаются обе службы, SCM породит два отдельных процесса, каждый из которых будет выполнять один и тот же файл MyService.exe. Чтобы гарантировать, что SCM использует один процесс для всех служб, содержащихся в одном исполняемом файле, нужно при добавлении служб в базу данных SCM указывать одну и ту же строку с полным путем к исполняемому файлу.
Система сама отслеживает, какие службы выполняются в запущенном процессе. Когда какая-либо служба заканчивает работу (обычно при возврате из ServiceMain), система проверяет, остались ли еще работающие службы. Возврат из StartServiceCtrlDispatcher происходит, только когда не остается работающих служб. Затем наша программа должна освободить ресурсы всего процесса, после чего следует выполнить возврат из основной функции процесса, при котором система прекратит его работу. Помните, что ресурсы должны быть освобождены в течение 30 секунд, иначе SCM уничтожит процесс.