2

我正在使用这种方法从 Delphi 应用程序内部发送带有 PDF 附件的 MAPI 电子邮件。

它会打开一个 MS Outlook“新消息”窗口,其中包含已附加的 pdf 文档和一个空白收件人。

如果你输入一个普通的电子邮件联系人,那么它就可以了。

但是,如果您选择一个传真收件人,它会出现在我的“已发送邮件”文件夹中,但发送失败时会静默失败(没有错误,没有 MS Outlook“发送失败”消息,也没有发送消息)。

“传真收件人”在 MS Outlook 中设置,只有一个传真号码。没有电子邮件或任何东西。我们使用传真核心服务器将这些“传真”路由到 Outlook 收件箱。

如果您查看这张图片,我为该联系人填写的唯一字段是标有“商务传真”的字段。

如果我手动(即,在我的应用程序之外)创建标准的 MS Outlook 电子邮件并选择相同的传真收件人,并手动附加相同的 PDF,那么它可以正常工作。

因此,似乎有关使用 MAPI 发送到传真号码的某些事情会导致它失败。 这篇文章听起来很相似,除了他们收到“无法传递的消息”错误而我没有。

谁能给我一些指示?

谢谢

更新:如果我使用 MAPI 创建电子邮件,然后我手动删除了附件,那么它确实有效。因此,在 Outlook 中,我可以将附件通过电子邮件发送给传真收件人,但使用 MAPI 失败。

完整的源代码如下:

unit Main;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    function SendEMailUsingMAPI(const Subject, Body, FileName, SenderName,
      SenderEMail, RecipientName, RecipientEMail: string): integer;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

uses
  Mapi;

procedure TForm1.Button1Click(Sender: TObject);
begin
  //this will bring up an MS Outlook dialog.
  //inside that dialog, if i choose a normal email recipient, it works.
  //                    if i choose a fax recipient, it fails silently.
  //if i create the email from w/in outlook, it can go to *either* with success.

  SendEmailUsingMAPI(
    'Subject',  //subject of email
    'Body',  //body of email text
    'c:\my_doc.pdf',  //attachment file name
    'My name',  //sender email name
    'myemail@mydomain.com',  //sender email address
    '',  //recipient email name
    '');  //recipient email address
end;


function TForm1.SendEMailUsingMAPI(const Subject, Body, FileName, SenderName,
  SenderEMail, RecipientName, RecipientEMail: string): Integer;
var
  Message: TMapiMessage;
  lpSender, lpRecipient: TMapiRecipDesc;
  FileAttach: TMapiFileDesc;
  SM: TFNMapiSendMail;
  MAPIModule: HModule;
  FileType: TMapiFileTagExt;
begin
  FillChar(Message,SizeOf(Message),0);

  if (Subject <> '') then begin
    Message.lpszSubject := PChar(Subject);
  end;

  if (Body <> '') then begin
    Message.lpszNoteText := PChar(Body);
  end;

  if (SenderEmail <> '') then
  begin
    lpSender.ulRecipClass := MAPI_ORIG;
    if (SenderName = '') then begin
      lpSender.lpszName := PChar(SenderEMail);
    end
    else begin
      lpSender.lpszName := PChar(SenderName);
    end;
    lpSender.lpszAddress := PChar(SenderEmail);
    lpSender.ulReserved := 0;
    lpSender.ulEIDSize := 0;
    lpSender.lpEntryID := nil;
    Message.lpOriginator := @lpSender;
  end;

  if (RecipientEmail <> '') then begin
    lpRecipient.ulRecipClass := MAPI_TO;
    if (RecipientName = '') then begin
      lpRecipient.lpszName := PChar(RecipientEMail);
    end
    else begin
      lpRecipient.lpszName := PChar(RecipientName);
    end;
    lpRecipient.lpszAddress := PChar(RecipientEmail);
    lpRecipient.ulReserved := 0;
    lpRecipient.ulEIDSize := 0;
    lpRecipient.lpEntryID := nil;
    Message.nRecipCount := 1;
    Message.lpRecips := @lpRecipient;
  end
  else begin
    Message.lpRecips := nil;
  end;

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

    FileType.ulReserved := 0;
    FileType.cbEncoding := 0;
    FileType.cbTag := 0;
    FileType.lpTag := nil;
    FileType.lpEncoding := nil;

    FileAttach.lpFileType := @FileType;
    Message.nFileCount := 1;
    Message.lpFiles := @FileAttach;
  end;

  MAPIModule := LoadLibrary(PChar(MAPIDLL));

  if MAPIModule = 0 then begin
    Result := -1;
  end
  else begin
    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 begin
        Result := 1;
      end;
    finally
      FreeLibrary(MAPIModule);
    end;
  end;

  if Result <> 0 then begin
    MessageDlg('Error sending mail ('+IntToStr(Result)+').',mtError,[mbOK],0);
  end;
end;

end.
4

3 回答 3

2

好的,您的更新指向附件,所以我要进行另一个猜测:尝试将附件的文件类型明确设置为“应用程序/pdf”(您当前的代码未设置 lpFileType 字段)。传真处理可能取决于此。您可以将 MapiFileTagExt(lpFileType 指向的类型)的编码部分留空,只需 FillChar 记录并设置 cbTag 和 lpTag 字段。

如果您需要代码(mapi 结构有时可能有点令人眼花缭乱),只需大喊大叫,但我需要一些时间才能找到时间来输入它。无论如何,我只是在猜测。我的家庭环境中没有传真设置,否则我会做一些适当的测试。

编辑

说明下面的代码。但是,从那时起,我就使用 Outlook Spy 进行了检查,并且没有使用任何方法,也没有手动附加文件时,似乎在发送的项目上设置了 PR_ATTACH_MIME_TAG 属性,仅在生成的传入消息上设置。

  FillChar(FileAttach,SizeOf(FileAttach),0);
  FileAttach.nPosition := Cardinal($FFFFFFFF);
  FileAttach.lpszPathName := PChar(FileName);
  //
  MimeType := 'application/pdf'; 
  //
  FileType.ulReserved := 0;
  FileType.cbTag := Length( MimeType );
  FileType.lpTag := PByte(MimeType);
  FileType.cbEncoding := 0;
  FileType.lpEncoding := nil;
  //
  FileAttach.lpFileType := @FileType;
  Message.nFileCount := 1;
  Message.lpFiles := @FileAttach;

(代码格式化程序并不是特别有用)。

于 2009-08-06T18:41:20.357 回答
1

您可以尝试启用Outlook Transport Logging,希望那里会出现一些(任何)错误消息。确保首先记录手动传真(工作情况),以检查此日志中是否确实显示了任何相关内容。

不幸的是,我个人通过此日志解决问题的成功率是 zilch,但尝试获取更多信息永远不会受到伤害,对吧?

于 2009-08-06T13:22:23.847 回答
1

可能是传真地址在 0(临时)会话中不可用吗?换句话说,是否首先使用 MAPILogon 登录会话,然后在 MAPISendMail 调用帮助中提供 hSession?

于 2009-08-05T20:02:29.467 回答