启动默认的电子邮件客户端,用预先选定的文件附件打开“发送电子邮件”窗口

问题描述:

我需要为我们的应用程序添加“创建并发送电子邮件”功能。我们的程序会创建一个输出文件,然后我必须启动默认的电子邮件客户端来打开“写入电子邮件”窗口,并将输出文件预先选为附件。启动默认的电子邮件客户端,用预先选定的文件附件打开“发送电子邮件”窗口

我已经看到其他程序这样做,即使默认客户端是Thunderbird而不是Outlook。

+0

可以使用的ShellExecute与收件人地址启动电子邮件客户端(见下面的链接),但不知道如何通知客户有关attachement。 http://*.com/questions/3863231/easy-way-to-invoke-standard-mail-client-from-c-with-recipient-adress-and-subjec/3863259#3863259 – 2011-01-27 19:44:56

我最终使用MAPI来实现它。我使用LoadLibrary和GetProcAddress来获得所需的功能。

我使用的代码是这样的:

bool MailSender::Send(HWND hWndParent, LPCTSTR szSubject) 
{ 
    if (!m_hLib) 
     return false; 

    LPMAPISENDMAIL SendMail; 
    SendMail = (LPMAPISENDMAIL) GetProcAddress(m_hLib, "MAPISendMail"); 

    if (!SendMail) 
     return false; 

    vector<MapiFileDesc> filedesc; 
    for (std::vector<attachment>::const_iterator ii = m_Files.begin(); ii!=m_Files.end(); ii++) 
    { 
     MapiFileDesc fileDesc; 
     ZeroMemory(&fileDesc, sizeof(fileDesc)); 
     fileDesc.nPosition = (ULONG)-1; 
     fileDesc.lpszPathName = (LPSTR) ii->path.c_str(); 
     fileDesc.lpszFileName = (LPSTR) ii->name.c_str(); 
     filedesc.push_back(fileDesc); 
    } 

    std::string subject; 
    if (szSubject) 
     subject = utf16to8(szSubject).c_str(); 
    else 
    { 
     for (std::vector<attachment>::const_iterator ii = m_Files.begin(); ii!=m_Files.end(); ii++) 
     { 
      subject += ii->name.c_str(); 
      if (ii+1 != m_Files.end()) 
       subject += ", "; 
     } 
    } 

    MapiMessage message; 
    ZeroMemory(&message, sizeof(message)); 
    message.lpszSubject = (LPSTR) subject.c_str(); 
    message.nFileCount = filedesc.size(); 
    message.lpFiles = &filedesc[0]; 

    int nError = SendMail(0, (ULONG)hWndParent, &message, MAPI_LOGON_UI|MAPI_DIALOG, 0); 

    if (nError != SUCCESS_SUCCESS && nError != MAPI_USER_ABORT && nError != MAPI_E_LOGIN_FAILURE) 
     return false; 

    return true; 
} 

使用mailto方案可能是一个解决方案,但它会很棘手,由于在哪些领域被认为是安全的(参见RFC 23686067的全部细节,如果你想要去的路线)的限制。

另一个解决方案是找出安装的电子邮件客户端,并在任何可能的情况下启动它,并通过命令行指定所需的全部内容。对于Outlook,请参阅here Thunderbird & here

+0

谢谢,但mailto doesn不支持文件附件。我测试了具有此功能的第三方应用程序。他们使用以下命令行调用Thunderbird:“”C:\ Program Files \ Mozilla Thunderbird \ thunderbird.exe“/ MAPIStartup -Embedding”。所以他们似乎在使用MAPI来实现结果。我会尽力先调查一下。 – sashoalm 2011-01-28 08:25:16

+0

@satuon:使用`mailto`我在想将MIME编码的附件包含在body字段中,但它至少会很棘手,而且很可能根本不起作用。查看答案中关于Thunderbird和Outlook的备用命令行选项的链接。 – 2011-01-28 08:36:57