Procedure in Datenmodul (TIdHTTP Komponente)
Hallo
Ich bin gerade dabei ein Service zu machen, der mit Http.get() Daten von einer Website ausließt. Ich habe versucht die Prozedur im Datenmodul zu programmieren und mit dm.MeineProzedure einzubinden. Leider bin ich nicht in die Prozedur hinein gekommen. Als ich versucht die Prozedur in meiner Haupt-Service Unit zu entwickeln und auf die Komponenten mit dm.IdHttp1 zu verweisen, hat es funktioniert. Ist es nicht möglich eine Prozedur vom Datenmodul einzubinden oder habe ich etwas falsch gemacht? (Ja das Datenmodul wurde erstellt laut Log Datei) |
AW: Procedure in Datenmodul (TIdHTTP Komponente)
Hallo und willkommen...
ich versuche das mal etwas zu ordnen: Du willst eine Prozedur in einem Datenmodul definieren und diese dann aufrufen? Dann muss die Prozedur in einem public Abschnitt definiert werden. Von der aufrufenden Stelle musst Du natürlich Zugriff auf die Datenmudulinstanz haben und dazu die Unit in der dortigen uses-Klausel eingebunden sein. Ggf. musst Du nochmal genauer beschreiben, was gegeben ist und wo es Probleme gibt. |
AW: Procedure in Datenmodul (TIdHTTP Komponente)
Danke für die schnelle Antwort
Also ich habe ein Datenmodul wo ich die Indy HTTP und Open SSL Komponente eingebunden habe. Weiters habe ich auch eine Prozedur:
Code:
Diese Prozedur möchte ich gerne in meinem Main Service aufrufen:
procedure TFrmDm.doDownload(Website: string; Outputfile: string);
var ResponseStream: TFileStream; begin WriteToLog('doDownload', 'Try to read'); ResponseStream := TFileStream.Create(Outputfile, fmCreate); IdHTTP1.IOHandler:= IdSSLIOHandlerSocketOpenSSL1; IdHTTP1.HandleRedirects:= true; try IdHTTP1.Get(Website, ResponseStream); WriteToLog('Timer1Timer','HTTP-Status: ' + IntToStr(IdHTTP1.ResponseCode)); finally ResponseStream.Free; end; WriteToLog('doDownload', 'Download abgeschlossen'); end;
Code:
Jedoch komme ich nicht in die Funktion hinein und der Timer startet immer von neuem ohne etwas zu tun.
procedure TEuropeanCentralBankCurrencyService.Timer1Timer(Sender: TObject);
begin WriteToLog('Timer1Timer','Start'); dm:= TFrmDm.Create(FrmDm); dm.doDownload(WEBSITE, outputFilePathName); WriteToLog('Timer1Timer','Finished'); self.DoStop; dm.Free; end; Habe auch versucht die Funktion in Public zu geben, aber das hat auch nichts genützt |
AW: Procedure in Datenmodul (TIdHTTP Komponente)
Delphi-Quellcode:
Was ist FrmDm? Wie oft gibt es dein datenmodul?
dm:= TFrmDm.Create(FrmDm);
|
AW: Procedure in Datenmodul (TIdHTTP Komponente)
Da es die Variabel FrmDm für die Klasse TFrmDm gibt, hätte ich eher dashier erwartet:
Delphi-Quellcode:
Befremdlich finde ich auch, dass dm in der Timerprozedure erstellt und freigegeben wird, aber die Variabel dazu nicht in der Prozedure deklariert ist, sondern eine globale Variabel zu sein scheint.
procedure TEuropeanCentralBankCurrencyService.Timer1Timer(Sender: TObject);
begin WriteToLog('Timer1Timer','Start'); FrmDm.doDownload(WEBSITE, outputFilePathName); WriteToLog('Timer1Timer','Finished'); DoStop; end; Sehe ich das richtig?
Delphi-Quellcode:
dm:= TFrmDm.Create(FrmDm);
Damit wird ein Datenmodul dm vom Typ TFrmDm erstellt, dessen Owner ein Datenmodul vom Typ TFrmDm ist? Das ist rekursionsverdächtig. |
AW: Procedure in Datenmodul (TIdHTTP Komponente)
Moin...:P
Zitat:
1. Wieso ein Timer? 2. Intervall des Timers? Vermutung: Der Intervall des Timers ist zu kurz. Das würde bedeuten, daß der Timer sich wieder selbst "aufruft" ('Timer startet immer von neuem') Lösung in diesem Falle: In Timer1Timer in der ersten Zeile den Timer deaktivieren und in der letzten Zeile wieder aktivieren. PS: Besser auf den Timer verzichten. :zwinker: |
AW: Procedure in Datenmodul (TIdHTTP Komponente)
Zitat:
Nur wenn ich die einzelnen Komponenten von meinem Datenmodul einbinde geht es. (also mit FrmDm.IdHttp). Aber das muss doch auch schöner gehen |
AW: Procedure in Datenmodul (TIdHTTP Komponente)
Zitat:
Das habe ich schon ein paar mal gehört das der Timer nicht die beste Lösung ist. Aber bis jetzt hat es immer funktioniert. Das mit dem Intervall kann auch nicht das Problem sein, da ich es, wie oben erklärt, schon funktioniert hat. Jedoch ohne Aufruf der Prozedur sondern der Komponenten. (Timer ist auf 1 Minute eingestellt... Das müsste reichen) Aber ich versuche mit Enabled auf false während des Durchlaufes. :) |
AW: Procedure in Datenmodul (TIdHTTP Komponente)
Zitat:
Steht die Ausgabe von
Delphi-Quellcode:
nie in der Logdatei?
WriteToLog('Timer1Timer','Start');
Oder steht es in der Logdatei, aber die Ausgabe von
Delphi-Quellcode:
fehlt?
WriteToLog('doDownload', 'Try to read');
Oder ...? Irgendwie reichen Deine Informationen noch nicht aus, um sich eine konkrete Vorstellung des Problemes machen zu können. Wäre es möglich den Quelltext des Projektes hier mal anzuhängen, einschließlich einer Logdatei, in der der Fehler nachzuvollziehen ist? |
AW: Procedure in Datenmodul (TIdHTTP Komponente)
Danke an alle die mir geholfen haben. Mein Programm funktioniert jetzt.
Jedoch bin ich mir unsicher was falsch war :cyclops:. Ich vermute es hat was mit der rekursion was zu tun. |
AW: Procedure in Datenmodul (TIdHTTP Komponente)
Hier ist mein Code... Vielleicht kann ihn wer gebrauchen :) :
Code:
nit main;
interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.SvcMgr, Vcl.Dialogs, Vcl.ExtCtrls, DMUnit; type TEuropeanCentralBankCurrencyService = class(TService) Timer1: TTimer; procedure ServiceAfterInstall(Sender: TService); procedure ServiceContinue(Sender: TService; var Continued: Boolean); procedure ServiceCreate(Sender: TObject); procedure WriteToLog(destination, Text: string); procedure ServiceExecute(Sender: TService); procedure ServicePause(Sender: TService; var Paused: Boolean); procedure ServiceStart(Sender: TService; var Started: Boolean); procedure ServiceStop(Sender: TService; var Stopped: Boolean); procedure Timer1Timer(Sender: TObject); private swLogFile: TStreamWriter; outputFileName, outputFilePath, outputFilePathName: String; currency: TStringList; const WEBSITE = 'https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml'; public function GetServiceController: TServiceController; override; { Public-Deklarationen } end; var EuropeanCentralBankCurrencyService: TEuropeanCentralBankCurrencyService; implementation {$R *.dfm} uses System.Win.Registry, System.ioutils; procedure TEuropeanCentralBankCurrencyService.WriteToLog(destination: string; Text: string); begin swLogFile.WriteLine('[' + DateTimeToStr(now) + '] ' + destination + ' schreibt: ' + text); end; procedure ServiceController(CtrlCode: DWord); stdcall; begin EuropeanCentralBankCurrencyService.Controller(CtrlCode); end; function TEuropeanCentralBankCurrencyService.GetServiceController: TServiceController; begin Result := ServiceController; end; procedure TEuropeanCentralBankCurrencyService.ServiceAfterInstall(Sender: TService); var 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 Reg.WriteString('Description', 'Dieses Service Synchronisiert die Daten European Central Bank'); Reg.CloseKey; end; finally Reg.Free; end; end; procedure TEuropeanCentralBankCurrencyService.ServiceContinue(Sender: TService;var Continued: Boolean); begin WriteToLog('ServiceContinue','Continued'); Continued:= true; end; procedure TEuropeanCentralBankCurrencyService.ServiceCreate(Sender: TObject); var ExePath, logFilePathName, logFileName, logFilePath: String; begin //Übergebe den Pfad der Exe ExePath := TPath.GetDirectoryName(GetModuleName(HInstance)); //Namen der Dateien logFileName := 'log_Service.txt'; outputFileName := 'currency.xls'; //Weise dem ExePath den jeweiligen Ordner zu logFilePath := TPath.Combine(exePath, 'logFile'); outputFilePath := TPath.Combine(exePath, 'OutputFile'); //Füge zu den Pfaden, die Namen hinzu logFilePathName := TPath.Combine(logFilePath, logFileName); outputFilePathName:= TPath.Combine(outputFilePath, outputFileName); //Erstelle Path wenn nicht existiert if not TDirectory.Exists(logFilePath) then TDirectory.CreateDirectory(logFilePath); if not TDirectory.Exists(outputFilePath) then TDirectory.CreateDirectory(outputFilePath); //Erstelle Log Stream Reader swLogFile := TStreamWriter.Create(TFileStream.Create(logFilePathName, fmCreate or fmShareDenyWrite)); currency:= TStringList.Create; end; procedure TEuropeanCentralBankCurrencyService.ServiceExecute(Sender: TService); begin while not Terminated do begin ServiceThread.ProcessRequests(false); TThread.Sleep(1000); end; end; procedure TEuropeanCentralBankCurrencyService.ServicePause(Sender: TService; var Paused: Boolean); begin WriteToLog('ServicePause', 'Paused'); Paused:= True; end; procedure TEuropeanCentralBankCurrencyService.ServiceStart(Sender: TService; var Started: Boolean); begin WriteToLog('ServiceStart', 'Service Started'); Started:= true; Timer1.Enabled:= true; end; procedure TEuropeanCentralBankCurrencyService.ServiceStop(Sender: TService; var Stopped: Boolean); begin WriteToLog('ServiceStop','Stopped'); Stopped:= true; end; procedure TEuropeanCentralBankCurrencyService.Timer1Timer(Sender: TObject); begin WriteToLog('Timer1Timer','Start'); FrmDm.doDownload(WEBSITE, outputFilePathName); WriteToLog('Timer1Timer','Finished'); end; end.
Code:
unit DMUnit;
interface uses System.SysUtils, System.Classes, IdIOHandler, IdIOHandlerSocket, IdIOHandlerStack, IdSSL, IdSSLOpenSSL, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdHTTP; type TFrmDm = class(TDataModule) IdHTTP1: TIdHTTP; IdSSLIOHandlerSocketOpenSSL1: TIdSSLIOHandlerSocketOpenSSL; procedure WriteToLog(Destination, Text: String); procedure DataModuleCreate(Sender: TObject); procedure doDownload(Website, Outputfile: String); private swLogFile: TStreamWriter; public end; var FrmDm: TFrmDm; implementation uses System.ioutils; {%CLASSGROUP 'Vcl.Controls.TControl'} {$R *.dfm} procedure TFrmDm.DataModuleCreate(Sender: TObject); var ExePath, logFilePathName, logFileName, logFilePath: String; begin //Übergebe den Pfad der Exe ExePath := TPath.GetDirectoryName(GetModuleName(HInstance)); //Namen der Dateien logFileName := 'log_DM.txt'; //Weise dem ExePath den jeweiligen Ordner zu logFilePath := TPath.Combine(exePath, 'logFile'); //Füge zu den Pfaden, die Namen hinzu logFilePathName := TPath.Combine(logFilePath, logFileName); //Erstelle Path wenn nicht existiert if not TDirectory.Exists(logFilePath) then TDirectory.CreateDirectory(logFilePath); //Erstelle Log Stream Reader swLogFile := TStreamWriter.Create(TFileStream.Create(logFilePathName, fmCreate or fmShareDenyWrite)); WriteToLog('DataModuleCreate', 'Created'); end; procedure TFrmDm.WriteToLog(destination: string; Text: string); begin swLogFile.WriteLine('[' + DateTimeToStr(now) + '] ' + destination + ' schreibt: ' + text); end; procedure TFrmDm.doDownload(Website: string; Outputfile: string); var ResponseStream: TFileStream; begin WriteToLog('doDownload', 'Try to read'); ResponseStream := TFileStream.Create(Outputfile, fmCreate); IdHTTP1.IOHandler:= IdSSLIOHandlerSocketOpenSSL1; IdHTTP1.HandleRedirects:= true; try IdHTTP1.Get(Website, ResponseStream); WriteToLog('Timer1Timer','HTTP-Status: ' + IntToStr(IdHTTP1.ResponseCode)); finally ResponseStream.Free; end; WriteToLog('doDownload', 'Download abgeschlossen'); end; end. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:12 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz