).Atentie: nu este vorba despre lansarea executabilului cu parametri din linie de comanda, ci despre parametrii care sa vor transmite functiei ServiceMain (sau obiectului de tip TService, daca e vorba despre un service scris in Delphi).
Atunci cand dorim sa trimitem un singur parametru, acest lucru se poate realiza simplu, apeland API-ul StartService in modul urmator: StartService('COMPUTER', 'SERVICE', PChar('PARAMETRU'));
Daca ne uitam insa pe MSDN la documentatia functiei StartService, vom vedea ca daca dorim sa pornim serviciul cu mai mult de un parametru, un simplu type-cast in PChar al unui sir de caractere ce contine toti parametrii nu va merge.
A rezultat astfel functia ServiceStartWithParam, care realizeaza ceea ce dorim si pe care o aveti mai jos.
Parametri ServiceStartWithParam:
aMachine - numele computerului pe care ruleaza serviciul
aService - numele serviciului (Atentie: Service Name, NU Display Name!)
aParams - un vector cu elemente de tip string ce va contine parametrii cu care va fi pornit serviciul
Rezultat ServiceStartWithParam:
True - serviciul a fost pornit
False - serviciul NU a fost pornit
- ...
- uses WinSvc;
- ...
- function ServiceStartWithParam(aMachine, aService: string; aParams: array of string): boolean;
- var
- lhSCM: SC_Handle;
- lhSvc: SC_Handle;
- lStatus: TServiceStatus;
- lCheckPoint: longint;
- lParamsArr: array of integer;
- iCounter: integer;
- begin
- lStatus.dwCurrentState := 0;
- // Conectare la SCM (Service Control Manager)
- lhSCM := OpenSCManager(PChar(aMachine), nil, SC_MANAGER_CONNECT);
- if(lhSCM > 0)then
- begin
- // Incercam sa obtinem un handle catre serviciu. Vrem sa-l interogam si sa-l pornim (SERVICE_START or SERVICE_QUERY_STATUS).
- lhSvc := OpenService(lhSCM, PChar(aService), SERVICE_START or SERVICE_QUERY_STATUS);
- if (lhSvc > 0) then
- begin
- // Adaugam parametrii intr-un array local
- SetLength(lParamsArr, Length(aParams) + 1);
- if (Length(aParams) <> 0) then
- for iCounter := 0 to Length(aParams) - 1 do
- lParamsArr[iCounter] := Integer(PChar(aParams[iCounter]));
- // Incercam sa pornim serviciul
- if (StartService(lhSvc, Length(aParams), PChar(lParamsArr[0]))) then
- begin
- // Verificare status
- if (QueryServiceStatus(lhSvc, lStatus)) then
- begin
- while (SERVICE_RUNNING <> lStatus.dwCurrentState) do
- begin
- // lCheckPoint contine o valoare pe care serviciul
- // o incrementeaza periodic pentru a raporta progresul.
- lCheckPoint := lStatus.dwCheckPoint;
- // Asteptam inainte de a verifica statusul din nou
- Sleep(lStatus.dwWaitHint);
- // Nu s-a putut verifica statusul, iesire din bucla
- if (not QueryServiceStatus(lhSvc, lStatus)) then
- Break;
- // QueryServiceStatus nu a incrementat dwCheckPoint, iesire din bucla
- if lStatus.dwCheckPoint < lCheckPoint then
- Break;
- end;
- end;
- end;
- // Inchidere handle serviciu
- CloseServiceHandle(lhSvc);
- end;
- // Inchidere handle SCM
- CloseServiceHandle(lhSCM);
- end;
- // Intoarcem TRUE daca statusul serviciului este RUNNING
- Result := SERVICE_RUNNING = lStatus.dwCurrentState;
- end;
Un exemplu de apel al functiei:
- procedure TForm1.Button1Click(Sender: TObject);
- var
- lArr: array of string;
- begin
- SetLength(lArr, 2);
- lArr[0] := 'Param_01';
- lArr[1] := 'Param_02';
- ServiceStartWithParam('COMPUTER_NAME', 'SERVICE_NAME', lArr);
- end;
Credits also to DarkByte
Welcome to BitCell. Click here to register !