WedX - журнал о программировании и компьютерных науках

Несколько служб Windows в одном exe

Я пытаюсь создать несколько служб 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);
    }

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?


  • Есть ли какая-то особая причина, кроме того, что я хочу, что вам нужно иметь службы в одном исполняемом файле? Обычно предпочтительнее использовать модульность, но могут быть смягчающие обстоятельства, требующие иного. 03.05.2009
  • Единственная реальная причина - простота установки и развертывания. Все службы представляют собой довольно быстрые, разовые функциональные возможности, поэтому я бы предпочел не устанавливать x количество служб Windows для небольших фрагментов кода. 04.05.2009
  • @pyrochild - Я уверен, что есть множество причин для монтирования нескольких сервисов в одной сборке. Там, где я работаю сейчас, мы используем зверей этого дизайна для каждого клиента - это упрощает тестирование программного обеспечения, которое взаимодействует с этими сервисами. 06.09.2011
  • Это может помочь 21.12.2016

Ответы:


1

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

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

Вы можете найти демонстрационный код здесь:
https://code.google.com/p/multi-service-install/

Наслаждаться!

06.11.2009
  • привет, спасибо за ваш комментарий, но я не понимаю пункта 4, не могли бы вы обновить свой код, пожалуйста 19.01.2021

  • 2

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

    15.10.2009
  • Мне пришлось использовать приведенную здесь деталь, чтобы рассказать мне, как это сделать: msdn.microsoft.com/en-us/library/zt39148a (v = vs.110) .aspx Для ленивых: откройте контекстное меню для окна дизайнера (если вы используете указатель устройства, щелкните правой кнопкой мыши внутри окна), а затем выберите Добавить установщик. 08.03.2016
  • @RitwikSen, я думаю, он имеет в виду тип проекта, который был доступен на момент написания (2009 г.), который создавал мастеров установки программ для конечных пользователей. Это было удалено, начиная с VS2012, но все еще доступно как расширение на торговой площадке VS. Но я бы порекомендовал использовать для этого что-то еще, так как он создает действительно устаревший интерфейс и имеет ошибку с 64-битными приложениями. 25.06.2018

  • 3

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

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

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

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

    11.06.2009

    4

    На самом деле я создаю нечто очень похожее на то, о чем вы думаете. То, что я решил сделать (на данный момент), - это реализовать все мои `` службы '' (хотя они и не являются службами, единственный `` контроллер '') реализовать определенный интерфейс (с операциями init () и execute (), а также как перечисление FREQUENCY).

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

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

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

    03.05.2009

    5

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

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

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

    04.01.2011
  • На случай, если кто-то попал сюда, как я, и хотел, чтобы это работало с sc.exe (то есть без установщика): --service в конце binpath - это параметр, который вы можете добавить в свой основной метод службы. Там вы можете выбрать, какую службу хотите запустить, в зависимости от этого параметра. Дополнительная информация здесь 25.04.2020

  • 6

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

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

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

    20.11.2009

    7

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

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

    Надеюсь, это поможет

    12.10.2009
    Новые материалы

    Как создать диаграмму градиентной кисти с помощью D3.js
    Резюме: Из этого туториала Вы узнаете, как добавить градиентную кисть к диаграмме с областями в D3.js. Мы добавим градиент к значениям SVG и применим градиент в качестве заливки к диаграмме с..

    Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что это выглядит сложно…
    Просто начните и учитесь самостоятельно Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что он кажется мне сложным, и я бросил его. Это в основном инструмент..

    Лицензии с открытым исходным кодом: руководство для разработчиков и создателей
    В динамичном мире разработки программного обеспечения открытый исходный код стал мощной парадигмой, способствующей сотрудничеству, инновациям и прогрессу, движимому сообществом. В основе..

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..


    Для любых предложений по сайту: [email protected]