我正在使用Delphi 2006,Indy 10(版本4957),IMAP4。
我想下载一封电子邮件,存储它,几周后我想在另一个文件夹中重新创建它。 (它有点归档和恢复它,所以在文件夹之间移动是不行的,因为我将删除原始消息。)我下载消息,存储它,然后用AppendMsg
制作它的副本。
直到那时我检查目标Temp2文件夹,其中大多数邮件包含
这是MIME格式的多部分邮件
unit Mail_Test;
interface
uses
Windows,
Messages,
SysUtils,
Variants,
Classes,
Graphics,
Controls,
Forms,
Dialogs,
StdCtrls;
type
TForm1 = class( TForm )
memLog: TMemo;
btn1: TButton;
procedure btn1Click( Sender: TObject );
private
procedure Log( LogMsg: string );
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses
IdIMAP4,
IdMessage,
IdExplicitTLSClientServerBase,
IdSSLOpenSSL;
{$R *.dfm}
procedure TForm1.btn1Click( Sender: TObject );
var
IMAPClient: TIdIMAP4;
UsersFolders: TStringList;
OpenSSLHandler: TIdSSLIOHandlerSocketOpenSSL;
res: Boolean;
i: integer;
inbox, currUID: string;
cntMsg: integer;
msg, msg2: TIdMessage;
BodyTexts: TStringList;
flags: TIdMessageFlagsSet;
fileName_MailSource, TmpFolder: string;
begin
IMAPClient := TIdIMAP4.Create( nil );
try
OpenSSLHandler := TIdSSLIOHandlerSocketOpenSSL.Create( nil );
try
IMAPClient.Host := 'imap.gmail.com';
IMAPClient.Port := 993;
IMAPClient.Username := '....@gmail.com';
IMAPClient.Password := '....';
if Pos( 'gmail.com', IMAPClient.Host ) > 0 then begin
OpenSSLHandler.SSLOptions.Method := sslvSSLv3;
IMAPClient.IOHandler := OpenSSLHandler;
IMAPClient.UseTLS := utUseImplicitTLS;
end;
try
res := IMAPClient.Connect;
if not res then begin
Log( ' Unsuccessful connection.' );
exit;
end;
except
on e: Exception do begin
Log( ' Unsuccessful connection.' );
Log( ' (' + Trim( e.Message ) + ')' );
exit;
end;
end;
try
UsersFolders := TStringList.Create;
try
res := IMAPClient.ListMailBoxes( UsersFolders );
if not res then begin
Log( ' ListMailBoxes error.' );
exit
end;
except
on e: Exception do begin
Log( ' ListMailBoxes error.' );
Log( ' (' + Trim( e.Message ) + ')' );
exit;
end;
end;
Log( 'User folders: ' + IntToStr( UsersFolders.Count ) );
for i := 0 to UsersFolders.Count - 1 do begin
Log( ' [' + inttostr( i + 1 ) + '/' + inttostr( UsersFolders.Count ) + '] Folder: "' + UsersFolders[ i ] + '"' );
end;
IMAPClient.RetrieveOnSelect := rsDisabled;
inbox := 'INBOX';
Log( 'Opening folder "' + inbox + '"...' );
res := IMAPClient.SelectMailBox( inbox );
cntMsg := IMAPClient.MailBox.TotalMsgs;
Log( 'E-mails to read: ' + IntToStr( cntMsg ) );
// res := IMAPClient.RetrieveAllEnvelopes( AMsgList );
msg := TIdMessage.Create( nil );
msg2 := TIdMessage.Create( nil );
BodyTexts := TStringList.Create;
TmpFolder := 'c:\';
res := IMAPClient.CreateMailBox( 'Temp2' )
try
for I := 0 to cntMsg - 1 do begin
Log( ' [' + inttostr( i + 1 ) + '/' + inttostr( cntMsg ) + '] E-mail...' );
IMAPClient.GetUID( i + 1, currUID );
Log( '(Downloading message...)' );
IMAPClient.UIDRetrieve( currUID, msg );
fileName_MailSource := TmpFolder + 'Log_Mail_' + currUID + '.eml';
msg.SaveToFile( fileName_MailSource, false );
// In the final version I will delete the original message
// so I have to recreate it from the archived file
msg2.LoadFromFile( fileName_MailSource );
res := IMAPClient.AppendMsg( 'Temp2', msg2, msg2.Headers, [] );
end;
finally
FreeAndNil( msg );
FreeAndNil( msg2 );
FreeAndNil( BodyTexts )
end;
finally
IMAPClient.Disconnect;
end;
finally
OpenSSLHandler.Free;
end;
finally
IMAPClient.Free;
end;
end;
procedure TForm1.Log( LogMsg: string );
begin
memLog.Lines.Add( LogMsg );
Application.ProcessMessages;
end;
end.
答案 0 :(得分:3)
您正在调用AppendMsg()
版本,可让您指定其他电子邮件标头。几乎在我能想到的每种情况下,你都不会想要这样做(我甚至不知道为什么TIdIMAP4会暴露这种功能)。
原因是AppendMsg()
将TIdMessage
保存到内部TStream
,然后将电子邮件正文从TStream
发送到服务器。如果您指定了备用标头,它们将按原样发送,并且与用于创建电子邮件正文的标头数据不匹配。最重要的是,用于分隔电子邮件正文中MIME部分的MIME边界将与实际发送到服务器的标头中指定的边界不匹配,这将考虑您所看到的症状。无论何时编码,TIdMessage
都会随机生成该边界值,因此在调用TIdMessage.Headers
之前,AppendMsg()
属性中无法使用该边界值。
所以,话虽如此,我强烈建议您更改代码,将AAlternativeHeaders
的{{1}}参数设置为nil(或使用没有AppendMsg()
的重载版本完全AppendMsg()
参数),以便AAlternativeHeaders
发送AppendMsg()
在上传之前编码时生成的实际标题:
TIdMessage
或者:
res := IMAPClient.AppendMsg( 'Temp2', msg2, nil, [] );