![]() |
Dienst installieren + unter anderen Benutzerdaten starten
Hallo,
Ich habe einen Systemdienst in Delphi erstellt und möchte diesen zusammen mit einem kleinen Hilfsprogramm an den Kunden ausliefern. Über das Hilfsprogramm soll der Kunde die Möglichkeit haben, einen Windows Benutzeraccount anzugeben. Hierbei soll der Systemdienst installiert werden und unter dem angegebenen Benutzeraccount gestartet werden (sowas lässt sich unter Windows ansonsten über "Systemsteuerung -> Dienste -> <<Dienst doppelt anklicken>> -> Tab Anmelden" konfigurieren). Die Installation des Dienstes ist kein Problem. Dies geht ja über einen zusätzlichen Parameter "-install". Lassen sich so vielleicht auch die entsprechenden Zugangsdaten als Parameter übermitteln? Leider habe ich diesbezüglich nichts im Forum gefunden. |
Re: Dienst installieren + unter anderen Benutzerdaten starte
Ein Dienst wird normalerweise gestartet, bevor sich jemand am System anmelden kann, beim Booten.
Der Dienst kann sich mit einer Benutzerkennugn anmelden. Normalerweise ist dies "Administrator". |
Re: Dienst installieren + unter anderen Benutzerdaten starte
Hallo RavenIV,
Danke für deine Antwort. Das ist klar, ich glaub ich hab mich etwas missverständlich ausgedrückt. Das kleine Hilfsprogramm soll lediglich den Dienst installieren und dabei schon bestimmte Anmeldedaten für diesen Dienst hinterlegen - unter welchen er beim Systemstart ausgeführt werden soll. Ich möchte so dem Endanwender lediglich den Weg über "Systemsteuerung -> Dienste" ersparen. |
Re: Dienst installieren + unter anderen Benutzerdaten starte
Ich habe schon seit einer Weile das gleiche Problem. Installieren, starten und stoppen mache ich mit folgenden Funktionen:
Delphi-Quellcode:
Bloss, wie ich dem Dienst vor dem Starten einen anderen Benutzer zuweisen muss, habe ich noch nicht heraus gefunden. Ich werde diesen Thread aber noch im Auge behalten.
procedure ServiceInstall;
var SvcMgr, Svc: HWND; begin SvcMgr := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS); try Svc := CreateService(SvcMgr, APPLICATION_NAME, PChar(APPLICATION_NAME), SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, PChar(WorkDir + FILE_SERVICE), '', nil, '', nil, ''); finally CloseServiceHandle(Svc); end; CloseServiceHandle(SvcMgr); end; function ServiceStart(Machine, ServiceName: String): Boolean; //****************************************************************************** //* Parameter: //* Machine: Computername //* Service: Name des Dienstes //****************************************************************************** var h_manager, h_svc: SC_Handle; ServiceStatus: TServiceStatus; dwCheckPoint: DWORD; ServiceArgVectors: PChar; begin h_manager := OpenSCManager(PChar(Machine), nil, SC_MANAGER_CONNECT); if h_manager > 0 then begin h_svc := OpenService(h_manager, PChar(ServiceName), SERVICE_START or SERVICE_QUERY_STATUS or SC_MANAGER_ALL_ACCESS); if h_svc > 0 then begin if (StartService(h_svc, 0, ServiceArgVectors)) then { succeeded } begin if (QueryServiceStatus(h_svc, ServiceStatus)) then begin while (SERVICE_RUNNING <> ServiceStatus.dwCurrentState) do begin dwCheckPoint := ServiceStatus.dwCheckPoint; Sleep(ServiceStatus.dwWaitHint); if (not QueryServiceStatus(h_svc, ServiceStatus)) then // couldn't check status break; if (ServiceStatus.dwCheckPoint < dwCheckPoint) then break; end; end; end; CloseServiceHandle(h_svc); end; CloseServiceHandle(h_manager); end; Result := (SERVICE_RUNNING = ServiceStatus.dwCurrentState); end; function ServiceStop(Machine, ServiceName: String): Boolean; //****************************************************************************** //* Parameter: //* Machine: Computername //* Service: Name des Dienstes //****************************************************************************** var h_manager, h_svc: SC_Handle; ServiceStatus: TServiceStatus; dwCheckPoint: DWORD; begin h_manager := OpenSCManager(PChar(Machine), nil, SC_MANAGER_CONNECT); if h_manager > 0 then begin h_svc := OpenService(h_manager, PChar(ServiceName), SERVICE_STOP or SERVICE_QUERY_STATUS); if h_svc > 0 then begin if (ControlService(h_svc, SERVICE_CONTROL_STOP, ServiceStatus)) then begin if (QueryServiceStatus(h_svc, ServiceStatus)) then begin while (SERVICE_STOPPED <> ServiceStatus.dwCurrentState) do begin dwCheckPoint := ServiceStatus.dwCheckPoint; Sleep(ServiceStatus.dwWaitHint); if (not QueryServiceStatus(h_svc, ServiceStatus)) then // couldn't check status break; if (ServiceStatus.dwCheckPoint < dwCheckPoint) then break; end; end; end; CloseServiceHandle(h_svc); end; CloseServiceHandle(h_manager); end; Result := (SERVICE_STOPPED = ServiceStatus.dwCurrentState); end; |
Re: Dienst installieren + unter anderen Benutzerdaten starte
Hallo et2004,
Laut ![]() |
Re: Dienst installieren + unter anderen Benutzerdaten starte
Hallo Stephan,
es klappt! Danke für den Tip. Manche Funktionsbeschreibungen sollte man (ich) bis zum Ende durchlesen (grins).
Delphi-Quellcode:
Die letzten beiden Parameter waren die Lösung: Benutzername und Passwort. Beim Benutzernamen musste ich den Computernamen einfügen, da es immer ein lokaler Benutzer sein muss.
Svc := CreateService(SvcMgr, APPLICATION_NAME, PChar(APPLICATION_NAME), SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, PChar(WorkDir + FILE_SERVICE), '', nil, '', 'COMPUTER\Administrator', '*******');
Viele Grüssse |
Re: Dienst installieren + unter anderen Benutzerdaten starte
Hallo et2004,
Danke für deine Rückmeldung :) Zitat:
|
Re: Dienst installieren + unter anderen Benutzerdaten starte
Delphi-Quellcode:
Wenn ich das richtig verstehe, muss man dabei das Passwort in den Quelltext eingebe.
Svc := CreateService(SvcMgr, APPLICATION_NAME, PChar(APPLICATION_NAME), SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, PChar(WorkDir + FILE_SERVICE), '', nil, '', 'COMPUTER\Administrator', '*******');
Das beantwortet aber immer noch nicht die ursprüngliche Frage des Titels (Dienst installieren + unter anderen Benutzerdaten starte). Mich würde auch interessieren, ob eine Möglichkeit besteht, dem Dienst gleich bei der Installation entsprechende Benutzerdaten mitzugeben; möglichst auch gleich noch vom installierenden Benutzer abgefragt... Ich suche (mittlerweile krampfhaft) nach einer Lösung mittels Dienst auf Dateien einer Netzwerkfreigabe zuzugreifen. Ich könnte theoretisch auch den Benutzer System mit leerem Passwort auf dem Server anlegen, halte das aber nicht für sicher. Sollte das alles nicht klappen, werde ich wohl in den sauren Apfel beißen und eine Applikation bauen müssen, die als normales Programm einfach nur in den Tray minimiert und geschlossen wird. Gruß, Alex |
Re: Dienst installieren + unter anderen Benutzerdaten starte
Hallo,
bei einem Service gibt es die Methode
Delphi-Quellcode:
Hier müsstest Du mal probieren, ob Du an Kommandozeilenparameter kommst, ggfls. auch eine INI-Datei lesen, die das Installationsprogramm schreibt, bevor es den Dienst zur Installation aufruft.
procedure ServiceBeforeInstall(Sender: TService);
Paramstr(0)... sollte aber funktionieren, da diverse Dienste mit Parametern gestartet werden. Wenn Du ein eigenes Eventmessagefile für Deinen Dienst hast, muss Du dies in der Registrierung eintragen, das geht z. B. so:
Delphi-Quellcode:
Wenn wir hier schon in der Registrierung sind:
// Messagefile registrieren
procedure TReplikator.ServiceBeforeInstall(Sender: TService); Var Reg : TRegistry; begin Reg := TRegistry.Create; Reg.RootKey := HKEY_LOCAL_MACHINE; Reg.OpenKey('system\CurrentControlSet\Services\EventLog\Application\' + Self.Name,True); Reg.WriteString('EventMessageFile',ParamStr(0)); Reg.WriteInteger('TypesSupported',7); Reg.CloseKey; Reg.OpenKey('system\CurrentControlSet\Services\Replikator\' + Self.Name,True); Reg.WriteString('Description','Repliziert die Daten zwischen Asterix und Obelix'); Reg.CloseKey; Reg.Free; end; Auf der gleichen Ebene gibt es für die Dienste, die einen anderen Benutzer verwenden, einen Eintrag "ObjectName", der den Namen des Benutzerkontos enthält. Bei dem Dienst "aspnet_state" ist das z. B. zu sehen. Hier würde also die Zeile
Delphi-Quellcode:
eventuell schon reichen.
Reg.WriteString('ObjectName',ParamStr(2));
Was ich (noch) nicht herausgefunden habe, ist, wird das Passwort gespeichert, wenn ja wo und wie? Reicht es eventuell aus, dass in der Systemsteuerung beim Eintragen der Anmeldung das richtige Passwort eingegeben wird? (Wäre wohl etwas zu billig.) Eventuell wirst Du hierzu ja bei MSDN oder so fündig. Stephan |
Re: Dienst installieren + unter anderen Benutzerdaten starte
Zitat:
Ich komme aber nicht dahinter, wie ich das mit dem Benutzernamen/Passwort machen kann. Ich bin daher dazu übergegangen, meinen "Dienst" als VCL-Applikation ohne Fenster zu schreiben und das Beenden zu unterbinden. Das hat den Nachteil kein Dienst zu sein. Aber es hat auch den Vorteil, ohne zutun als angemeldeter Benutzer zu laufen und gleich ein Formular mitzuliefern, welches ich für meine Interaktion sowieso brauche. Letzteres ist ja - so entnehme ich es diversen Äußerungen im Forum - sicherheitstechnisch gesehen riskant. Das Fenster blende ich einfach ein und aus... [edit] Zum Starten trage ich es einfach so ein:
Delphi-Quellcode:
[/edit]
**Reg:=TRegistry.Create;
Reg.RootKey:=HKEY_LOCAL_MACHINE; Reg.OpenKey('SOFTWARE\Microsoft\Windows\CurrentVersion\Run',True); Reg.WriteString('Mein Programm',ParamStr(0)); Reg.Free; Gruß, Alex |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:15 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz