Несколько служб Windows в одном exe
Я пытаюсь создать несколько служб Windows, чтобы делать разные вещи. Например, мне нужны службы Windows, которые будут:
- Отправить ежедневный отчет по электронной почте
- Периодически очищайте некоторую архивированную информацию каждые 30 минут.
- и др.
Задачи, которые мне нужны для работы служб Windows, различны, поэтому мне не очень нравится идея иметь их всех в одной службе.
То, что у меня есть, - это проект в Visual Studio 2008. Я создал службу Windows, я настроил таймер на событии OnStart (он просто пишет в текстовый файл каждые 5 секунд для тестирования цели). Затем я добавил установщика в проект, и когда я запускаю InstallUtil.exe, все работает нормально.
Проблема возникает, когда я добавляю вторую службу Windows в тот же проект. Я снова установил код OnStart с той же информацией о регистрации (немного другой, чтобы я мог указать, какая служба записывает в журнал). Со второй службой Windows я изменил главное событие в Program.cs:
static void Main(string[] args)
{
ServiceBase[] ServicesToRun = new ServiceBase[]
{
new Service1()
};
ServiceBase.Run(ServicesToRun);
}
to:
static void Main(string[] args)
{
ServiceBase[] ServicesToRun = new ServiceBase[]
{
new Service1(),
new Service2()
};
ServiceBase.Run(ServicesToRun);
}
На данный момент ошибок компиляции не существует, но служба Service2 никогда ничего не делает... задача ведения журнала никогда не срабатывает.
Я сузил его до того, что второй сервис не связан с ним "установщиком". Затем я попытался добавить установщик так, как я сделал с первой службой (т.е. Щелкните правой кнопкой мыши на конструкторе служб и нажмите "Добавить установщик" ). Теперь, когда я перехожу к файлу ProjectInstaller.cs, там есть другой serviceInstaller (serviceInstaller2).
Теперь, когда я создаю проект и пытаюсь установить службы, и я иду в окно панели управления "Службы", и я пытаюсь запустить Service1, я получаю следующее сообщение об ошибке:
Windows не удалось запустить службу Service1 на локальном компьютере.
Ошибка 1083: исполняемая программа, для которой эта служба настроена для запуска, не выполняет службу.
Я получаю то же сообщение об ошибке, если я попытаюсь запустить Service2 (за исключением того, что сообщение об ошибке идентифицирует Service2, конечно).
Есть ли что-то, что мне не хватает, чтобы получить две службы, запущенные из одного exe?
Ответы
Ответ 1
Я выяснил, как иметь одну исполняемую, но две службы. Каждая служба устанавливается в диспетчер службы с собственным именем и возможностью запуска/остановки. Я думаю, что это то, чего ты хочешь, правильно? Вот что я сделал:
- Создал сервисный проект.
- Добавлена вторая услуга в тот же проект (с уникальным именем службы).
- Добавлен установщик для обеих служб (ServiceA и ServiceB).
- В файле ProjectInstaller.Designer.vb я изменил строку Me.Installers.AddRange, чтобы показать оба установщика службы. (Me.ServiceInstaller1, Me.ServiceInstaller2)
- В главной точке входа основной службы (ServiceA в моем случае) я установил переменную ServicesToRun в массив ServiceBase, содержащий все службы, которые я хочу запустить (ServiceA и ServiceB). Это важный шаг, так как диспетчер сервиса устанавливает свойство на основе количества аргументов здесь - либо для того, чтобы разрешить несколько экземпляров одного и того же exe или только одного экземпляра.
- Добавьте проект установщика и используйте выходные данные служб.
- Добавить настраиваемое действие с помощью вывода служб.
Здесь вы можете найти демо-код:
http://code.google.com/p/multi-service-install/
Наслаждайтесь!
Ответ 2
Я предполагаю, что вы, ребята, уже решили это, но в случае, если это кому-то еще понадобится, я отправлю ответ на этот вопрос, который занял у меня несколько часов сегодня.
Решения не включают в себя еще один установщик проекта, но установщик услуг, который является компонентом в программе установки. У этого недавно добавленного сервисного установщика должно быть настроено второе имя службы.
Ответ 3
У меня была аналогичная проблема сегодня, и мне удалось ее решить.
Во-первых, я удостоверился, что каждая из служб имеет значимое и уникальное свойство ServiceName. Генератор предоставил обе службы одноименное имя, которое не помогло бы.
Затем я удалил и восстановил класс ProjectInstaller и добавил установщиков для каждого из классов. Я убедился, что оба они были созданы в статическом методе Main.
Теперь я могу установить две службы с одной DLL, но, к сожалению, когда я запускаю одну из служб, она, как представляется, выполняет функции как самой, так и другой службы. То есть обе службы работают (хотя только одна из служб отображается как "Начать" в диспетчере компьютеров). Я все еще пытаюсь понять, что это...
Ответ 4
Я на самом деле строю нечто похожее на то, о чем вы думаете. То, что я решил сделать (пока), имеет все мои "сервисы" (хотя они не являются сервисами, один "контроллер" ) реализует определенный интерфейс (с операциями init() и execute() как перечисление FREQUENCY).
Контроллер является службой Windows, и он считывает список программ /dll из файла настроек xml во время выполнения и загружает их в список и вызывает их метод execute() (если применимо) на любой частоте, которую они определили.
В моем случае каждая программа также содержит пользовательский элемент управления, который загружается на вкладку контроллера, что позволяет пользователю контролировать/изменять его. Если вы заинтересованы, я отправлю код.
Не уверен, что это было ясно. Я действительно получил идею от другого пользователя SO, который реализовал что-то подобное, но я не могу найти этот пост сейчас.
Ответ 5
Я использовал sc.exe, чтобы выполнить это легко. http://support.microsoft.com/kb/251192
Для ex: sc create "My Display Service Name" binpath= "c:\app\mysvc.exe --service"
Примечание: каждый равный должен иметь пробел перед его значением, как вы можете видеть для "binpath"
Ответ 6
У меня была такая же проблема сегодня, и мне удалось ее исправить.
В моем случае мне просто пришлось открыть файлы *.designer.cs моих сервисов и убедиться, что имя службы установлено правильно. Более того, одно и то же имя должно использоваться в * Installer.Designer.cs, и если у вас есть код в * Installer.cs.
Я думаю, что эта ошибка возникает только из-за несоответствия имени.
Надеюсь, что эта подсказка
Ответ 7
Установка 2-х разных и несвязанных сервисов в одном исполняемом файле имеет смешной запах. Хотя это позволяет заставить его работать, это не делает все правильно.
Из того, что это звучит, вам нужно выполнить несколько разных заданий с различными интервалами, и ваши задачи могут или не могут быть связаны. Вы заглянули в Quartz.NET? Это звучит как подходящее для ваших нужд.
http://quartznet.sourceforge.net/features.html