Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 使用TIdMessageBuilderHtml设置电子邮件附件名称_Delphi_Smtp_Indy - Fatal编程技术网

Delphi 使用TIdMessageBuilderHtml设置电子邮件附件名称

Delphi 使用TIdMessageBuilderHtml设置电子邮件附件名称,delphi,smtp,indy,Delphi,Smtp,Indy,我正在尝试使用Delphi(D10S)将PDF文档附加到电子邮件中,我希望将名称设置为文件系统上文件名以外的其他名称 我发现了以下线程(从2011年开始),Remy Lebeau指出,在使用TIdMessageBuilderHtml将对象附加到电子邮件时,可以通过设置TIdMessageBuilderAttachment对象的Name属性来实现这一点: 然而,这听起来很简单,但似乎对我不起作用。电子邮件通过了,但是附件通过了原始文件名,而不是我指定的文件名 下面是一段代码,我希望按照我所描述的

我正在尝试使用Delphi(D10S)将PDF文档附加到电子邮件中,我希望将名称设置为文件系统上文件名以外的其他名称

我发现了以下线程(从2011年开始),Remy Lebeau指出,在使用
TIdMessageBuilderHtml
将对象附加到电子邮件时,可以通过设置
TIdMessageBuilderAttachment
对象的
Name
属性来实现这一点:

然而,这听起来很简单,但似乎对我不起作用。电子邮件通过了,但是附件通过了原始文件名,而不是我指定的文件名

下面是一段代码,我希望按照我所描述的那样去做,但是,不管出于什么原因,我没有这样做。在本例中,我希望文件名显示为
所需的\u filename.pdf
,但它显示为
所需的\u filename.pdf
。我已删除邮件服务器凭据,原因很明显:

procedure TForm4.Button1Click(Sender: TObject);
var
  FMessageBuilder : TIdMessageBuilderHtml;
  FSMTP : TIdSMTP;
  FMessage : TIdMessage;
  FAttachment : TIdMessageBuilderAttachment;
begin
  FMessage := TIdMessage.Create();
  FMessageBuilder := TIdMessageBuilderHtml.Create;
  FSMTP := TIdSMTP.Create;

  FAttachment := FMessageBuilder.Attachments.Add('c:\undesired_filename.pdf');
  FAttachment.Name := 'desired_filename.pdf';
  FMessageBuilder.FillMessage(FMessage);

  FMessage.Sender.Address := '<Insert Sender Address>';
  FMessage.Sender.Name := '<Insert Sender Name>';
  FMessage.From.Address := '<Insert From Address>';
  FMessage.From.Name := '<Insert From Name>';
  FMessage.Recipients.EMailAddresses := '<Insert Recepient Address>';
  FMessage.Subject := 'Attachment Test';

  FSMTP.Host := '<Insert Mail Host>';
  FSMTP.Username := '<Insert Username>';
  FSMTP.Password := '<Insert Password>';
  FSMTP.Connect;
  FSMTP.Send(FMessage);
  FSMTP.Disconnect;
end;
程序TForm4.按钮1点击(发送者:ToObject);
变量
FMessageBuilder:TIdMessageBuilderHtml;
FSMTP:tidstp;
FMessage:TIdMessage;
FAttachment:TIdMessageBuilderAttachment;
开始
FMessage:=TIdMessage.Create();
FMessageBuilder:=TIdMessageBuilderHtml.Create;
FSMTP:=tidstp.Create;
FAttachment:=FMessageBuilder.Attachments.Add('c:\undefered_filename.pdf');
FAttachment.Name:=“所需的文件名.pdf”;
FMessageBuilder.FillMessage(FMessage);
FMessage.Sender.Address:='';
FMessage.Sender.Name:='';
FMessage.From.Address:='';
FMessage.From.Name:='';
FMessage.Recipients.EMailAddresses:='';
FMessage.Subject:=“附件测试”;
FSMTP.Host:='';
FSMTP.Username:='';
FSMTP.密码:='';
连接;
FSMTP.Send(FMessage);
断开连接;
结束;

我已经在D10和XE中测试过了,它们都做了同样的测试。知道我做错了什么吗?

使用
TIdMessageBuilderAttachments.Add
重载,它接受
TStream
,并将
TIdMessageBuilderAttachment.FileName
属性设置为所需的名称,这对我在XE4(Indy 10.6.0.4975)上很有帮助

stream := TFileStream.Create('c:\undesired_filename.pdf', fmOpenRead);
FAttachment := FMessageBuilder.Attachments.Add(stream, 'application/pdf');
FAttachment.FileName := 'desired_filename.pdf';

TIdMessageBuilderAttachment
同时具有
FileName
Name
属性。将附件添加到生成器时,这些值将分配给添加到
TIdMessage.MessageParts
集合的
TIdAttachment
对象的相应属性

如果附件分配了
名称
,则该值将置于
内容类型
标题的
名称
属性中,例如:

Content-Type: media/type; name="desired_filename.pdf"
Content-Disposition: attachment; filename="undesired_filename.pdf"
如果附件分配了
文件名
,则该值将置于
内容处置
标题的
文件名
属性中,例如:

Content-Type: media/type; name="desired_filename.pdf"
Content-Disposition: attachment; filename="undesired_filename.pdf"
如果两个标题都存在,则一致性读者在查找文件名时将给予
内容处置
优先级。这就是您的阅读器显示不需要的文件名的原因

将物理文件添加到生成器时,
TIdMessageBuilderAttachment
当前不允许您指定与实际文件不同的
文件名。这是因为
TIdMessageBuilderAttachment
不是实际加载文件的。它只创建一个新的
TIdAttachmentFile
对象,并将其
FileName
分配给该对象,因此它需要实际的文件名,否则发送电子邮件时附件将无法加载。但是,
TIdAttachmentFile
确实允许在创建后自定义自己的
FileName
。它有一个单独的
StoredPathName
属性来跟踪物理文件,因此它的
FileName
可以是您想要的任何文件

在@Fantagirocco的示例中,将
TStream
添加到生成器会导致
TIdAttachmentMemory
添加到
TIdMessage
中,而不是
TIdAttachmentFile
。由于不涉及任何物理文件,因此附件的
文件名可以是您想要的任何内容

因此,必须更新
TIdMessageBuilderAttachment
,以允许将物理文件附件的
文件名
与其
存储路径名
分开设置。同时,您可以在填写
TIdMessage
后手动更新
TIdAttachmentFile.FileName
属性,例如:

FAttachment := FMessageBuilder.Attachments.Add('c:\undesired_filename.pdf');
FAttachment.Name := 'desired_filename.pdf';
FMessageBuilder.FillMessage(FMessage);

for I := 0 to FMessage.MessageParts.Count-1 do
begin
  if FMessage.MessageParts[I].PartType = mptAttachment then
    FMessage.MessageParts[I].FileName = FMessage.MessageParts[I].Name;
end;

那很有效,谢谢!然而,我仍然有点好奇,想知道我使用的方法有什么问题。在我把这个标记为答案之前,我会等着看是否有其他人能找到答案(我也没有足够的声誉来+1这个,但如果我能的话,我会的)。@Adam,不客气,将此视为一个解决方案,直到'ReMy将解决您的问题],这种方法的一个问题是,该重载导致输入<代码> TStase数据被复制到内存中(A<代码> TIdAttachmentMemory < /Cord>对象被添加到<代码> TIDeMase. MessageParts < /Cuff>集合),因此,这对于大型附件是不可取的。我已经将Remy的答案标记为已被接受,因为它提供了一个解决方案,并解释了为什么我的方法不起作用。我希望你不介意。@Adam根本没有问题,这是它的用途。你做得对,谢谢;)哇,我从没想到你会来回答这个问题!谢谢如果在“TIdMessageBuilderAttachment”上设置“name”属性只会更新“Content Type”标题,但“Content Disposition”(填充了我的“FileName”)具有优先权,这是否意味着您在我链接的线程中给出的示例也会有同样的问题,或者我遗漏了一些细微的差异?我只是假设他对你的答案很满意,他也会这么做。前面的例子也会遇到同样的问题。这是我第一次写它时没有考虑到的
TIdMessageBuilder
的一个限制,因此我必须对它进行更新以考虑它