Autor Beitrag
adrian4321
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 41

Win2000, Linux (Suse9.0)
D5 Prof, D7 Pers, K3 OE
BeitragVerfasst: Di 04.07.06 14:20 
Hi!

Ich habe ein Problem mit der Indy-Komponente (genauer beim Zerlegen der Mails mitteld IdMessage). Auf das Problem möchte ich jetzt nicht mehr genauer eingehen, hab das schon in einigen Beiträgen erfolglos versucht.

Jedenfalls ist es so dass das Zerlegen von MultiParts der Mails nach bestimmten Situationen nicht mehr funktioniert (Indy gibt Schrott zurück...), nach einem Programmstart funktionierts jedenfalls immer mind. 1 Mal.

Daher habe ich mir als Krücke überlegt dass ich nach jeder Mail die Indy-Komponente zurücksetzen könnte (also quasi wie ein Programmneustart), möchte dabei aber nicht die restlichen Variablen in meinem Prog verlieren.

Der Befehl Message1.Clear von Indy scheint nicht alles zu resetten. Gibt es eine halbwegs vernünftige Lösung um alles was Indy betrifft nach jeder zerlegten Mail zurückzusetzen?

Danke für Eure Hilfe!
crowley
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 406

Win XP, Win Vista, Mandriva, Ubuntu
Delphi 4-8, Delphi 2006, Delphi 2007
BeitragVerfasst: Di 04.07.06 14:26 
wenn du's unbedingt brauchst, würd ich die benötigten Indy- Komponenten zur Laufzeit dynamisch erzeugen... und dann entsprechend mit FreeAndNil freigeben... dann kannst du sie vor dem Laden der nächsten Nachricht auch wieder erzeugen
adrian4321 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 41

Win2000, Linux (Suse9.0)
D5 Prof, D7 Pers, K3 OE
BeitragVerfasst: Di 04.07.06 15:18 
Ich weiss dass es keine schöne Lösung ist, aber ich habs nicht geschafft das Problem anders in den Griff zu bekommen. (ich beschreibs unten nochmal, habe es in diesem Forum noch nicht getan)...

Kannst Du mir bitte noch etwas genauer erklären wie ich die Komponenten dynamisch erzeuge und freigebe, hab das noch nie gemacht...


Also zum Problem an sich:
Ich möchte eingehende Mails in einer Tabelle ablegen (zerlegt in Betreff, Textkörper, Anhänge etc.). Dazu lade ich die Mail in die Indy-Message und klappere bei Multipart Mails jeden Multipart ab. Funktioniert prinzipiell wunderbar, es gibt aber Fälle (zb. wenn ich eine Mail 2 Mal durchlaufen lasse, oder 2 Mails durchlaufen lasse die sich irgendwie ähnlich sind, keine Ahnung warum....) nach denen mir Indy beim Content-Type des Multiparts nurnoch Schwachsinn zurückgibt, und zwar dann auch bei allen folgenden Mails. Nach einen Programmneustart zerlegt er mir dann auch die Mail bei der der Fehler anfing korrekt, bis es wieder irgendwann nicht mehr funktioniert....
crowley
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 406

Win XP, Win Vista, Mandriva, Ubuntu
Delphi 4-8, Delphi 2006, Delphi 2007
BeitragVerfasst: Di 04.07.06 15:33 
also... dynamisch anlegen ist recht einfach... merk dir aber, welche Einstellungen du im ObjektInspektor vorgenommen hast... denn die musst du dann im Quellcode machen...

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
type
  TMainForm = class(TForm)
  {...}
  private
    FIndyMessage : TIdMessage;
    {...}
  end;
{...}


Mein Problem ist gerade, dass ich hier auf meinem Arbeitsrechner keine Indy- Komponenten habe, daher mache ich das quasi gerade freihändig ;)


ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
procedure TMainForm.Button1Click(Sender: TObject);
begin
  if not Assigned(FIndyMessage) then begin
    FIndyMessage := TIdMessage.Create;  {weiss auswendig nicht, ob TIdMessage noch im constructor Parameter braucht}
    try
//      FIndyMessage.Property1 := '...';
        {... hier die Eigenschaften von deiner IndyMessage setzen}
    finally
      FreeAndNil(FIndyMessage);
    end;
  end;
end;  

procedure TMainForm.FormDestroy(Sender: TObject);
begin
  if Assigned(FIndyMessage) then 
    FreeAndNil(FIndyMessage);
end;


okay... an meinem obigen Ansatz kann man noch Dinge ändern... du kannst FIndyMessage auch innerhalb der "ButtonClick"- Routine deklarieren... dann ist es wie eine lokale Variable... mein Ansatz hat den Vorteil, dass du überall in deinem Form auf deine FIndyMessage zugreifen kannst... kannst ja das Erzeugen und das Freigeben deiner Message auf zwei Buttons/Ereignisse verteilen ;)
wichtig ist, dass du vor dem ersten Zugriff auf deine Message diese erzeugt hast... und auch, dass du sie spätestens im FormDestroy wieder freigibst

C.
adrian4321 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 41

Win2000, Linux (Suse9.0)
D5 Prof, D7 Pers, K3 OE
BeitragVerfasst: Di 04.07.06 15:42 
ok, herzlichen dank, die vorgehensweise ist mir nun auf jeden fall klar und ich werds gleich mal ausprobiern!
adrian4321 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 41

Win2000, Linux (Suse9.0)
D5 Prof, D7 Pers, K3 OE
BeitragVerfasst: Di 04.07.06 16:18 
So, habs eingebaut, funktioniert jetzt wunderbar. Keine Ahnung warum die Message-Komponente nach einigen Mails anfing Müll zurückzugeben, direkt nach dem Anlegen funktioniert sie mindestens für eine Mail lang korrekt.

Danke vielmals für die Hilfe!

_________________
Der PC tut immer nur das was ich will - aber wie erklär ich ihm was ich will?!?
crowley
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 406

Win XP, Win Vista, Mandriva, Ubuntu
Delphi 4-8, Delphi 2006, Delphi 2007
BeitragVerfasst: Di 04.07.06 16:26 
ich denke, dass es irgendwo in IdMessage ein Refresh oder Clear oder so gibt... damit könntest du das garantiert auch zurücksetzen... nur ich hab halt keine Indy-Komponenten hier ;)
adrian4321 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 41

Win2000, Linux (Suse9.0)
D5 Prof, D7 Pers, K3 OE
BeitragVerfasst: Di 04.07.06 16:36 
Ja, natürlich hat die eine Clear-Funktion, nur scheint die auch nicht alles aufzuräumen, denn das Problem beim Decodieren der Multiparts bleibt auch nach einem Clear bestehen, nicht jedoch nach einem Neuanlegen der Komponente!
crowley
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 406

Win XP, Win Vista, Mandriva, Ubuntu
Delphi 4-8, Delphi 2006, Delphi 2007
BeitragVerfasst: Di 04.07.06 16:54 
ein Blick in die Indy Hilfe verrät, dass das Clear nur Header und Body "leert"...
die MessageParts musst du selber aufräumen... und auch da gibt es ein Clear ;)

versuch es vielleicht mal so ;)
adrian4321 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 41

Win2000, Linux (Suse9.0)
D5 Prof, D7 Pers, K3 OE
BeitragVerfasst: Mi 05.07.06 01:42 
hmm, da steht:

"[...] Clear calls ClearBody to remove the contents of the message body including any text or attachments founbd in the MessageParts collection. [...]"

Und bei einer MIME-Mail sind die Multiparts ja im Grunde genommen auch nur im "klassischen" Body untergebracht. Ich werd das trotzdem aus Neugier einmal mit IdMessage.MultiParts.Clear testen, obwohl diese Funktion nichtmal in der Hilfe beschrieben wird....
crowley
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 406

Win XP, Win Vista, Mandriva, Ubuntu
Delphi 4-8, Delphi 2006, Delphi 2007
BeitragVerfasst: Mi 05.07.06 07:40 
OH für TIdMessage.Clear

Zitat:

Clears the header and body for the message.
procedure Clear; virtual;

Description

Clear is a procedure used to clear the values stored in the Header and Body of the message.
Clear calls ClearHeader to remove the contents of the message header. Clear calls ClearBody to remove the contents of the message body.



OH für TIdMessage.MessageParts

Zitat:

List of message parts for the message.
property MessageParts: TIdMessageParts;

Description

MessageParts is a TIdMessagePartsList used to store the TIdMessagePart components that make up the message. MessageParts can contain two TIdMessagePart descendants: TIdText and TIdAttachment.
MessageParts is used when IsEncoded is set to True (on sending), or NoDecode is set to false for receiving.


OH für TIdMessageParts

Zitat:

Collection for individual message parts in the message.

TIdMessageParts = class(TOwnedCollection)

Unit

IdMessage

Description

TIdMessageParts is a collection which contains the individual message parts for a MIME message, and contains ancestors of TIdMessagePart such as TIdText and TIdAttachment.


OH für TOwnedCollection

Zitat:

Deletes all items from the collection.

Delphi syntax:

procedure Clear;

C++ syntax:

void __fastcall Clear(void);

Description

Clear empties the Items array and destroys each TCollectionItem.


... man muss nur ein bisserl zwischen den Hilfedateien Hin und Her springen ;)
adrian4321 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 41

Win2000, Linux (Suse9.0)
D5 Prof, D7 Pers, K3 OE
BeitragVerfasst: Mi 05.07.06 11:43 
Ja, schön und gut.... hilft nur nix! Ich habe das mit dem Neuanlegen wieder rausgenommen und ein Message.MessageParts.Clear mit in jeden Durchlauf reingesetzt, da kommt als Content-Type schnell wieder permanent multipart/alternative. Lediglich Attachments werden korrekt identifiziert.

_________________
Der PC tut immer nur das was ich will - aber wie erklär ich ihm was ich will?!?
crowley
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 406

Win XP, Win Vista, Mandriva, Ubuntu
Delphi 4-8, Delphi 2006, Delphi 2007
BeitragVerfasst: Mi 05.07.06 12:35 
o_O ... wie's scheint, kann ich das nur reproduzieren, wenn ich mir die Indy- Komponenten installiere... da wir die aber bei uns in der Firma explizit ausgeklammert haben, müsste ich das zu Hause machen... da hab ich derzeit aber keinen Entwicklungsrechner *himpf*

bist du dir sicher, dass du sonst keinen Fehler da drin haben kannst? was machst du sonst in dem Code mit deiner IdMessage? Zeig am besten mal die Abarbeitung deiner Nachrichten im Quellcode her...
adrian4321 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 41

Win2000, Linux (Suse9.0)
D5 Prof, D7 Pers, K3 OE
BeitragVerfasst: Mi 05.07.06 13:11 
Naja, was heisst sicher sein dass keiner drin ist.... alles relativ :) Ich habe das jedenfalls auch mal alles aufs wesentliche reduziert (also Message clearen, Mail aus Datei öffnen, Betreff etc auslesen, falls Messageparts vorhanden sind jeden abklappern und mittels Content-Type identifizieren), und das ganze in einer Schleife mit mehreren Testmails (mal mit mal ohne Anhang, mal mit mal ohne html-Textteil etc.).

Bei der Fehlersuche bin ich dann auch darauf gekommen dass die Indykomponente den Header des jeweiligen MultiParts falsch ausgibt, da stand irgendwas anderes zusammenhangloses aus der Mail gerissenes, aber nicht der Header des betreffenden Multiparts (Message.MessageParts.Items[i].Headers.Text).

Ich habe hier mal meine Zerlegungsprozedur ins Netz gestellt, befindet sich noch in der Aufbauphase und enthält daher einiges auskommentiertes und ist sicherlich noch verbesserungswürdig ;)
Die Problemlösung mit dem Neuerzeugen habe ich dort wieder ausgeklammert, in der Form tritt bei mir der Fehler auf.

deepserve.mine.nu/public/email.txt