It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center




7年前关闭。





我正在使用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 := '[email protected]';
      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.

最佳答案

您正在调用AppendMsg()的版本,该版本允许您指定备用电子邮件标题。在我能想到的几乎每种情况下,您都永远不会这样做(我什至不知道为什么TIdIMAP4公开了该功能)。

原因是因为AppendMsg()TIdMessage保存到内部TStream,然后将电子邮件正文从该TStream发送到服务器。如果指定备用标题,它们将按原样发送,并且与用于创建电子邮件正文的标题数据不匹配。最重要的是,用于分隔电子邮件正文中的MIME部分的MIME边界将与实际发送到服务器的标头中指定的边界不匹配,这将说明您所看到的症状。每当TIdMessage对其进行编码时,该边界值都是随机生成的,因此在调用TIdMessage.Headers之前在AppendMsg()属性中不可用。

因此,话虽如此,我强烈建议您更改代码,以将AAlternativeHeadersAppendMsg()参数设置为nil(或使用根本没有AppendMsg()参数的AAlternativeHeaders的重载版本),以便AppendMsg()将发送TIdMessage本身在上传之前进行编码时生成的实际标头:

res := IMAPClient.AppendMsg( 'Temp2', msg2, nil, [] );


要么:

res := IMAPClient.AppendMsg( 'Temp2', msg2, [] );

关于delphi - 如何下载消息,将其存储并在其他文件夹中重新创建? ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15359744/

10-09 13:09