Форум: "Основная";
Текущий архив: 2012.01.01;
Скачать: [xml.tar.bz2];
ВнизКак передать параметры при инсталляции сервиса Найти похожие ветки
← →
Дмитрий Белькевич (2010-07-14 22:44) [0]Можно ли как-то в наследнике TService при инсталляции сервиса задать параметры командной строки последующего запуска сервиса?
← →
Leonid Troyanovsky © (2010-07-14 22:59) [1]
> Дмитрий Белькевич (14.07.10 22:44)
> Можно ли как-то в наследнике TService при инсталляции сервиса
> задать параметры командной строки
http://rsdn.ru/?summary/2393.xml читал?
--
Regards, LVT.
← →
Дмитрий Белькевич (2010-07-15 00:40) [2]Смотрю сырцы TService:
procedure TServiceApplication.RegisterServices(Install, Silent: Boolean);
procedure InstallService(Service: TService; SvcMgr: Integer);
var
TmpTagID, Svc: Integer;
PTag, PSSN: Pointer;
Path: string;
begin
Path := ParamStr(0);
with Service do
begin
if Assigned(BeforeInstall) then BeforeInstall(Service);
TmpTagID := TagID;
if TmpTagID > 0 then PTag := @TmpTagID else PTag := nil;
if ServiceStartName = "" then
PSSN := nil else
PSSN := PChar(ServiceStartName);
Svc := CreateService(SvcMgr, PChar(Name), PChar(DisplayName),
SERVICE_ALL_ACCESS, GetNTServiceType, GetNTStartType, GetNTErrorSeverity,
PChar(Path), PChar(LoadGroup), PTag, PChar(GetNTDependencies),
PSSN, PChar(Password));
Как я понял, параметры будущего сервиса нужно передавать в параметре "Path" (lpBinaryPathName):
"Pointer to a null-terminated string that contains the fully qualified path to the service binary file. If the path contains a space, it must be quoted so that it is correctly interpreted. For example, "d:\\my share\\myservice.exe" should be specified as "\"d:\\my share\\myservice.exe\"".
The path can also include arguments for an auto-start service. For example, "d:\\myshare\\myservice.exe arg1 arg2"."
Так вот - в TService туда название экзешника просто передаётся. И, как я понял, это изменить никак нельзя. Что же делать? Делать в два захода? Инсталлироваться, как есть, а потом менять параметры сервиса?
← →
Leonid Troyanovsky © (2010-07-15 08:34) [3]
> Дмитрий Белькевич (15.07.10 00:40) [2]
> Инсталлироваться, как есть, а потом менять параметры сервиса?
AfterInstall ChangeServiceConfig.
--
Regards, LVT.
← →
sniknik © (2010-07-15 09:22) [4]лучше не закладываться на параметры командной строки, т.к. сервис могут установить не только запустив его екзешник, но и просто командами контролеру.
ну или учитывать это и в доке прописать - устанавливать только так ... ххх ...
← →
Дмитрий Белькевич (2010-07-15 09:45) [5]Спасибо, так и сделаю.
← →
Дмитрий Белькевич (2010-07-15 10:24) [6]Набросал небольшой класс... Может кому-то пригодится. Мне в классе не нравится то, что приходится AfterInstall менять. Потенциальный баг - если в наследниках поменять AfterInstall еще раз (прописать обработчик), то не будут применяться изменения, вносимые OnAfterInstall. Если кто-то знает, как это исправить, было бы интересно увидеть исправления.
Код для D2010.
const
SERVICE_CONFIG_DESCRIPTION = 1;
SERVICE_CONFIG_FAILURE_ACTIONS = 2;
type
_SC_ACTION_TYPE = (SC_ACTION_NONE, SC_ACTION_RESTART, SC_ACTION_REBOOT, SC_ACTION_RUN_COMMAND);
SC_ACTION_TYPE = _SC_ACTION_TYPE;
TScActionType = _SC_ACTION_TYPE;
_SC_ACTION = record
aType: SC_ACTION_TYPE;
Delay: DWORD;
end;
SC_ACTION = _SC_ACTION;
PSC_ACTION = ^SC_ACTION;
TScAction = SC_ACTION;
TSC_ACTION_Array = array of SC_ACTION;
_SERVICE_FAILURE_ACTIONSW = record
dwResetPeriod: DWORD;
lpRebootMsg: LPWSTR;
lpCommand: LPWSTR;
cActions: DWORD;
lpsaActions: TSC_ACTION_Array;
end;
SERVICE_FAILURE_ACTIONS = _SERVICE_FAILURE_ACTIONSW;
TServiceFailureActions = _SERVICE_FAILURE_ACTIONSW;
type
TMakhService = class(TService)
private
FDescription: string;
FStartParams: string;
procedure OnAfterInstall(Sender: TService);
public
FailureActions: TServiceFailureActions;
constructor CreateNew(AOwner: TComponent; Dummy: integer = 0); override;
property Description: string Read FDescription Write FDescription;
property StartParams: string Read FStartParams Write FStartParams;
end;
constructor TMakhService.CreateNew(AOwner: TComponent; Dummy: integer);
begin
inherited;
AfterInstall := OnAfterInstall;
end;
procedure TMakhService.OnAfterInstall(Sender: TService);
var
Svc: SC_HANDLE;
SvcMgr: SC_HANDLE;
Path: string;
begin
Path := ParamStr(0) + " " + FStartParams;
SvcMgr := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
if SvcMgr <> 0 then
try
Svc := OpenService(SvcMgr, PChar(Sender.Name), SERVICE_ALL_ACCESS);
if Svc <> 0 then
try
if not ChangeServiceConfig(Svc, // handle of service
SERVICE_NO_CHANGE, // service type
SERVICE_NO_CHANGE, // change service start type
SERVICE_NO_CHANGE, // error control
PChar(Path), // binary path
nil, // load order group
nil, // tag ID
nil, // dependencies
nil, // account name
nil, // password
nil // Display Description
) then
RaiseLastOSError;
if not ChangeServiceConfig2(Svc, SERVICE_CONFIG_FAILURE_ACTIONS, @FailureActions) then
RaiseLastOSError;
if not ChangeServiceConfig2(Svc, SERVICE_CONFIG_DESCRIPTION, @Description) then
RaiseLastOSError;
finally
CloseServiceHandle(Svc);
end;
finally
CloseServiceHandle(SvcMgr);
end;
end;
← →
Дмитрий Белькевич (2010-07-15 10:29) [7]
> ну или учитывать это и в доке прописать - устанавливать
> только так ... ххх ...
Мы сервис устанавливаем и деинсталлируем своим инсталлером. Думаю, что всё нормально будет работать.
← →
Leonid Troyanovsky © (2010-07-15 11:28) [8]
> Дмитрий Белькевич (15.07.10 10:24) [6]
> изменения, вносимые OnAfterInstall. Если кто-то знает, как
> это исправить, было бы интересно увидеть исправления.
Можно TServiceApplication.RegisterServices; override.
Только придется в initialization пересоздать ServiceApplication,
что ради одного install как-то избыточно.
Проще, IMHO, сохранить старый обработчик, если он назначен,
и вызвать его из нового.
> Мы сервис устанавливаем и деинсталлируем своим инсталлером.
А тогда и прописать его из инсталлера.
--
Regards, LVT.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2012.01.01;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.004 c