Можно ли установить несколько экземпляров одного и того же приложения-службы delphi? - PullRequest
8 голосов
/ 05 марта 2009

У меня есть сервисное приложение, встроенное в Delphi, которое прекрасно работает. Он делает именно то, что я хочу, и все счастливы. Все в порядке, пока я не хочу запустить два (или более) экземпляра этой службы на одной машине. Поскольку имя службы жестко запрограммировано в программе (через свойство Name службы), я могу установить службу только один раз на любом компьютере. Если я пытаюсь изменить свойство Name во время выполнения, служба не отвечает, если для свойства Name не установлено то же значение, которое было задано во время разработки.

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

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

Можно ли как-нибудь изменить свой код, чтобы у меня был только один проект Delphi, который можно установить и запустить как несколько экземпляров службы с простым вводом во время выполнения (например, с помощью флага командной строки)?

Или, возможно, более широкий вопрос: есть ли "правильный путь" для достижения цели?

Ответы [ 5 ]

14 голосов
/ 05 марта 2009

Вы не дали понять, что пытались изменить в подклассе TService.

Вы добавили обработчик "BeforeInstall"?

Что-то вроде:

procedure TServiceMain.ServiceLoadInfo(Sender : TObject);// new method, not an override
begin
  Name := ParamStr(2);
  DisplayName := ParamStr(3);
end;

procedure TServiceMain.ServiceBeforeInstall(Sender: TService);
begin
  ServiceLoadInfo(Self);
end;
procedure TServiceMain.ServiceCreate(Sender: TObject);
begin
  ServiceLoadInfo(Self);
end;

Если вы делаете это регулярно, подкласс TService, чтобы сделать это в Конструкторе.

Вы должны сделать то же самое в BeforeUninstall, а также указать оба события одним и тем же методом.

C:\>servicename /install MyService "My Service Description"
3 голосов
/ 05 марта 2009

Вы можете создать свой сервис с несколькими внутренними потоками, каждый из которых действует как собственная версия / копия сервиса. Вы управляете этим с помощью API Service Controller, IIRC.

2 голосов
/ 05 марта 2009

Ну, да, возможно установить несколько экземпляров одной и той же службы, вам просто нужно динамически изменить имя во время установки (не во время выполнения), однако это не делает его желательным. (есть некоторый пример кода в проекте Code http://www.codeproject.com/KB/dotnet/MultipleInstNetWinService.aspx)

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

0 голосов
/ 26 января 2010

Принятый ответ выше был очень полезным.

Код, который я использовал:

procedure TService1.ServiceAfterInstall(Sender: TService);
begin
///586239/mozhno-li-ustanovit-neskolko-ekzemplyarov-odnogo-i-togo-zhe-prilozheniya-sluzhby-delphi
//http://www.c-sharpcorner.com/UploadFile/timosten/DynamicServiceInCSharp11262005062503AM/DynamicServiceInCSharp.aspx?ArticleID=4d5020e4-7317-425c-ab29-5bf37a1db421
//http://support.microsoft.com/kb/137890
  SaveRegSetting('\SYSTEM\CurrentControlSet\Services\' + Name, 'ImagePath', ParamStr(0) + ' --name=' + Name, HKEY_LOCAL_MACHINE)
end;

procedure TService1.ServiceCreate(Sender: TObject);
begin
  Name := Trim(FCommandLineOptions.Values['name']);
  DisplayName := Name;
end;

SaveRegSetting - это моя собственная процедура, а FCommandLineOptions - это объект, который маркирует параметры командной строки.

0 голосов
/ 05 марта 2009

Оберните весь ваш код в класс, который наследуется от TThread.

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

Каждый экземпляр работает независимо.

Чтобы изменить количество запущенных экземпляров, вы можете закрыть службу, отредактировать настройку (в файле или реестре) и перезапустить службу.

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