E-MAil versenden klappt nicht



  • Ich versuche schon lange eine E-Mail versteckt zu versenden und arbeite im BCB C++ Builder. Aber iregendwie krieg ichs nicht hin. Ich habe mir auch schon mehrere Quelltexte besorgt. Im Moment sieht meiner so aus:

    CODE:
    //---------------------------------------------------------------------------
    #include <vcl\vcl.h>
    #pragma hdrstop
    #include <windows.h>
    #include <mapi.h>

    #include "Unit1.h"
    #define NUM_ELEMENTS(x) (sizeof((x)) / sizeof((x)[0]))
    //---------------------------------------------------------------------------
    #pragma resource "*.dfm"
    TForm1 Form1;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent
    Owner)
    : TForm(Owner)
    {

    }

    //---------------------------------------------------------------------------
    int _tmain(void)
    {
    LPMAPISENDMAIL pfnSendMail;
    MapiRecipDesc rdOriginator;
    MapiRecipDesc rdRecipient[1];
    LPMAPILOGOFF pfnLogoff;
    LPMAPILOGON pfnLogon;
    MapiMessage mapimsg;
    HINSTANCE hDll;
    LHANDLE lHnd;

    // Die Funktionen aus der DLL holen
    pfnLogon = (LPMAPILOGON)GetProcAddress(hDll, "MAPILogon");
    pfnLogoff = (LPMAPILOGOFF)GetProcAddress(hDll, "MAPILogoff");
    pfnSendMail = (LPMAPISENDMAIL)GetProcAddress(hDll, "MAPISendMail");

    pfnLogon(0, NULL, NULL, 0, 0, &lHnd); // Einloggen

    mapimsg.ulReserved = 0;
    mapimsg.lpszSubject = "E-müll";
    mapimsg.lpszNoteText = "Nachricht blablabla"; // EMailtext
    mapimsg.lpszMessageType = NULL;
    mapimsg.lpszDateReceived = NULL;
    mapimsg.lpszConversationID = NULL;
    mapimsg.flFlags = 0;
    mapimsg.lpOriginator = &rdOriginator;
    mapimsg.nRecipCount = NUM_ELEMENTS(rdRecipient);
    mapimsg.lpRecips = rdRecipient;

    rdOriginator.ulReserved = 0;
    rdOriginator.ulRecipClass = MAPI_ORIG;
    rdOriginator.lpszName = "rdOriginator";
    rdOriginator.lpszAddress = "ich@sender.de"; // Sender
    rdOriginator.ulEIDSize = 0;
    rdOriginator.lpEntryID = NULL;

    rdRecipient[0].ulReserved = 0;
    rdRecipient[0].ulRecipClass = MAPI_TO;
    rdRecipient[0].lpszName = "Karl-Otto"; // Empfängername
    rdRecipient[0].lpszAddress = "SMTP:Empfänger@web.de"; // Empfängeradresse
    rdRecipient[0].ulEIDSize = 0;
    rdRecipient[0].lpEntryID = NULL;

    pfnSendMail(lHnd, NULL, &mapimsg, 0, 0); // Das eigentliche Versenden

    pfnLogoff(lHnd, 0, 0, 0); // Ausloggen

    FreeLibrary(hDll);

    return (0);
    }

    Mein Compiler generiert zwar die Datei, aber es passiert nichts.
    Ich würde gerne auf einen Button drücken, sodass die Mail dann abgeschickt wird. Das ganze zeugs in den Befehl von Button reinzukopieren hat auch nix gebracht. 😞

    Der Text für den Button lautet:
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {

    }

    Weiss Jemand wie das geht? 😕 😕 :confused
    Mit Tips, wo man irgendwie nachshauen kann, komm ich nicht zu recht, da ich noch Anfänger bin. 🙄 Es würde mir sehr helfen, wenn mir jemand einen Fertigen Quelltext vorgeben würde, oder wenn dieser ok ist, was ich dann in den Befehl von Button schreiben muss.



  • Hi,
    warum glaubts du wohl muss man bei einem anderen EMail-Programm immer noch einen Postausgangsserver angeben? Ich sehe in deinem Code (auch wenn ich zugeben muss, dass ich nicht alles verstehe) nichts, wo du dich bei einem Postausgangsserver einloggst? Wohin soll denn die Mail dann gesendet werden?

    MfG

    Alexander Sulfrian

    PS: Schau die doch mal die Indy-Komponenten an....



  • Hallo,
    ich habe mir das nur ganz kurz angesehen, aber da geht so einiges schief. Hier nur 2 Sachen (das wird wahrscheinlich nicht reichen, bringt Dich aber vielleicht dichter an das Ziel.

    Du musst die dll vorher laden, bevor Du auf die Adressen zugreifen kannst

    hMapilib = LoadLibrary("MAPI32.DLL");
       lpfnMAPISendMail = (LPMAPISENDMAIL) GetProcAddress(hMapilib, "MAPISendMail");
       pfMapiLogon= (LPMAPILOGON)GetProcAddress(hMapilib,"MAPILogon");
       pfMapiLogoff=(LPMAPILOGOFF)GetProcAddress(hMapilib,"MAPILogoff");
    

    Dein 2. Problem ist der Speicher, der für diie Aufrufe verwendet wird. Immer, wenn eine Variable lpsz ... heisst, dann ist das ein ZEIGER auf ein Zeichenfeld. Die kann man nicht so einfach zuweisen, da muss man vorher schon ausreichend Speicherplatz für anfordern und den Inhalt der Zeichenkette an die entsprechende Position kopieren.

    So wird aus Deinem

    mapimsg.lpszSubject = "E-müll";
    

    schnell

    mapimsg.lpszSubject = new[strlen("E-müll") + 1]; 
    strcpy(mapimsg.lpszSubject, "E-müll");
    ...
    

    Das gleiche natürlich auch für den Absender, die Empfänger, .... Am Ende musst Du diesen Speicher auch noch aufräumen, also alles wieder freigeben. Deshalb lohnt es sich immer, um diese MAPI-Aufrufe eine eigene Highlevel- Funktion (oder Klasse) zu legen.

    Schöne Grüße aus Berlin

    Volker Hillmann



  • Ich hab keine Ahnung, was du geschrieben hast und was das bedeutet, aber trotzdem danke. Ich habe schon selber herausgefunden, wie ich die mail verschicken kann.
    Nur jetzt habe ich wiederum ein neues Problem. Es wird immer eine Meldung angezeigt, ob ich wirklich die mail verschicken will.
    <img src="http://www.lo-net.de/fileexchange/6187_926260/test.jpg">

    Kann ich die auch automatisch bestätigen lassen?



  • Hier ist mein Quellcode:

    //---------------------------------------------------------------------------
    #include <vcl\vcl.h>
    #pragma hdrstop
    #include <windows.h>
    #include <mapi.h>
    #include <tchar.h>
    #include <stdio.h>
    #define NUM_ELEMENTS(x) (sizeof((x)) / sizeof((x)[0]))

    #include "mail.h"
    //---------------------------------------------------------------------------
    #pragma resource "*.dfm"
    TForm1 Form1;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent
    Owner)
    : TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
    LPMAPISENDMAIL pfnSendMail;
    MapiRecipDesc rdOriginator;
    MapiRecipDesc rdRecipient[1];
    LPMAPILOGOFF pfnLogoff;
    LPMAPILOGON pfnLogon;
    MapiMessage mapimsg;
    HINSTANCE hDll;
    LHANDLE lHnd;

    if(NULL == (hDll = LoadLibrary(TEXT("MAPI32.DLL"))))
    {
    _tprintf(TEXT("could not load mapi32.dll, ErrorCode: %u"), GetLastError());

    }

    pfnLogon = (LPMAPILOGON) GetProcAddress(hDll, "MAPILogon");
    pfnLogoff = (LPMAPILOGOFF) GetProcAddress(hDll, "MAPILogoff");
    pfnSendMail = (LPMAPISENDMAIL)GetProcAddress(hDll, "MAPISendMail");

    pfnLogon(0, NULL, NULL, 0, 0, &lHnd);

    mapimsg.ulReserved = 0;
    mapimsg.lpszSubject = "Test-Betreff";
    mapimsg.lpszNoteText = "Test-Nachricht";
    mapimsg.lpszMessageType = NULL;
    mapimsg.lpszDateReceived = NULL;
    mapimsg.lpszConversationID = NULL;
    mapimsg.flFlags = 0;
    mapimsg.lpOriginator = &rdOriginator;
    mapimsg.nRecipCount = NUM_ELEMENTS(rdRecipient);
    mapimsg.lpRecips = rdRecipient;
    mapimsg.nFileCount = 0;
    mapimsg.lpFiles = NULL;

    rdOriginator.ulReserved = 0;
    rdOriginator.ulRecipClass = MAPI_ORIG;
    rdOriginator.lpszName = "rdOriginator";
    rdOriginator.lpszAddress = "test@irgendwo.de";
    rdOriginator.ulEIDSize = 0;
    rdOriginator.lpEntryID = NULL;

    rdRecipient[0].ulReserved = 0;
    rdRecipient[0].ulRecipClass = MAPI_TO;
    rdRecipient[0].lpszName = "rdRecipient[0]";
    rdRecipient[0].lpszAddress = "test@irgendwo.de";
    rdRecipient[0].ulEIDSize = 0;
    rdRecipient[0].lpEntryID = NULL;

    pfnSendMail(lHnd, NULL, &mapimsg, 0, 0);
    pfnLogoff(lHnd, 0, 0, 0);

    FreeLibrary(hDll);

    }
    //---------------------------------------------------------------------------

    Wennn ich auf den Button1 drücke, werde ich gefragt, ob ich die E-Mail senden will. Ich würde dieses gerne automatisch bestätigen lassen.

    Hat da jemand ne Idee? 😕 😕 😕 😕



  • Es gibt mehrere Möglichkeiten eine EMail aus dem eigenen Programm zu versenden. Die beiden gebräuchlisten sind: SMTP (Simple Mail Transfer Protokoll) und MAPI (Mail Application Programming Interface).

    Während für MAPI ein s.g. MAPI-Client (ein Programm welches die e-Mail Funktion über MAPI zu Verfügung stellt) auf dem entsprechenden Rechner installiert sein muss (in deinem Fall Outlook Express) ist dies bei SMTP nicht nötig. Dafür ist man bei SMTP auf einen SMTP-Server im Internet angewiesen, dieser sollte von Benutzer eingestellt werden können.

    Bei SMTP muss man sich desweiteren mit Protokoll und dem Format an sich auseinandersetzten, das Format ist im RFC 822 definiert. Das Protokoll wirt in RFC 821 beschrieben. Dafür ist SMTP Plattformunabhängig.

    Für MAPI gibt es noch einen Scriptfähigen Aufsatz mit dem Namen CDO (Collaboration Data Objects), dies ist ein COM-Basierender Ansatz um EMails aus Programmen zu verschicken.

    Beispiel Programme dazu gibt es im Internet Bereich auf der CodeGuru Webseite, dort den Unterpunkt EMail.

    http://www.codeguru.com/Cpp/I-N/internet/

    oder du benutzt direkt Outlook, dazu sollte dir das weiterhelfen http://support.microsoft.com/?kbid=220600. Ich weiß aber nicht ob das auch für outlook express zählt 😃

    cux mosta



  • mailer schrieb:

    Wennn ich auf den Button1 drücke, werde ich gefragt, ob ich die E-Mail senden will. Ich würde dieses gerne automatisch bestätigen lassen.

    Dies ist AFAIK nicht zu umgehen, da es ein Teil der Sicherheitspatches von MS gegen Viren ist. Damit soll umgangen werden, dass ein Programm unerwünscht Mails über Outlook versendet. Nicht umsonst haben die Viren heutzutage eine eigene SMTP-Engine.

    Joe_M.


Anmelden zum Antworten