Hallo,<br>
ich versuche einen NT Service aus der <i>ServiceStart</i> Routine eines anderen Service zu starten. Das klappt auch, nur dass man die Fehlermeldung bekommt, dass der (aufrufende) Service nicht korrekt gestartet werden konnte (obwohl dieser läuft). Gibt es in diesem speziellen Fall vielleicht etwas zu beachten?<br>
Hier vielleicht noch ein Stück Code:<br>
<pre>
procedure TNTInvClientInit.ServiceStart(Sender: TService; var Started: Boolean);
var
mgr, svc : THandle;
Status : TServiceStatus;
p : PChar;
SysDir : Array [0..254] of char;
HWndProgMan : THandle;
begin
// COM+ initialisieren. Das muss gemacht werden, weil für den Dienst ein
// Thread abgespalten wird. Immer wenn man auf COM Objekte zugreift (hier z.B. RDS)
// muss man das explizit tun. (s.a. A.Kosch Delphi Win32 Lösungen Seite 472/473)
CoInitialize(nil);
mgr := 0;
svc := 0;
GetSystemDirectory(SysDir, SizeOf(SysDir));
FSysDir := AppendDirBackSlash(SysDir);
try
mgr := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
if mgr = 0 then
begin
FEventLogger.LogMessage('Service-Manager nicht erreicht!', EVENTLOG_WARNING_TYPE, 0, 1);
exit;
end;
svc := OpenService(mgr, INVSERVICE_NAME, SERVICE_ALL_ACCESS);
if svc = 0 then
begin
// Service (noch) nicht vorhanden, nichts tun
FEventLogger.LogMessage('Service '+INVSERVICE_NAME+' nicht gefunden!', EVENTLOG_WARNING_TYPE, 0, 1);
exit;
end
else
begin
// NTInvClient Service stoppen
QueryServiceStatus(svc, Status);
// Wenn NTInvClient läuft, diesen stoppen
if Status.dwCurrentState = SERVICE_RUNNING then
begin
ControlService(svc, SERVICE_CONTROL_STOP, Status);
end;
end;
if (svc <> 0) then
begin
// Warten bis Service gestoppt ist
QueryServiceStatus(svc, Status);
while (Status.dwCurrentState <> SERVICE_STOPPED) do
QueryServiceStatus(svc, Status);
if Status.dwCurrentState = SERVICE_STOPPED then
begin
// Update checken
if UpdateInvClientService = 0 then
begin
// NTInvClient wieder starten (wenn Update erfolgreich war);
QueryServiceStatus(svc, Status);
if Status.dwCurrentState <> SERVICE_RUNNING then
begin
p := nil;
// BIS HIERHIN GING ES:
{ TEST *** KANN WIEDER RAUS }
// AKTUELLER TESTPUNKT
Started := TRUE;
exit;
{ TEST ENDE *** KANN WIEDER RAUS }
// ###################################
// STARTSERVICE MACHT DAS PROBLEM !!!!!!
// ###################################
StartService(svc, 0, p);
end;
end;
end;
end;
finally
if mgr <> 0 then CloseServiceHandle(mgr);
if svc <> 0 then CloseServiceHandle(svc);
end;
Started := TRUE;
end;
</pre>
Viele Grüsse<br>
Hermann
ich versuche einen NT Service aus der <i>ServiceStart</i> Routine eines anderen Service zu starten. Das klappt auch, nur dass man die Fehlermeldung bekommt, dass der (aufrufende) Service nicht korrekt gestartet werden konnte (obwohl dieser läuft). Gibt es in diesem speziellen Fall vielleicht etwas zu beachten?<br>
Hier vielleicht noch ein Stück Code:<br>
<pre>
procedure TNTInvClientInit.ServiceStart(Sender: TService; var Started: Boolean);
var
mgr, svc : THandle;
Status : TServiceStatus;
p : PChar;
SysDir : Array [0..254] of char;
HWndProgMan : THandle;
begin
// COM+ initialisieren. Das muss gemacht werden, weil für den Dienst ein
// Thread abgespalten wird. Immer wenn man auf COM Objekte zugreift (hier z.B. RDS)
// muss man das explizit tun. (s.a. A.Kosch Delphi Win32 Lösungen Seite 472/473)
CoInitialize(nil);
mgr := 0;
svc := 0;
GetSystemDirectory(SysDir, SizeOf(SysDir));
FSysDir := AppendDirBackSlash(SysDir);
try
mgr := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
if mgr = 0 then
begin
FEventLogger.LogMessage('Service-Manager nicht erreicht!', EVENTLOG_WARNING_TYPE, 0, 1);
exit;
end;
svc := OpenService(mgr, INVSERVICE_NAME, SERVICE_ALL_ACCESS);
if svc = 0 then
begin
// Service (noch) nicht vorhanden, nichts tun
FEventLogger.LogMessage('Service '+INVSERVICE_NAME+' nicht gefunden!', EVENTLOG_WARNING_TYPE, 0, 1);
exit;
end
else
begin
// NTInvClient Service stoppen
QueryServiceStatus(svc, Status);
// Wenn NTInvClient läuft, diesen stoppen
if Status.dwCurrentState = SERVICE_RUNNING then
begin
ControlService(svc, SERVICE_CONTROL_STOP, Status);
end;
end;
if (svc <> 0) then
begin
// Warten bis Service gestoppt ist
QueryServiceStatus(svc, Status);
while (Status.dwCurrentState <> SERVICE_STOPPED) do
QueryServiceStatus(svc, Status);
if Status.dwCurrentState = SERVICE_STOPPED then
begin
// Update checken
if UpdateInvClientService = 0 then
begin
// NTInvClient wieder starten (wenn Update erfolgreich war);
QueryServiceStatus(svc, Status);
if Status.dwCurrentState <> SERVICE_RUNNING then
begin
p := nil;
// BIS HIERHIN GING ES:
{ TEST *** KANN WIEDER RAUS }
// AKTUELLER TESTPUNKT
Started := TRUE;
exit;
{ TEST ENDE *** KANN WIEDER RAUS }
// ###################################
// STARTSERVICE MACHT DAS PROBLEM !!!!!!
// ###################################
StartService(svc, 0, p);
end;
end;
end;
end;
finally
if mgr <> 0 then CloseServiceHandle(mgr);
if svc <> 0 then CloseServiceHandle(svc);
end;
Started := TRUE;
end;
</pre>
Viele Grüsse<br>
Hermann
Comment