Несколько служб Windows в одном exe - PullRequest
25 голосов
/ 03 мая 2009

Я пытаюсь создать несколько служб Windows для разных целей. Например, мне нужны службы Windows, которые будут:

  1. Отправить ежедневный отчет по электронной почте
  2. Периодически очищать некоторые архивные данные каждые 30 минут
  3. и т.д.

Задачи, для которых мне нужны службы 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);
    }

до:

    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?

Ответы [ 7 ]

15 голосов
/ 07 ноября 2009

Я понял, как иметь один исполняемый файл, но две службы. Каждая служба устанавливается в диспетчере служб со своим именем и возможностью запуска / остановки. Я думаю, это то, что вы хотите, правильно? Вот что я сделал:

  1. Создан сервисный проект.
  2. Добавлен второй сервис в тот же проект (с уникальным именем сервиса).
  3. Добавлен установщик для обеих служб (ServiceA и ServiceB).
  4. В файле ProjectInstaller.Designer.vb я изменил строку Me.Installers.AddRange, чтобы показать оба установщика службы. (Me.ServiceInstaller1, Me.ServiceInstaller2)
  5. В главной точке входа основной службы (в моем случае ServiceA) я установил переменную ServicesToRun в массив ServiceBase, содержащий все службы, которые я хочу, чтобы она выполнялась (ServiceA и ServiceB). Это важный шаг, так как менеджер сервисов устанавливает здесь свойство на основе количества аргументов - чтобы разрешить несколько экземпляров одного и того же exe или только один экземпляр.
  6. Добавьте проект установщика и используйте выходные данные Services.
  7. Добавить настраиваемое действие, используя выходные данные служб.

Демо-код можно найти здесь:
http://code.google.com/p/multi-service-install/

Наслаждайтесь!

5 голосов
/ 15 октября 2009

Полагаю, что вы, ребята, уже решили эту проблему, но если кому-то это понадобится, я опубликую ответ на этот вопрос, который занял у меня несколько часов сегодня. Решением является не добавление другого установщика проекта, а установщика службы, который является компонентом установщика проекта. У этого недавно добавленного установщика службы должно быть настроено второе имя службы.

2 голосов
/ 11 июня 2009

У меня была похожая проблема сегодня, и мне удалось ее решить.

Во-первых, я позаботился о том, чтобы каждая из служб имела осмысленное и уникальное свойство ServiceName. Генератор дал обеим службам одно и то же имя, которое не помогло бы.

Затем я удалил и заново сгенерировал класс ProjectInstaller и добавил установщики для каждого из классов. Я убедился, что они оба были созданы в статическом методе Main.

Теперь я могу установить две службы с одной DLL, но, к сожалению, когда я запускаю одну из служб, кажется, что она выполняет функции как самой, так и другой службы. То есть обе службы работают (даже если в Диспетчере компьютеров только одна из служб отображается как «Запущена»). Я все еще пытаюсь понять это ...

1 голос
/ 04 января 2011

Я использовал sc.exe, чтобы сделать это легко. http://support.microsoft.com/kb/251192

Например: sc create "My Display Service Name" binpath= "c:\app\mysvc.exe --service"

Примечание: каждый равный должен иметь пробел перед его значением, как вы можете видеть для 'binpath'

1 голос
/ 03 мая 2009

Я на самом деле строю что-то очень похожее на то, о чем вы думаете. Я решил (пока что), чтобы все мои «сервисы» (хотя они и не сервисы, а «контроллер») реализовали определенный интерфейс (с помощью операций init () и execute ()). как ЧАСТОТА перечисления).

Контроллер - это служба Windows, которая читает список программ / dll из файла настроек xml во время выполнения, загружает их в список и вызывает их метод execute () (если это применимо) с любой определенной им частотой. 1003 *

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

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

0 голосов
/ 20 ноября 2009

Установка двух разных и не связанных между собой сервисов в один исполняемый файл вызывает у меня странный запах. Хотя можно заставить его работать, но это не так.

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

http://quartznet.sourceforge.net/features.html

0 голосов
/ 12 октября 2009

У меня была такая же проблема сегодня, и мне удалось ее исправить. В моем случае мне просто нужно было открыть файлы * .designer.cs моих сервисов и убедиться, что имя сервиса установлено правильно. Что еще более важно, то же имя следует использовать в * Installer.Designer.cs и, если у вас есть код в * Installer.cs.

Я думаю, что эта ошибка возникает только из-за несоответствия имени.

Надеюсь, что это helpds

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...