Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Outlook msg lesen / parsen (https://www.delphipraxis.net/184389-outlook-msg-lesen-parsen.html)

norwegen60 22. Mär 2015 22:37

Outlook msg lesen / parsen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo zusammen,

ich kann mit angehängtem Code Outlook-Mails lesen. Ich habe aber zwei Probleme die ich nicht gelöst bekomme.

Mit
Delphi-Quellcode:
procedure TForm1.LoadHeaders(aStorage: IStorage);
var
  Stream: IStream;
  Statistics:        STATSTG;
  buff_8:            pChar;
  iSize,
  dwfetch:           Integer;

begin
  aStorage.OpenStream('__substg1.0_007D001F', nil, STGM_READWRITE or
      STGM_SHARE_EXCLUSIVE, 0, Stream);
  if Stream = nil then
  begin
    mmoHeaders.Text := '';
    mmoContent.Text := '[could not read message headers]';
  end
  else
  begin
     mmoContent.Text := '';

       { Informationen über Stream, u.A. Größe einlesen }
        Stream.Stat(Statistics, STATFLAG_NONAME);
        { Buffer in passender Größe reservieren }
        buff_8 := AllocMem(Statistics.cbSize);
        iSize := Statistics.cbSize DIV 2;
        { Inhalt in buff einlesen }
        Stream.Read(buff_8, Statistics.cbSize, @dwFetch);
        { Inhalt des Buffers als Result speichern }
        mmoHeaders.Text := copy(String(buff_8), 1, iSize);
        { Speicher für Buffer wieder freigeben }
        freeMem(buff_8);
  end;
end;
lässt sich nur der Header von empfangenen Messages auslesen, aber nicht der von gesendeten. Ich habe noch festgestellt, dass z.B. das Sendedatum in einem Sub-Stream von '__properties_version1.0' enthalten ist. Diese werden aber nicht angezeigt.
Hat jemand einen Tip wie ich auch den Header von gesendeten Mails lesen kann?


Mit
Delphi-Quellcode:
  function GetAnzAttachment(aStorage: IStorage; Slash: WideString):Integer;
  var
    EnumStatStg: IEnumStatStg;
    StatStg: TStatStg;
    SubStorage: IStorage;
  begin
    Result:=0;
    aStorage.EnumElements(0, nil, 0, EnumStatStg);
    while EnumStatStg.Next(1, StatStg, nil) = S_OK do
    begin
      case StatStg.dwType of
        STGTY_STORAGE: begin
          aStorage.OpenStorage(StatStg.pwcsName, nil, STGM_READWRITE or
            STGM_SHARE_EXCLUSIVE, nil, 0, SubStorage);
          if SubStorage <> nil then
          begin
            if (pos('ATTACH', Uppercase(StatStg.pwcsName)) >0) then
              Result:=Result+1;
          end;
        end;
      end;
    end;
  end;
ermittle ich die Anzahl der Anhänge. Leider werden hiermit aber auch z.B. Logos in der Fußzeile als Anhänge gezählt. Wie kann ich tatsächliche Anhänge von integrierten Grafiken unterscheiden?

Vielen Dank für eure Hilfe
Gerd

Pitschki1801 27. Mär 2015 14:47

AW: Outlook msg lesen / parsen
 
Zitat:

Leider werden hiermit aber auch z.B. Logos in der Fußzeile als Anhänge gezählt. Wie kann ich tatsächliche Anhänge von integrierten Grafiken unterscheiden?
Hallo Gerd,

ich beschäftige mich gerade mit dem selbem Thema. Ich unterscheide die tatsächlichen und integrierten Grafiken über den Dateinamen innerhalb des Storages. Outlook vergibt für Grafiken innerhalb einer E-Mail einen eigenen Dateinamen image001.jpg, image002.jpg, image003.png, usw., usw. Die tatsächlich Anhänge werden in den Attachments mit ihrem normal Namen geführt. Wenn du also nicht gerade Grafiken versendest die image00X.XXX heißen, könntest du diese darüber herausfiltern.


Gruß
David

norwegen60 29. Mär 2015 11:47

AW: Outlook msg lesen / parsen
 
Hallo David,

danke für den Tip. Ich dachte es gibt vielleicht noch irgendeine Kennung. Habe es jetzt auch über den Grafiknamen gelöst.

Da ich bis jetzt sehr wenig mit Streams gearbeitet habe, dazu noch eine Frage
Ich wandle den Stream per
Delphi-Quellcode:
function TForm1.GetText(Stream: IStream):String;
var
  Statistics : STATSTG;
  buff_8     : pChar;
  iSize,
  iFetch    : Integer;

begin
  { Informationen über Stream, u.A. Größe einlesen }
  Stream.Stat(Statistics, STATFLAG_NONAME);
  { Buffer in passender Größe reservieren }
  buff_8 := AllocMem(Statistics.cbSize);
  iSize := Statistics.cbSize DIV 2;
  { Inhalt in buff einlesen }
  Stream.Read(buff_8, Statistics.cbSize, @iFetch);
  { Inhalt des Buffers als Result speichern }
  Result := copy(String(buff_8), 1, iSize);
  { Speicher für Buffer wieder freigeben }
  freeMem(buff_8);
end;

begin
  ...
  aStorage.OpenStream('__substg1.0_007D001F', nil, STGM_READWRITE or STGM_SHARE_EXCLUSIVE, 0, Stream);
  if Stream = nil then
    mmoHeaders.Text := '[could not read message headers]'
  else
     mmoHeaders.Text := GetText(Stream);
in ein String um. Gibt es noch eine elegantere Möglichkeit?

Zusätzlich bleibt noch meine alte Frage:
Wie lässt sich der Header von gesendeten Mails auslesen. Ich benötige hier vor allem das Sendedatum

Grüße
Gerd

Pitschki1801 30. Mär 2015 07:09

AW: Outlook msg lesen / parsen
 
Moin Gerd,

vielleicht gibt es eine Kennung, aber die hab ich auch noch nicht gefunden :|

Ich wandel den IStream in einen TStringStream um, ist vielleicht etwas einfacher zu handeln.
Bei dem E-Mailtext solltest du die Nullzeichen nicht unbedingt gegen Leerzeichen ersetzen ^^

Delphi-Quellcode:
function PDropTarget.GetAttachmentFilename(_AttachmentStorage: IStorage): String;
var
    l_AttachmentStream: IStream;
    l_AttachmentStat: TStatStg;
    l_OleStream: TOleStream;
    l_StringStream: TStringStream;
    l_FileName: String;
    p : PChar;
    i : integer;
begin
    //CONST_AttachmentFileName = '__substg1.0_3001001F'
    _AttachmentStorage.OpenStream(CON_AttachmentFileName, nil, STGM_READWRITE or STGM_SHARE_EXCLUSIVE, 0, l_AttachmentStream);
    if (l_AttachmentStream.Stat(l_AttachmentStat, STATFLAG_NONAME) = S_OK) then
    begin
        try
            l_OleStream := TOleStream.Create(ISTREAM(l_AttachmentStream));
            l_StringStream := TStringStream.Create('');
            l_StringStream.CopyFrom(l_OleStream, 0);
            l_FileName := l_StringStream.DataString;
            UniqueString(l_FileName);
            p := PChar(l_FileName);
            for i := 1 to length(l_FileName) do
            begin
                if p^ = #0 then
                    p^ := #32;
                Inc(p);
            end;
            result := StringReplace(l_FileName, #32, '', [rfReplaceAll]);
        finally
            l_OleStream.Free;
            l_AttachmentStream := NIL;
        end;
    end;
end;
Mit dem Datum von gesendeten Mails kann ich dir zur Zeit leider nicht weiter helfen.

Gruß
David

norwegen60 30. Mär 2015 22:35

AW: Outlook msg lesen / parsen
 
Hallo David,

wirklich einfacher finde ich deinen Weg auch nicht gerade :)

Als ID verwende ich allerdings __substg1.0_3707001F. Bei __substg1.0_3001001F hatte ich es schon, dass dort der Name des Anhangs nicht drin stand obwohl ein Anhang da war.

Die Sucherei nach den richtigen ID ist ziemlich mühsam. Gibt es nirgend eine Quelle, wo alle ID erklärt sind? Z.B. auch die für das Sendedatum?

Grüße
Gerd

Pitschki1801 31. Mär 2015 08:13

AW: Outlook msg lesen / parsen
 
Moin,

das es einfacher und schöner ist würde ich auch nie behaupten :P
Hmm ich hatte mit der ID bislang keine Probleme, aber ich behalte das mal im Auge.

Bei MS selbst findest du schon bisschen was über .MSG
https://msdn.microsoft.com/en-us/lib...exchg.80).aspx
http://blogs.msdn.com/b/openspecific...at-part-1.aspx
http://blogs.msdn.com/b/openspecific...ge-part-2.aspx
http://blogs.msdn.com/b/openspecific...ge-part-3.aspx

Ansonsten hab ich noch dies gefunden sicher nicht vollständig, aber besser als nichts.
http://www.fileformat.info/format/outlookmsg/


Gruß
David


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