![]() |
EMails auslesen mit Simple MAPI
Hallo zusammen,
ich habe folgendes Problem: Ich möchte mit Hilfe von Simple MAPI meine ungelesenen Mails aus Outlook Express auslesen. Dazu benutze ich folgenden Quellcode:
Delphi-Quellcode:
Nach dem ersten Aufruf von MapiFindNext wird meine SessionID, die ich über MapiLogon bekommen habe, überschrieben. Jeder weitere Mapi-Funktionsaufruf funktioniert danach nicht mehr.
uses Mapi;
procedure TForm1.Button1Click(Sender: TObject); var Err: Cardinal; SessionID: LHANDLE; MessID: AnsiChar; pMsg: PMapiMessage; i: Integer; begin Err := MapiLogOn(Handle, '', '', MAPI_EXPLICIT_PROFILE, 0, @SessionID); i := 1; Err := MapiFindNext(SessionID, Handle, '', '', MAPI_UNREAD_ONLY, 0, @MessID); while Err = SUCCESS_SUCCESS do begin Err := MapiReadMail(SessionID, 0, @MessID, MAPI_UNREAD_ONLY or MAPI_PEEK, 0, pMsg); // <- ab hier simmt die Session-ID nicht mehr if Err = SUCCESS_SUCCESS then begin StringGrid1.Cells[0,i] := MessID; StringGrid1.Cells[1,i] := pMsg^.lpOriginator^.lpszName + ' (' + pMsg^.lpOriginator^.lpszAddress + ')'; StringGrid1.Cells[2,i] := pMsg^.lpszSubject; StringGrid1.Cells[3,i] := pMsg^.lpszDateReceived; Inc(i); end; Err := MapiFreeBuffer(pMsg); Err := MapiFindNext(SessionID, 0, nil, @MessID, MAPI_UNREAD_ONLY, 0, @MessID); end; Err := MapiLogOff(SessionID, 0, MAPI_LOGOFF_SHARED, 0); end; Kann mir jemand erklären, woran das liegt? Habe ich evtl. einen Fehler beim Referenzieren/Dereferenzieren der Zeiger gemacht? Schon mal im Voraus vielen Dank für Eure Hilfe Katrin |
Re: EMails auslesen mit Simple MAPI
Lokale Variablen ändern sich.
Schreibe Deine SessionID in eine globale Variable oder in ein Edit-Feld. |
Re: EMails auslesen mit Simple MAPI
Hallo,
Zitat:
Damit scheint es zu funktionieren:
Delphi-Quellcode:
uses Mapi;
Var SessionID: LHANDLE; // <- warum das erforderlich ist, hätte ich gerne mal erklärt. procedure TForm1.Button1Click(Sender: TObject); var Err: Cardinal; // SessionID: LHANDLE; // <- Wieso muss die ausserhalb der Prozedure deklariert sein? MessID: AnsiChar; pMsg: PMapiMessage; i: Integer; begin Err := MapiLogOn(Handle, '', '', MAPI_EXPLICIT_PROFILE, 0, @SessionID); i := 1; Err := MapiFindNext(SessionID, 0, nil, nil, 0 {MAPI_UNREAD_ONLY}, 0, @MessID); while Err = SUCCESS_SUCCESS do begin Err := MapiReadMail(SessionID, Handle, @MessID, 0 {MAPI_UNREAD_ONLY or MAPI_PEEK}, 0, pMsg); // <- ab hier simmt die Session-ID nicht mehr if (Err = SUCCESS_SUCCESS) then begin StringGrid1.Cells[0,i] := MessID; StringGrid1.Cells[1,i] := pMsg^.lpOriginator^.lpszName + ' (' + pMsg^.lpOriginator^.lpszAddress + ')'; StringGrid1.Cells[2,i] := pMsg^.lpszSubject; StringGrid1.Cells[3,i] := pMsg^.lpszDateReceived; Inc(i); StringGrid1.RowCount := i + 1; Application.ProcessMessages; end; Err := MapiFreeBuffer(pMsg); Err := MapiFindNext(SessionID, 0, nil, @MessID, 0 {MAPI_UNREAD_ONLY}, 0, @MessID); end; Err := MapiLogOff(SessionID, 0, MAPI_LOGOFF_SHARED, 0); end; |
Re: EMails auslesen mit Simple MAPI
Danke für den Tipp mit der globalen Variable. Die Mails werden jetzt ausgelesen.
Allerdings bekomme ich nun diese Meldung, wenn die Prozedur komplett abgearbeitet wurde: --------------------------- Benachrichtigung über Debugger-Problem --------------------------- In Projekt D:\Katrin\Prog\MapiTest\MapiTest.exe trat ein Problem mit folgender Meldung auf: 'access violation at 0x00433fc0: read of address 0x00003137'. Prozess angehalten. Mit Einzelne Anweisung oder Start fortsetzen. --------------------------- OK --------------------------- Habt ihr dazu vielleicht auch noch eine Idee? |
Re: EMails auslesen mit Simple MAPI
Hallo Katrin,
nö, habe da keine Idee, habe mir schon 'nen Wolf gesucht, um herauszufinden, wo es denn da bitte knallt. Mit dem Debugger bin ich da nicht weitergekommen. Vermute, dass der "Fehler" ausserhalb des Delphicodes auftritt, bzw. habe keine Ahnung, wie man das in Delphi ändern muss, damit es nicht mehr knallt. Vermutlich scheitert das MapiFindNext, wenn es nichts mehr zu finden gibt, aber da bin ich mir noch nicht so sicher. Eventuell versuchst Du mal (sofern noch nicht geschehen), durch diverse Try Except eine Konstellation zu finden, bei der Du die Schutzverletzung (ohne negative Nebenwirkungen) ignorieren kannst (Ich weiß ist äußerst unsauber, aber mir fällt da momentan nix besseres zu ein.). [edit]Schreibfehler und unsinnige Satzstellung korrigiert.[/edit] |
Re: EMails auslesen mit Simple MAPI
Hallo Stephan,
erstmal Danke, dass Du Dir die Zeit nimmst, mir zu helfen. Das MapiFindNext gibt einen bestimmten Code (MAPI_E_NO_MESSAGES) zurück, wenn es alle Mails gelesen hat. Das würde ich mal als Fehlerquelle ausschließen. Vor allem, weil der Fehler nicht auftritt, wenn es nichts zu lesen gibt. Mit dem Try-Except-Block experimentiere ich jetzt mal ein bisschen. Katrin |
Re: EMails auslesen mit Simple MAPI
Gib uns doch bitte den ganzen Code als Anhang.
|
Re: EMails auslesen mit Simple MAPI
Hallo,
stehe da jetzt vor einem Problem, dass ich nicht lösen kann: Habe mal als Anhang einen Screenshot vom CPU-Fenster der IDE gemacht. Die Stelle, an der die Zugriffsverletzung auftritt, ist markiert. Wer kann uns sagen, wie wir diesem Fehler auf die Schliche kommen können, momentan habe ich keine Ahnung, wo überhaupt der Fehler (ausgehend vom Quelltext) zu suchen ist. Der von mir genutzte Quelltext hängt ebenfalls am Post. Wenn ich das beim letzten Versuch richtig interpretiert habe, tritt der Fehler hinter
Delphi-Quellcode:
auf und zwar in der Unit Windows beim Aufruf von
Err := MapiLogOff(SessionID, 0, MAPI_LOGOFF_SHARED, 0);
Delphi-Quellcode:
Durch die Funktion MapiLogOff komme ich mit dem Debugger im Einzelschritt noch durch.
function GetMailslotInfo; external kernel32 name 'GetMailslotInfo';
|
Re: EMails auslesen mit Simple MAPI
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
|
Re: EMails auslesen mit Simple MAPI
Ich bekomme 2 Fehlermeldungen:
[Pascal Hint] FormMain.pas(70): H2077 Value assigned to 'Err' never used [Pascal Hint] FormMain.pas(75): H2077 Value assigned to 'Err' never used |
Re: EMails auslesen mit Simple MAPI
Hallo,
Zitat:
Delphi-Quellcode:
Err := MapiLogOn(Handle, '', '', MAPI_EXPLICIT_PROFILE, 0, @SessionID);
Delphi-Quellcode:
und
Err := MapiFreeBuffer(pMsg);
Delphi-Quellcode:
auch verzichten, da sie für die Weiterverarbeitung (vermutlich?) nicht von Belang sind.
Err := MapiFreeBuffer(pMsg);
Habe mal die Rückgabewerte protokolliert, sie sind immer 0 = SUCCESS_SUCCESS mit Ausnahme des letzten MapiFindNext, dieses liefert 16 = MAPI_E_NO_MESSAGES. MapiLogOff liefert 0 = SUCCESS_SUCCESS, danach tritt die Ausnahme auf. Nachdem ich dann den Quelltext noch ein bisserl verändert hatte und vor das Abschließende end; von Button1Click(Sender: TObject), eine ShowMessage('Fehler vorher oder nachher?'); gesetzt hatte, durfte ich Feststellen, dass der Fehler hinter diesem ShowMessage auftritt, mit der "Nebenwirkung", dass man im Debugger nicht mehr über die Zugriffverletzung(en) hinauskommt, jedes F9 führt zu einer weiteren Zugriffsverletzung, die Adresse ändert sich dabei nicht. Wenn ich das CPU-Fenster richtig interpretiere, tritt der Fehler in TControl.WndProc auf. Wird hier irgendwo unterwegs was zerschossen? |
Re: EMails auslesen mit Simple MAPI
Hallo zusammen,
ich habe das Problem jetzt gelöst, weiß aber nicht, warum es so funktioniert und nicht anders. Als erstes habe ich alle Variablen, die ich für Mapi-Aufrufe brauchte, global definiert. Danach bekam ich aber wieder den gleichen Fehler wie am Anfang (Variable Session wurde überschrieben). Wenn ich aber die Session lokal und alle anderen Variablen global definiere, funktioniert es. Wenn mir das noch jemand erklären könnte ... Hier ist der funktionierende Quelltext:
Delphi-Quellcode:
Viele Grüße und Danke für Eure Hilfe
var MessID: AnsiChar;
pMsg: PMapiMessage; Err: Cardinal; procedure TForm1.Button1Click(Sender: TObject); var i: Integer; Session: LHANDLE; begin Err := MapiLogOn(Handle, '', '', MAPI_EXPLICIT_PROFILE, 0, @Session); if Err <> SUCCESS_SUCCESS then begin ShowMessage('Verbindung konnte nicht hergestellt werden! ' + IntToStr(Err)); Exit; end; i := 1; Err := MapiFindNext(Session, Handle, '', '', MAPI_UNREAD_ONLY, 0, @MessID); while Err = SUCCESS_SUCCESS do begin Err := MapiReadMail(Session, 0, @MessID, MAPI_PEEK, 0, pMsg); if Err = SUCCESS_SUCCESS then begin StringGrid1.Cells[0,i] := MessID; StringGrid1.Cells[1,i] := pMsg^.lpOriginator^.lpszName + ' (' + pMsg^.lpOriginator^.lpszAddress + ')'; StringGrid1.Cells[2,i] := pMsg^.lpszSubject; StringGrid1.Cells[3,i] := pMsg^.lpszDateReceived; Inc(i); Application.ProcessMessages; end; Err := MapiFindNext(Session, 0, nil, @MessID, MAPI_UNREAD_ONLY, 0, @MessID); end; MapiFreeBuffer(pMsg); MapiLogOff(Session, 0, MAPI_LOGOFF_SHARED, 0); StringGrid1.RowCount := Max(i, 2); end; Katrin |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:21 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz