Entwickler-Ecke

Datenbanken - ADODB im Dienst läßt sich nicht starten


AndyM79 - Mi 12.01.11 16:01
Titel: ADODB im Dienst läßt sich nicht starten
Hallo,
habe folgendes Problem.
Ich möchte mit einer ADO Komponente über ODBC auf einem MSSQL Express Server zugreifen
In der Entwicklung kann ich eine Verbindung herstellen, wenn ich aber den Dienst starte bricht dieser direkt wieder ab.
kann hier keinen Fehler erkennen und bin etwas ratlos.

Hier der Quellcode:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
procedure TAurumPCService.ServiceStart(Sender: TService; var Started: Boolean);
var
  s : String;
  vfile : Textfile;
  vConnection, vUser, vPasswort, vKatalog : string;
  Reg: TRegistry;
begin
  Reg := TRegistry.Create(KEY_READ or KEY_WRITE);
  try
    Reg.RootKey := HKEY_LOCAL_MACHINE;
    if Reg.OpenKey('\SYSTEM\CurrentControlSet\Services\' + Name, false) then
    begin
      vPfad := Reg.ReadString('Pfad');
      Reg.CloseKey;
    end;
  finally

    Reg.Free;
  end;
  Assignfile(vfile,vPfad + '\a3pc.ini');
  Reset(vfile);
  while not eof(vfile) do
  begin
    Readln(vfile,s);
    if Pos('Connection=',s) > 0 then
      vConnection := trim(copy(s,Pos('=',s)+1,Length(s)));
    if Pos('User=',s) > 0 then
      vUser := trim(copy(s,Pos('=',s)+1,Length(s)));
    if Pos('Pass=',s) > 0 then
      vPasswort := trim(copy(s,Pos('=',s)+1,Length(s)));
    if Pos('Table=',s) > 0 then
      vKatalog := trim(copy(s,Pos('=',s)+1,Length(s)));
  end;
  Closefile(vfile);
  ADOConnection.ConnectionString := 'Provider=MSDASQL.1;' +
                              'Password=' + vPasswort + ';'+
                              'Persist Security Info=True;'+
                              'User ID=' + vUser + ';'+
                              'Data Source=' + vConnection + ';' +
                              'Initial Catalog=' + vKatalog  + ';';
  ADOConnection.Connected := true;
end;


wie gesagt wenn ich in der Entwicklung Connected auf true setze mit dem entsprechenden ConnectionString kein Problem
wenn ich den Dienst starte wird dieser mit der Meldung: Dienst wurde gestaret und angehalten. Einige Dienste werden automatisch angehalten....
beendet.
Nehme ich die Zeile "ADOConnection.Connected := true;" raus startet der Dienst normal

Gruß
Andy

Moderiert von user profile iconNarses: Code- durch Delphi-Tags ersetzt


Klabautermann - Mi 12.01.11 17:17

Hallo,

also erst einmal möchte ich dich auf die Klassen tIniFile und tMemIniFile hinweisen, mit denen sollte sich das Auflesen der Datei vereinfachen lassen.

Aber zum Thema zurück. In fällen, wie diesem würde ich mir noch einmal alles genau angucken, was im Designer anders ist, als zur Laufzeit in diesem Fall natürlich insbesondere den Connection-String. Lasse dir den am besten einmal, nachdem er zusammen kopiert wurde, ausgeben und vergleiche ihn mit dem was du in der IDE eingetragen hast. In deinen Copy-Anweisungen Kopierst du über das Zeilenende hinaus (der letzte Parameter gibt nicht an bis zu welcher Position kopiert werden soll, sondern wie viele Zeichen Kopiert werden sollen), vielleicht kommt da einfach noch etwas mit, was trim dir nicht wieder löscht, wodurch du dann einen kaputten String erhältst.

Erst wenn du solchen Fehlerquellen ausgeschlossen hast solltest du dich um die Services kümmern, da verwirrende/fehlerhafte Fehlermeldungen leider nicht so selten sind. Also erst die banalen Fehlerquellen angehen (einfach mal an jedem Kabel ruckeln und gucken ob es dann wieder geht ;)).

Gruß
Klabautermann

PS: Müssen deine eingefügten Strings im Connection-String vielleicht (teilweise) in Anführungszeichen gesetzt werden?


Muck - Mi 12.01.11 21:44

Hallo,

wenn Du ADO im Dienst nutzen willst binde ActiveX ein.
Vor dem ersten Benutzen (oder im Service Start) rufe

Delphi-Quelltext
1:
CoInitialize(nil);                    


auf
Dann, nachdem Du die ADO Connection schliesst (oder im Service Stop) rufe

Delphi-Quelltext
1:
CoUnintialize;                    


auf. Dann sollte auf jeden Fall die ADOConnection keinen Fehler mehr liefern.
Ausserdem aufpassen mit welchen Benutzerkonto der Dienst laeuft, es kann sein, dass Du keinen Zugriff auf das Verzeichnes der ini Datei hast.

Ach ja, am Ende des ServiceStart Events ein

Delphi-Quelltext
1:
Started:=true;                    

einbauen. Dann wird Windows den Dienst auch als Gestartet anzeigen.

Markus


AndyM79 - Do 13.01.11 08:48

danke für die schnellen Antworten. leider immer noch die selbe Meldung.
@Klabautermann
danke für den Tipp mit der TiniFile, habe ich direkt mal eingebaut

@Muck
auch dir danke, hilf leider nicht

habe mit den ConnectionString in eine Log-File geschrieben und diesen dann mal direkt in die ADOConnection kopiert, klappt
Quellcode sieht jetzt so aus


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
procedure TAurumPCService.ServiceStart(Sender: TService; var Started: Boolean);
var
  vfile : Textfile;
  ini : TIniFile;
  vConnection, vUser, vPasswort, vKatalog : string;
  Reg: TRegistry;
begin
  CoInitialize(nil);
  Reg := TRegistry.Create(KEY_READ or KEY_WRITE);
  try
    Reg.RootKey := HKEY_LOCAL_MACHINE;
    if Reg.OpenKey('\SYSTEM\CurrentControlSet\Services\' + Name, false) then
    begin
      vPfad := Reg.ReadString('Pfad');
      Reg.CloseKey;
    end;
  finally
    Reg.Free;
  end;
  ini := TIniFile.Create(vPfad + '\a3pc.ini');
  try
    vConnection := ini.ReadString('MSSQL','Connection','');
    vUser := ini.ReadString('MSSQL','User','');
    vPasswort := ini.ReadString('MSSQL','Pass','');
    vKatalog := ini.ReadString('MSSQL','Table','');
  finally
    ini.Free;
  end;
  DC_A3PC.ConnectionString := 'Provider=MSDASQL.1;' +
                              'Password=' + vPasswort + ';'+
                              'Persist Security Info=True;'+
                              'User ID=' + vUser + ';'+
                              'Data Source=' + vConnection + ';' +
                              'Initial Catalog=' + vKatalog;
  Assignfile(vfile,vPfad + '\a3pc.log');
  if not FileExists(vPfad + '\a3pc.log'then
  begin
    Rewrite(vfile);
  end else
    Append(vfile);
  Writeln(vfile,DateTimeToStr(now) + '  ConnectionString="' + DC_A3PC.ConnectionString + '"');
  Closefile(vfile);
  DC_A3PC.Connected := true;
  Started := true;
end;


leider nach wie selbes Problem, lass ich Connected:= true weg, startet alles, anonsten bricht der Dienst direkt ab.
Gruß
Andy


bummi - Do 13.01.11 09:00

Häng mal in den Dienststart am Anfang ein Sleep(10000) rein, starte und wähle in Delphi mit Prozess verbinden, dann kannst Du das ganze debuggen, ansonsten

Delphi-Quelltext
1:
2:
3:
4:
5:
Try 
Ado.Open;
Except
ON E.Exeception do WriteLog(E.Message);
End;


AndyM79 - Do 13.01.11 09:01

OK, es läuft bis zum Connecten.
Hab beim Dienst noch den Benutzer geändert von Lokaler Dienst auf meinen Account, jetzt startet er.

Danke für die Tipps