我正在使用this method从Delphi应用程序中发送带有PDF附件的MAPI电子邮件。
它会显示一个MS Outlook“新消息”窗口,其中已附加了pdf文档,并且是一个空白收件人。
如果您输入正常的电子邮件联系人,那么它会很顺利。
但是,如果您选择传真收件人,它将显示在我的“已发送邮件”文件夹中,但是传递无提示失败(没有错误,没有MS Outlook“传递失败”消息,并且没有传递邮件)。
“传真收件人”在MS Outlook中设置,只有传真号码。没有电子邮件或任何东我们使用faxcore server将这些“传真”路由到Outlook收件箱。
如果您look at this image,我为此联系人填写的唯一字段是标有“商务传真”的字段。
如果我手动(即在我的应用程序之外)创建一个标准的MS Outlook电子邮件并选择完全相同的传真收件人,并手动附加相同的PDF,那么它就可以了。
因此,似乎使用MAPI发送到传真号码会导致其失败。 This post sounds similar, except they get a "message undeliverable" error and I don't.
有谁可以给我一些指示?
由于
更新:如果我使用MAPI创建电子邮件,但我手动删除了附件,那么 就可以了。因此,从外观来看,我可以通过电子邮件将附件发送给传真收件人,但使用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.
答案 0 :(得分:2)
好的,你的更新指向附件,所以我要再猜一下:尝试将附件的文件类型明确地设置为'application / 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;
(代码格式化程序并不是特别有帮助)。
答案 1 :(得分:1)
可能是0(临时)会话中的传真地址不可用吗?换句话说,首先使用MAPILogon登录会话,然后在MAPISendMail调用帮助中提供hSession吗?
答案 2 :(得分:1)
您可以尝试启用Outlook Transport Logging,希望某些(任何)错误消息会在那里出现。确保首先记录手动传真(工作情况),以检查相关内容是否确实显示在此日志中。
不幸的是,我通过此日志解决问题的个人成功率很高,但尝试获取更多信息从不会伤害,对吗?