Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi Email direkt aus Program mraus (https://www.delphipraxis.net/59009-email-direkt-aus-program-mraus.html)

renekr 15. Dez 2005 20:34


Email direkt aus Program mraus
 
Hallo,

Ich stecke grad an meinem Program man der Stelle mit der Email versenderei sehr tief fest.


Habe ein Szenario wo ich haben will und ev das 2. als ultimativen Bonus( ev auch beides in einem zusammen ):

Einige User haben Outlook installiert mit anbindung an einen Exchange Server

Ich will eine neue Email aufmachen mit mehreren Empfängern und Attachement als PDf.

Zudem noch Text im Betreff und im Body.

Das hatte ich schon über eine funktion,aber NUR möglich mit 1 Empfänger( weitere hat er im String z ueinem zusammengeführt ).


2.: Einige User haben kein Outlook client installiert ,habe aber ein Login und Passwort im Kopf ( gültiges für Exchange Server )


Ist es möglich direkt aus dem Programm eine Form zu machen ( Email nachbauen ) und per Exchange Server ohne Installiertes Outlook zu verschicken?
Dann bin ich auf Outlook garnicht angewiesen.



Bin euch echt dankbar.

ichbins 15. Dez 2005 20:49

Re: Email direkt aus Program mraus
 
Google doch einfach mal: Bei Google suchensmtp engine delphi

wie wärs z.B. damit

marabu 15. Dez 2005 20:56

Re: Email direkt aus Program mraus
 
Hallo René,

erstmal zu deinem Problem mit mehreren Empfängern - so stelle ich mir das vor - ungetestet:

Delphi-Quellcode:
var
  MapiMessage: TMapiMessage;
  recips: array of MapiRecipDesc;
  rl: TStrings;
  i: integer;
begin
  rl := TStringList.Create;
  rl.LoadFromFile('ListOfRecipientNames');
  SetLength(recips, rl.Count);
  ZeroMemory(@recips[0], SizeOf(MapiRecipDesc) * rl.Count);
  for i := Low(recips) to High(recips) do
    with recips[i] do
    begin
      ulRecipClass := MAPI_TO;
      lpszName := PChar(rl[i]);
    end;
  rl.Free;

  with MapiMessage do
  begin
    // siehe W2K Logo App
    nRecipCount := rl.Count;
    lpRecips := recips;
  end;
Grüße vom marabu

renekr 27. Dez 2005 11:27

Re: Email direkt aus Program mraus
 
Hi,
kleine Frage noch dazu.

ISt es möglich aus einem Programm raus über die Mapi.dll direkt mit angabe der userdaten eine email zu schicken,
wenn kein Outlook installiert ist??
Direkt über den Server darf i net weil i da eine Feste IP benötige und die im Exchange Server registriert sein muß in unseren LAN.

Danke.

marabu 27. Dez 2005 11:46

Re: Email direkt aus Program mraus
 
Outlook ist nicht notwendig um per MAPI eine mail zu verschicken - aber du brauchst einen account auf einem MAPI-Server.

Grüße vom marabu

renekr 27. Dez 2005 12:11

Re: Email direkt aus Program mraus
 
Hi marabu,

Das hab i schon gewußt, aber i weiß nicht wie.
Account und Passwort ist alles vorhanden,das übergebe ich dann als anmelde info mit
Ich will halt von manchen PCs ohne Outlook Emailen können,direkt über SMTP Server geht von usnerer IT Sicherheit nicht.

Habe hier einen Link allerdings für VB:

MAPI Control VB


Wen nes möglich wäre kannst du mir a bisserl helfen bei dem Thema?
Habe bis jetzt nur Email übers Outlook Profile geschickt, das heißt nur eine neue Email geöffnet.

Der absolute Luxus für mein Tool wäre, wenn ich ohne Outlook und in einer Extra Form eine Email mit mehreren Empfängern,ev. Liste vom Exchange Profile ( Adressbuch),
und schreiben ,speicher und senden kann m it anhang.

Vielen Dank.

Anbei mal der Code SendMail , den habe ich wo her und mit deinem ( mehrere Empfänger ) aktualisiert )
Delphi-Quellcode:
function SendMail(const Subject, Body, FileName,
         SenderName, SenderEMail,
         RecipientName, RecipientEMail: string): Integer;
var
  Message: TMapiMessage;
  lpSender, lpRecipient: TMapiRecipDesc;
  FileAttach: TMapiFileDesc;
  //neu
   recips: array of MapiRecipDesc;
   rl: TStrings;
  i: integer;
 //
  SM: TFNMapiSendMail;
  MAPIModule: HModule;
begin

  FillChar(Message, SizeOf(Message), 0);
  with Message do
  begin
    if (Subject <> '') then
    lpszSubject := PChar(Subject);

    if (Body <> '') then
      lpszNoteText := PChar(Body);

    if (SenderEmail <> '') then
    begin
      lpSender.ulRecipClass := MAPI_ORIG;
      if (SenderName = '') then
        lpSender.lpszName := PChar(SenderEMail)
      else
        lpSender.lpszName := PChar(SenderName);

      lpSender.lpszAddress := PChar(SenderEmail);
      lpSender.ulReserved := 0;
      lpSender.ulEIDSize := 0;
      lpSender.lpEntryID := nil;
      lpOriginator := @lpSender;
    end;
   ///

rl := TStringList.Create;
  rl.LoadFromFile('c:\test.txt');
  SetLength(recips, rl.Count);
  ZeroMemory(@recips[0], SizeOf(MapiRecipDesc) * rl.Count);
  for i := Low(recips) to High(recips) do
    with recips[i] do
    begin
      ulRecipClass := MAPI_TO;
      lpszName := PChar(rl[i]);
    end;
  rl.Free;

  ///
    if (RecipientEmail <> '') then
    begin
      lpRecipient.ulRecipClass := MAPI_TO;
      if (RecipientName = '') then
        lpRecipient.lpszName := PChar(RecipientEMail)
      else
        lpRecipient.lpszName := PChar(RecipientName);

      lpRecipient.lpszAddress := PChar(RecipientEmail);
      lpRecipient.ulReserved := 0;
      lpRecipient.ulEIDSize := 0;
      lpRecipient.lpEntryID := nil;
      nRecipCount := rl.Count;
     // lpRecips := recips;

     // nRecipCount := 1;
      lpRecips := @lpRecipient;
    end
    else
      lpRecips := nil;

    if (FileName = '') then
    begin
      nFileCount := 0;
      lpFiles := nil;
    end
    else
    begin
      FillChar(FileAttach, SizeOf(FileAttach), 0);
      FileAttach.nPosition := Cardinal($FFFFFFFF);
      FileAttach.lpszPathName := PChar(FileName);

      nFileCount := 1;
      lpFiles := @FileAttach;
    end;
  end;

  MAPIModule := LoadLibrary(PChar(MAPIDLL));
  if MAPIModule = 0 then
    Result := -1 
  else
    try
      @SM := GetProcAddress(MAPIModule, 'MAPISendMail');
      if @SM <> nil then
      begin
        Result := SM(0, Application.Handle, Message, MAPI_DIALOG or MAPI_LOGON_UI, 0);
      end
      else
        Result := 1;
    finally
      FreeLibrary(MAPIModule);
    end;

    if Result <> 0 then MessageDlg('Email wurde nicht gesendet.', mtError,[mbOK], 0);
    if Result = 0 then MessageDlg('Email wurde gesendet , und unter C:\MEKM Tool\Logbuchberichte abgelegt.', mtInformation,[mbOK], 0);

end;

marabu 27. Dez 2005 12:32

Re: Email direkt aus Program mraus
 
Hi René,

du willst also einen eigenen MAPI-Client entwickeln, nur damit du unabhängig von Outlook bist? Wahrscheinlich kannst du dir noch nicht vorstellen, was das für ein Aufwand ist. Nimm doch einen fertigen Client, wie Eudora. Wenn du es aber unbedingt willst, dann solltest du dich mal intensiv mit dem MAPI SDK auseinandersetzen. Und irgendwie musst du MAPI ja auf die Zielmaschine bringen. Das geht über die Installation der Exchange Client Software - oder über Outlook.

Dein Angebot zur Mitarbeit an diesem Projekt kann ich leider nicht annehmen, da es zuviel von meiner Zeit binden würde. Ich hoffe du kannst das verstehen.

Freundliche Grüße vom marabu

renekr 27. Dez 2005 12:40

Re: Email direkt aus Program mraus
 
Hi ,

das hast du mißvrstanden.
Natürlich will i keinen neuen MAPI Client entwickeln,dazu habe ich in dem Bereich zu wenig Ahnung .

Ich will eigentlich nur das ich auf Rechner wo kein Outlook installiert ist, mit so wenig Aufwand wie möglich von meinem Tool raus eine Email verschicken können.

Mit Attachment und ev. noch zugriff auf das Öffentliche Adressbuch auf dem Exchange Server .


Habe gelesen,das MAPI auch Emails lesen kann,also das ich dann die Mails vom Postfach im Tool anzeigen kann.


Wil lhier bei weitem keinen neuen Client entwickeln,sondern es nur für mich so einbinden das es geht und wenn möglich auf den Client PCs nix installieren muß
Client PCs= Win NT und Win 2000 .

Ist das überhaupt möglich?
Werde mich erst mal in die MAPI SDK einlesen.


Klar kann ich das verstehn das du dafür keine Zeit hast, die hab nicht mal ich :lol:

Aber wenns geht kannst mir einige kleinere tipps geben.

Will ja nicht das du alles machst.sonst bringt es ja nix.

Vielen Dank schonmal.

renekr 13. Jan 2006 10:15

Re: Email direkt aus Program mraus
 
Hi marabu,
kannst du mir ev. einen Tip geben was ich in meinem Source oben falsch habe mit dem mehreren Empfängern?
Da kommt immer eine Zugriffsverletzung.

Danke schön.

shmia 13. Jan 2006 12:54

Re: Email direkt aus Program mraus
 
Hallo renekr
ich gebe dir mal ein paar grundsätzliche Info's, wie man EMails verschicken kann:
1.) über MAPI
Vorraussetzung: auf dem Rechner ist ein MAPI-client wie z.B. Outlook, Eudora installiert
und komplett konfigueriert.
Dann kannst du über das Konto des Benutzers EMails verschicken.
Alle gesendeten Mails werden im Ordner "gesendete Objekte" gespeichert.
Dies kann ein grosser Vorteil sein.
Du kannst nur unter der EMail-Adresse des Benutzers versenden; eine andere Absender-EMail-Adr ist nicht möglich.
Dein Programm braucht keinerlei Information über User, Passwort, Server wissen, das wird alles vom EMail-Client verwaltet.
2.) über SMTP
Du musst Server, User und Passwort kennen und "redest" direkt mit dem Server.
Es braucht kein EMail-Client installiert sein.
Du benötigst Indy, Fastnet oder vergleichbare Komponenten.
Die Absender-Mail kann beliebig gewählt werden (falls Server das erlaubt).
3.) über eine Webseite
Man kann den IExplorer so steuern, dass über ein Konto bei GMX, Web.de oder andere EMail-Seite ein Mail verschickt wird.
Diese Variante bietet sich nur an, wenn über die Firewall alles ausser Port 80 geblockt wird.

Es gibt also 3 Wege, die sich programmiertechnisch stark unterscheiden.
Der Programmier-Aufwand ist bei MAPI relativ gering, vorrausgesetzt du verwendest eine
MAPI-Klasse/Komponente, die was taugt.
Die beste MAPI-Klasse, die ich bisher gesehen habe, ist in der JCL.
http://sourceforge.net/projects/jcl

marabu 13. Jan 2006 19:37

Re: Email direkt aus Program mraus
 
Hallo René,

ich habe mir eine Testanwendung gebaut und dann einige Dinge an deiner Funktion SendMail() abgeändert, da ich den Eindruck hatte, dass du sie noch nicht ganz fertige hattest. Sie sieht jetzt bei mir so aus:

Delphi-Quellcode:
function SendMail(const Subject, Body, FileName, SenderName,
  SenderEMail: String; Recipients: TStrings): Integer;
var
  msg: TMapiMessage;
  lpSender: TMapiRecipDesc;
  FileAttach: TMapiFileDesc;
  recips: array of MapiRecipDesc;
  i: integer;
  SM: TFNMapiSendMail;
  MAPIModule: HModule;
begin
  FillChar(msg, SizeOf(msg), 0);
  with msg do
  begin
    lpszSubject := PChar(Subject);
    lpszNoteText := PChar(Body);

    if (SenderEmail <> '') then
    begin
      FillChar(lpSender, SizeOf(lpSender), 0);
      lpOriginator := @lpSender;
      lpSender.ulRecipClass := MAPI_ORIG;
      if (SenderName = '')
        then lpSender.lpszName := PChar(SenderEMail)
        else lpSender.lpszName := PChar(SenderName);
      lpSender.lpszAddress := PChar(SenderEmail);
    end;

    if Recipients.Count > 0 then
    begin
      SetLength(recips, Recipients.Count);
      ZeroMemory(@recips[0], SizeOf(MapiRecipDesc) * Recipients.Count);
      for i := Low(recips) to High(recips) do
        with recips[i] do
        begin
          ulRecipClass := MAPI_TO;
          lpszName := PChar(Trim(Before(Recipients[i], '<')));
          lpszAddress := PChar(Trim(Between(Recipients[i], '<', '>')));
        end;
      lpRecips := @recips;
    end;

    if (FileName <> '') then
    begin
      FillChar(FileAttach, SizeOf(FileAttach), 0);
      FileAttach.nPosition := Cardinal($FFFFFFFF);
      FileAttach.lpszPathName := PChar(FileName);

      nFileCount := 1;
      lpFiles := @FileAttach;
    end;
  end;

  MAPIModule := LoadLibrary(PChar(MAPIDLL));
  if MAPIModule = 0 then
    Result := -1
  else
    try
      @SM := GetProcAddress(MAPIModule, 'MAPISendMail');
      if Assigned(@SM)
        then Result := SM(0, Application.Handle, msg, MAPI_DIALOG or MAPI_LOGON_UI, 0)
        else Result := 1;
    finally
      FreeLibrary(MAPIModule);
    end;
end;
Auf der Maschine, die mir gerade zur Verfügung steht, habe ich nur Mozilla Thunderbird als Simple MAPI Client drauf. Keine Zugriffsverletzung. Allerdings werden die Recipients nicht übernommen. Ich erhalte aber auch keine Fehlermeldung. Muss da später nochmal nachschauen. Vielleicht ein Sicherheitsmerkmal, damit der Thunderbird nicht wie Outlook als Virenschleuder verwendet werden kann.

Grüße vom marabu

renekr 13. Jan 2006 20:06

Re: Email direkt aus Program mraus
 
Hi @,

Erstmal Vielen Dank für eure schnelle und Fachliche Hilfe ( wie gewohnt in der DP )

Ich werde das gleich aus probieren und Rückinfo geben.

Kannst du mir das mal erklären ?
Was machst du da mit Trim(Before und Trim(Between
Ich bekomme Undefinierter Bezeichner bei den beiden.
Das kenne ich bis jetzt noch nicht.

Delphi-Quellcode:
lpszName := PChar(Trim(Before(Recipients[i], '<')));
lpszAddress := PChar(Trim(Between(Recipients[i], '<', '>')));
Vielen Dank.
@shmia : Das war mir klar, ich habe nur ein Problem weil ich in unserer Netzwerkumgebung ziemlich Eingeschränkt sind ( Sicherheitstechnischer Hinsicht )
zb: Das man per SMTP Server nur Emails schicken kann wenn die IP Fest im Server hinterlegt ist und das kann ich nicht bei allen PCs machen lasse.
Werde zuerst mal über MAPI an Outlook gehen , und dan nmal schaun wie ich das über SMTP mit der sicherheit mache kann.

Trotzdem Vielen Dank für die Info.

marabu 13. Jan 2006 21:45

Re: Email direkt aus Program mraus
 
Entschuldige René,

Delphi-Quellcode:
lpszName := PChar(Trim(Before(Recipients[i], '<')));
lpszAddress := PChar(Trim(Between(Recipients[i], '&lt;', '>')));
mit den beiden Funktionen zerlege ich das von mir gewählte Eingabeformat für die mail recipients - sie tun genau das was ihr Name suggeriert:

Delphi-Quellcode:
const
  sRecipient = 'Nachname, Vorname <postfach@mail-domain.de>';
begin
  if Before(sRecipient, '<') = 'Nachname, Vorname ' then
    ShowMessage('na also');
  if Between(sRecipient, '<', '>') = 'postfach@mail-domain.de' then
    ShowMessage('geht doch');
end;
marabu

renekr 13. Jan 2006 23:27

Re: Email direkt aus Program mraus
 
Hi marabu,


vielen Dank für deine Mühe.

Gleiches Ergebnis wie bei dir :
"Recipients werden nicht übernommen."

Wie ist es wenn ich die nachname,Vorname und dann Emai lnicht so komplex schreiben will,reicht dann folgendes:

Delphi-Quellcode:
lpszAddress :=PChar(Recipients[i]);
Ich geben meine Empfänger so an:ohne die Vor - Nachnamen und dann durch <Email Adresse>

Name1;Name2;name3;name4

Die namen werden von Outlook durch das Öffentliche Adressbuch entschlüsselt.
das Trennzeichen ist frei wählbar(bei ner Stringlist entfällt es natürlich).



Danke.

marabu 14. Jan 2006 16:49

Re: Email direkt aus Program mraus
 
Hallo René,

na klar kannst du deine Empfänger auch als Feldliste in einem String an deine SendMail-Funktion übergeben. Du musst sie dann aber zerlegen und für jeden einzelnen eine MapiRecipDesc-Struktur ausfüllen. In deinem Code darfst du dann aber nicht lpszName und lpszAddress mit dem gleichen Wert beschicken. Ist es ein DisplayName, dann weise ihn nur lpszName zu und MAPI-intern wird die Mail-Adresse ermittelt. Sobald du lpszAddress etwas zuweist gibt es keinen Automatismus mehr und die zugewiesene Adresse wird für den Versand benutzt.

Für die einfache Zerlegung deiner Empfänger-Feldliste kannst du vielleicht diesen Code brauchen:

Delphi-Quellcode:
function ParseStr(var s: string; delimiters: string; purge: boolean): string;
var
  i: integer;
begin
  i := 0;
  while (i < Length(s)) and (Pos(s[Succ(i)], delimiters) = 0) do
    Inc(i);
  Result := Copy(s, 1, i);
  Delete(s, 1, i + Ord(purge));
end;

procedure UsageDemo;
var
  sReceipients: String;
begin
  sRecipients := 'John Doe;Lisa Doe;Brother Tuck';
  while sReceipients <> '' do
    ShowMessage(ParseStr(sReceipients, ';', true));
end;
Grüße vom marabu

renekr 14. Jan 2006 18:50

Re: Email direkt aus Program mraus
 
Hi,
Danke aber das ist im moment nicht das Problem:
Wie gesagt ich gebe folgendes an in der SendMail Funktion:

Delphi-Quellcode:
if Recipients.Count > 0 then
    begin
      SetLength(recips, Recipients.Count);
      ZeroMemory(@recips[0], SizeOf(MapiRecipDesc) * Recipients.Count);
      for i := Low(recips) to High(recips) do
        with recips[i] do
        begin
          ulRecipClass := MAPI_TO;
         lpszName := PChar(Recipients[i]);
        end;
      lpRecips := @recips;
    end;
Aber die Empfänger ( AN ) bleiben leer.
Ich gebe ja nur den Display name mit in der Funktion anhand der vorab erstellten Stringliste.


Das mit den ; zwischen den Namen habe ich am Anfang verwendet,jetzt stelle ich die Namen mit Stringlist.add in der Stringliste zusammen ohne richtige Email Adresse, nur die namen.
Damit muß ich die Strings nicht entschlüsseln.


Aber das Problem das ich keine Namen habe ist immer noch da obwohl in der Schleife die Namen gesetzt werden.

Hast du dafür eine Erklärung was falsch ist?
In der Funktion wo ich gepostet habe geht es ( ohne mehrere Empfänger ).
Aber ich kann nicht erkennen was da unterschiedlich ist.

Danke.

marabu 15. Jan 2006 21:45

Re: Email direkt aus Program mraus
 
Zwei bugs habe ich gefunden:

Delphi-Quellcode:
if Recipients.Count > 0 then
begin
  SetLength(recips, Recipients.Count);
  ZeroMemory(@recips[0], SizeOf(MapiRecipDesc) * Recipients.Count);
  for i := Low(recips) to High(recips) do
    with recips[i] do
    begin
      ulRecipClass := MAPI_TO;
      lpszName := PChar(Recipients[i]);
    end;
  lpRecips := @recips[0]; // bug #1: @recips ist was anderes
  nRecipCount := Recipients.Count; // bug #2: hat gefehlt ...
end;
marabu

renekr 16. Jan 2006 19:30

Re: Email direkt aus Program mraus
 
Hi marabu,
Erstmal Vielen Vielen Dank für deine Geduld und Hilfe.

Hoffe nur ich kann mich mal Revanchieren :-D .
Wäre echt aufgeschmissen gewesen ohne deine Hilfe.


Danke.

renekr 22. Apr 2008 20:40

Re: Email direkt aus Program mraus
 
Hi Marabu,

Ich hoffe du kannst mir nochmals einen Tipp geben?

Ich bin soeben unter Vista und Outlook 2007 am Testen udn da geht es leider nicht.
Result:MAPI_E_FAILURE One or more unspecified errors occurred; no message was sent.

Ist die Mapi Routine unter Outlook 2007 anderst vom Handling?

Vielen Dank.

marabu 22. Apr 2008 21:29

Re: Email direkt aus Program mraus
 
Hallo René,

kann es sein, dass du früher OL98 oder OL2000 installiert hattest? Seither hat sich die Welt etwas verändert. Insbesondere hatte Microsoft es leid, dass Viren die MAPI.DLL recht einfach zur Reproduktion benutzt haben. Der bei dir auftretende Fehler MAPI_E_FAILURE (2) ist typisch für die verschärfte Sicherheit der neueren Outlook-Versionen.

Dieser Thread zeigt Wege aus dem Dilemma auf: Email Adresse des Senders über MAPI holen

Ich erinnere mich aber auch noch an andere Threads zum Thema Hier im Forum suchenExtended MAPI.

Freundliche Grüße

renekr 23. Apr 2008 08:10

Re: Email direkt aus Program mraus
 
Hi,
nein leider nicht.
Hatte O2003 im Einsatz und da ging alles PErfect.
Nur mit Vista und O2007 nciht mehr.

danke für die Links werd mal ein bisschen rum suchen.

mfg


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:56 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 by Thomas Breitkreuz