Search code examples
c++emailsmtpemail-attachmentsvisual-c++-2010-express

CSmtp won't send an e-mail attachment. But without the attachment it works fine. (c++)


I have a problem with sending an attachment using CSmtp class.
Here's the code on that link:

int SendMail()
{
  bool bError = false;

  try
  {
    CSmtp mail;

#define test_gmail_tls

#if defined(test_gmail_tls)
    mail.SetSMTPServer("smtp.gmail.com",587);
    mail.SetSecurityType(USE_TLS);
#elif defined(test_gmail_ssl)
    mail.SetSMTPServer("smtp.gmail.com",465);
    mail.SetSecurityType(USE_SSL);
#elif defined(test_hotmail_TLS)
    mail.SetSMTPServer("smtp.live.com",25);
    mail.SetSecurityType(USE_TLS);
#elif defined(test_aol_tls)
    mail.SetSMTPServer("smtp.aol.com",587);
    mail.SetSecurityType(USE_TLS);
#elif defined(test_yahoo_ssl)
    mail.SetSMTPServer("plus.smtp.mail.yahoo.com",465);
    mail.SetSecurityType(USE_SSL);
#endif

    mail.SetLogin("email@email.com");
    mail.SetPassword("password");
    mail.SetSenderName("");
    mail.SetSenderMail("email@email.com");
    mail.SetReplyTo("");
    mail.SetSubject("Subject");
    mail.AddRecipient("email@email.com");
    mail.SetXPriority(XPRIORITY_NORMAL);
    mail.SetXMailer("The Bat! (v3.02) Professional");
    mail.AddMsgLine("Hello,");
    mail.AddMsgLine("you have been successfully registered!");
    mail.AddMsgLine(" ");
    mail.AddMsgLine("Username: ");
    mail.AddMsgLine("Password: ");
    mail.AddMsgLine(" ");
    mail.AddMsgLine("See ya!");

    mail.AddAttachment("C:\\Users\\Jenda\\AppData\\Roaming\\text.dat");
    mail.Send();
}
catch(ECSmtp e)
{
    std::cout << "Error: " << e.GetErrorText().c_str() << ".\n";
    bError = true;
}
if(!bError)
    std::cout << "Registration E-Mail was sent on given address.\n";
return 0;
}

When I comment the attachment line, it successfully send the e-mail. BUT when I try to send that attachment it seems it just stops there and does nothing - it doesn't return any error or anything. It just does nothing (it is responding though - according to task manager, you know).

Also, here is a secondary question: You see the attachment path (C:\Users\Jenda\AppData\Roaming\text.dat)? How could the program get information about the user (name) and how could I add it into the path so it works on every computer. C:\Users\ WINDOWSUSERNAME \...

That's it, thank you for all your responses and ideas.

P.S. I am using Windows7 32bit and Visual c++ Express 2010.


Solution

  • For the first question I believe you are referring to this code.

    Possible issues:

    A)

    In CSmtp.cpp:

    hFile = fopen(FileName.c_str(), "rb");
    

    should be (also you should consider fopen_s):

    hFile = fopen(Attachments[FileId].c_str(), "rb");
    

    B)

    In the header file CSmtp.h there is a line specifying the maximum size of the mail. Probably your attachments are greater than 5MB. Change it to 25MB:

    #define MSG_SIZE_IN_MB 5  // the maximum size of the 
                              // message with all attachments
    

    C)

    There are a lot of Windows/Linux specific parts in the code. One such example is:

    pos = Attachments[FileId].find_last_of("\\");
    

    due to this the path of your attachment needs to contain "\\" and not "/" if you are in windows. A better approach would have been to get from the system the separation. In a few words see if you have defined the path properly (example: "c:\\test3.txt").

    D)

    I highly advice you to add at the end of main.cpp the line (in order to be able to see the system messages):

    Sleep(4000);
    

    For the second question you could do something like (also see here):

    #include <cassert>
    #include <fstream>
    #include <string>
    #include <Windows.h>
    
    std::string getPath(void){
        //Get local dir
        TCHAR szBuf[MAX_PATH] = { 0 };
        ::GetEnvironmentVariable("USERPROFILE", szBuf, MAX_PATH);
        std::string path = szBuf;
        path += "\\AppData\\Roaming\\text.dat";
        return path;
    }