【问题标题】:Win32, C++: Sending email in Windows 10 by invoking default mail clientWin32、C++:通过调用默认邮件客户端在 Windows 10 中发送电子邮件
【发布时间】:2017-12-04 17:58:37
【问题描述】:

在 Stackoverflow 以及许多其他网站中,有很多帖子展示了如何通过调用默认邮件客户端来发送带有附件的电子邮件。当您在 Windows 资源管理器中右键单击任何文件并从上下文菜单中选择“发送至”->“邮件收件人”时,几乎相同。

我在网上找到的很多这些示例都使用 MAPI,但它们都不起作用。还有一些使用 ShellExecute 和使用 mailto: 协议的示例。后者对我有用,但在我尝试发送附件时不起作用。附件根本不会出现在 Outlook 的“新邮件”窗口中。 MAPI 示例再次不适用于附件。我收到奇怪的错误,比如我是要允许还是拒绝。

如果 Windows 能够做到,那意味着其他应用程序也应该能够做到。有谁知道适用于 Windows 10 的 API 吗?

【问题讨论】:

  • 我知道你已经标记了 C++,但是如果你可以利用它,.NET 的 System.Net.Mail 工作得很好 - 并且完全支持附件。
  • 是否允许或拒绝对我来说听起来像是一个安全提示,而不是一个奇怪的错误。
  • @GSerg,即使在我允许之后,它也不会继续。并且API调用返回0,表示没有错误...
  • @STLDeveloper,我很确定 .Net 可以工作:) 问题是我的应用程序在 Qt 中,我不想向 .Net 添加依赖项。
  • 我不清楚 Windows 是否可以使用任意邮件客户端来做到这一点。 Explorer 中的 SendTo 调用一个 COM 对象,该对象适用于各种 Outlook 风格。 codeproject.com/Articles/3839/SendTo-mail-recipient

标签: c++ email winapi windows-10


【解决方案1】:

这是有效的代码。它与 Qt 的东西混合在一起,但 Qt 类后来在代码中转换为 STL。我的代码以前不起作用的原因是因为我将 lpszPathName 设置为附件的路径,并将 lpszFileName 设置为附件的文件名。路径必须设置为包含文件名的完整路径,并且文件名应设置为我们希望在电子邮件客户端中显示为附件名称的任何内容。它可能只是文件名,也可能是其他内容。

bool InvokeDefaultEmailClient(HWND hwndParent, const QStringList 
                             &attachmentFilenames, const QString &subject)
{
    HINSTANCE hInst = LoadLibraryW(L"mapi32.dll");
    if (!hInst) {
        return false;
    }

    ULONG(PASCAL *SendMail)(ULONG, ULONG_PTR, MapiMessageW*, FLAGS, ULONG);
    (FARPROC&)SendMail = GetProcAddress(hInst, "MAPISendMailW");

    if (!SendMail) {
        return false;
    }

    std::vector<std::wstring> attachmentFilenamesVector;
    for(int i=0; i<attachmentFilenames.size(); ++i) {
        QString filename = attachmentFilenames[i];
        attachmentFilenamesVector.push_back(filename.toStdWString());
    }

    QVector<MapiFileDescW> fileDescs;
    for (int i = 0; i < attachmentFilenamesVector.size(); ++i) {
        MapiFileDescW fileDesc;
        ZeroMemory(&fileDesc, sizeof(fileDesc));
        fileDesc.nPosition = (ULONG)-1;
        fileDesc.lpszPathName = (TCHAR*)attachmentFilenamesVector[i].c_str();
        fileDesc.lpszFileName = (TCHAR*)attachmentFilenamesVector[i].c_str();
        fileDescs.push_back(fileDesc);
    }

    MapiMessageW message;
    ZeroMemory(&message, sizeof(message));
    message.lpszSubject = (TCHAR*)subject.toStdString().c_str();
    message.nFileCount = fileDescs.size();
    message.lpFiles = fileDescs.data();

    int error = SendMail(0, (ULONG_PTR)hwndParent, &message, MAPI_LOGON_UI | MAPI_DIALOG, 0);

    if (error != SUCCESS_SUCCESS && error != MAPI_USER_ABORT && error != MAPI_E_LOGIN_FAILURE) {
        return false;
    }

    return true;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-06-02
    • 2022-01-13
    • 2010-10-23
    • 1970-01-01
    • 1970-01-01
    • 2014-07-11
    • 2015-10-28
    • 1970-01-01
    相关资源
    最近更新 更多