Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi IdMessage.SaveToFile Funktioniert nicht!??? (https://www.delphipraxis.net/11358-idmessage-savetofile-funktioniert-nicht.html)

NBG 5. Nov 2003 08:56


IdMessage.SaveToFile Funktioniert nicht!???
 
Habe nen POP3 Client geschrieben.

Immer wenn ich versuche ne E-Mail zu speichern über die SaveToFile methode von TIdMessage
dann wird folgende Exception beim durchtracen aufgerufen: Externel Exception C000001E.
beim komplett durchlaufen gibt's ne andere Fehlermeldung: Format '%p' ungültig oder nicht kompatiebel mit argument.

Das witzige ist, das die Mail gespeichert ist! jedoch fehlerhaft! wenn ich die mail wider lade,
ist dort zb. garkeine Massagepart einteilung mehr vorhannden. d.h. ich bekomme alle Parts im ersten Part siehe unten:

--_NextPart_2altrfkindysadvnqw3nerasdf
Content-Type: text/plain; charset"iso-8859-1"
Content-Transfer-Encoding: quoted-printable

...

--_NextPart_2altrfkindysadvnqw3nerasdf
Content-Type: text/html; charset"iso-8859-1"
Content-Transfer-Encoding: quoted-printable

...

ich habe mal die SaveToFile Methode getraced, dabei ist mir aufgefallen, das die Mail in einem
filestream geschrieben wird. Beim Free des Filestreams gibts dann ne Exception.
Ich denke aber das es vorher auch schon ne exception gab, die abgefangen wurde. kein plan?
gibt es ne möglichkein abgefangene Exceptions anzuzeigen?

Hier mal mein Soure vieleicht fällt jemanden was auf:

Delphi-Quellcode:
procedure TfrmEmailempfang.BtnOKClick(Sender: TObject);
var
  i : Integer;
  Filename : String;
  EMail: TEmail;

  function lfd(path : String) : Integer;
  begin
    Result := 0;
    while FileExists(path + '\' +FormatFloat('00000000', Result) + '.eml') do inc(Result);
  end;

begin
  Filename := MailPath + User;
  ForceDirectories(Filename);
  for i := 1 to StrGridEMails.RowCount-1 do
    if (Integer(StrGridEMails.Objects[0, i]) = 3) or
       (Integer(StrGridEMails.Objects[0, i]) = 2) then Inc(MailSum);
  for i := 1 to StrGridEMails.RowCount-1 do
  begin
    if (Integer(StrGridEMails.Objects[0, i]) = 3) or
       (Integer(StrGridEMails.Objects[0, i]) = 2) then begin
      IdMessage.Clear;
      POP3.Retrieve(StrGridEMails.RowCount-i-1, IdMessage);
      Filename := MailPath + User + '\' + FormatFloat('00000000', lfd(FileName)) + '.eml';
        IdMessage.SaveToFile(Filename);
    end;
    if (Integer(StrGridEMails.Objects[0, i]) = 4) or
       (Integer(StrGridEMails.Objects[0, i]) = 2) then
      POP3.Delete(StrGridEMails.RowCount - i);
  end;
  Close;
end;
Ich benutze übrigens die neuste Indy version 9.0.14
Vielen dank für Hilfen! Greatzzz...

NBG 5. Nov 2003 12:49

Re: IdMessage.SaveToFile Funktioniert nicht!???
 
Ok habe was herausgefunden!
die mail wird richtig abgespeichert, wenn man NoDecode auf True setzt!
aber die Exception gibt's nach wie vor :-(

ArrayOf.. 6. Nov 2003 00:29

Re: IdMessage.SaveToFile Funktioniert nicht!???
 
Zitat:

Ich denke aber das es vorher auch schon ne exception gab,...
Nicht eine Exception, sondern ein Free'n des Streams. Das Free'n des Filestreams in der TIdMessage.SaveToFile-Methode wäre danach also schon das zweite Mal hintereinander und würde demzufolge dann diese Exception verursachen.

Der eigentliche Fehler liegt aber noch eines tiefer, nämlich an LIOHS, diesem TIdIOHandlerStream, mittels dem diese IOAktion da abgewickelt wird. Da es bei diesen IORoutinen gelegentlich üblich ist, dass an sie übergebene Streams dann von ihnen auch gleich schon intern mit gefree't werden, wäre das also auch in unserem Falle der hier gesuchte Fehler. Und siehe da, beim Erzeugen von LIOHS wird im TIdIOHandlerStream-Konstruktor auch ein diesbezüglich so lautendes Feld 'FFreeStreams' auf TRUE gesetzt (welches also wie gesagt jetzt (unten, nach finally: FreeAndNil(LIOHS)) dafür sorgt, dass unser Stream fälschlicherweise schon intern gefreet wird). Wenn man also in der Zeile unter dem Konstruktor-Aufruf (innerhalb von TIdMessage.SaveToStream) dieses auf TRUE-Setzen gleich wieder rückgängig macht, und zwar mittels der dazugehörenden Property 'FreeStreams', dann funzt es danach auch ordnungsgemäß.


Code:
constructor TIdIOHandlerStream.Create(AOwner: TComponent);
begin
  inherited;
  FFreeStreams := True; // <===== verursacht bei uns nacher (indirekt) die Exception
end;


procedure TIdMessage.SaveToStream(AStream: TStream;
 const AHeadersOnly: Boolean = False);
var
  LMsgClient: TIdMessageClient;
  LIOHS: TIdIOHandlerStream;
begin
  LMsgClient := TIdMessageClient.Create(nil);
  try
    LIOHS := TIdIOHandlerStream.Create(nil);
    LIOHS.FreeStreams := false; // ====> wird fälschlicherweise im Creater darüber TRUE; ergo:...
(habe ich irgendwann/wo auch mal so ähnlich zur Kenntnis genommen ...handelt sich dabei wohl tatsächlich noch um einen echten Bug.)

NBG 6. Nov 2003 08:29

Re: IdMessage.SaveToFile Funktioniert nicht!???
 
Cool das war's! :-D
Vielen dank, ich dachte ich löse das Problem nie!
Thx!!!

himitsu 3. Mai 2006 19:24

Re: IdMessage.SaveToFile Funktioniert nicht!???
 
Tja und ich hab den gerade auch bekommen ... mein zweiter DebuggerBug -.-''

Zitat:

---------------------------
Benachrichtigung über Debugger-Exception
---------------------------
Im Projekt Demo.exe ist eine Exception der Klasse EExternalException aufgetreten. Meldung: 'Externe Exception C000001E'. Prozess wurde angehalten. Mit Einzelne Anweisung oder Start fortsetzen.
---------------------------
OK Hilfe
---------------------------
Nur das er bei mir wo anders auftaucht
Delphi-Quellcode:
Procedure Unlock(Var B: TByteLock);
  ASM
    LOCK   MOV BYTE PTR [&B], &False
  End;
Nicht threadsicher (also ohne LOCK) geht's aber so *peng*

Wenn ich das als ansehe, dann komm ich auf folgenden Fehler, aber was soll das in meinem Fall bedeuten, denn der Befehl MOV bringt ja nicht den Fehler :gruebel:
API_SEVERITY_ERROR+ERROR_READ_FAULT = The system cannot read from the specified device.

Umgangen hab ich das Problem jetzt zwar wie folgt, aber so richtig gefällt mir das nicht (also die sinnlose Lese- und Binäroperation) -.-''
Delphi-Quellcode:
Procedure Unlock(Var B: TByteLock);
  ASM
    LOCK   AND BYTE PTR [&B], 0
  End;


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:13 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