Translate

2015/03/10

Delphi XE7使用Indy 10.6.1連結Gmail SMTP

我在KTOP中回答「xe6 使用gmail的問題」這個主題,因為程式碼編排有問題,故在這裡另外轉貼。

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, IdExplicitTLSClientServerBase, IdSMTP, IdSSLOpenSSL,
  IdMessage, IdAttachmentFile, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    function SendEmail(sendTo: string;
                    subject: string;
                    body: string;
                    attachFiles: TStringList;
                    smtpHost: string;
                    smtpPort: Integer;
                    smtpUser: string;
                    smtpPass: string;
                    tls: TIdUseTLS): boolean;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
begin
  SendEmail( 'mybuddy@example.com', // 目的地E-Mail
                    'This is the subject',
                    'This is the body of the email....',
                    nil,
                    'smtp.gmail.com',
                    587,
                    'myusername@gmail.com', // 登入帳號
                    'mypassword'{ 登入密碼 }, utUseExplicitTLS);
end;

function TForm1.SendEmail(sendTo, subject, body: string;
  attachFiles: TStringList; smtpHost: string; smtpPort: Integer; smtpUser,
  smtpPass: string; tls: TIdUseTLS): boolean;
var
    smtp: TIdSmtp;
    ssl: TIdSSLIOHandlerSocketOpenSSL;
    msg: TIdMessage;
    i: Integer;
begin
    smtp:=TIdSmtp.Create(nil);
    ssl:=TIdSSLIOHandlerSocketOpenSSL.Create(nil);
    msg:=TIdMessage.Create(nil);
    try

        try
            smtp.Host:=smtpHost;
            smtp.Port:=smtpPort;
            smtp.Username:=smtpUser;
            smtp.Password:=smtpPass;

            //smtp.OnConnected :=IdSMTP1Connected;
            //smtp.OnDisconnected :=IdSMTP1Disconnected;
            //smtp.OnFailedRecipient :=IdSMTP1FailedRecipient;
            //smtp.OnStatus :=IdSMTP1Status;
            //smtp.OnTLSNotAvailable :=IdSMTP1TLSNotAvailable;
            //smtp.OnWork :=IdSMTP1Work;

            if not (tls=utNoTLSSupport) then begin
                ssl.Destination:=smtpHost + ':' + IntToStr(smtpPort);
                ssl.Host:=smtpHost;
                ssl.Port:=smtpPort;
                ssl.SSLOptions.Method:=sslvTLSv1;

                //ssl.OnStatusInfo:=IdSSLIOHandlerSocketOpenSSL1StatusInfo;
                //ssl.OnGetPassword:=IdSSLIOHandlerSocketOpenSSL1GetPassword;
                //ssl.OnStatus:=IdSSLIOHandlerSocketOpenSSL1Status;

                smtp.IOHandler:=ssl;
                smtp.UseTLS:=tls;
            end;

            msg.Recipients.EMailAddresses := sendTo;
            msg.Subject:=subject;
            msg.Body.Text:=body;

            if(Assigned(attachFiles)) then begin
                for i := 0 to attachFiles.Count - 1 do begin
                   if FileExists(attachFiles[i]) then
                        TIdAttachmentFile.Create(msg.MessageParts, attachFiles[i]);
                end;
            end;

            smtp.Connect;
            smtp.Send(msg);
            smtp.Disconnect;

            result:=true;
        finally
            msg.Free;
            ssl.Free;
            smtp.Free;
        end;
    except
       result:=false;
    end;
end;

end.

結論:
上述程式可以正確發出和收到信件,在XE7下驗證無誤。


參考資料來源:Sending email with attachments using Delphi, Indy 10.5.5 and GMail




6 則留言:

  1. 請教..
    我的環境為 win7 + xe7
    使用上述程式, 執行時出現錯誤訊息如下:
    ...EIdSMTPReplyError wiht message....
    Please log in via your web browser and then try again.
    Learn more at
    https://support.google.com/mail/bin/answer.py?answer=78754

    sorry .. 無法貼圖
    有試著到 https://support.google.com/mail/bin/answer.py?answer=78754 依其相關操作建議
    但並無法解決目前問題
    不知前輩有何建議, 謝謝

    回覆刪除
  2. 我在測試時
    「有發生不能寄出」的成因是「Could not load SSL library」

    請試一下這篇:Indy 操作 SMTP 發生 "Could not load SSL library"?
    http://grandruru.blogspot.tw/2014/12/indy-smtp-could-not-load-ssl-library.html

    升級 SSL 後再試試看。
    以上

    回覆刪除
  3. smtp.connect; 這行還是正常的
    smtp.send(msg); 這行最後的結果如上
    下面列出執行時的相關訊息如下:
    IdSSLIOHandlerSocketOpenSSL1Status AStatusText:=Resolving hostname smtp.gmail.com.
    IdSSLIOHandlerSocketOpenSSL1Status AStatusText:=Connecting to 74.125.203.108.
    IdSMTP1Status AStatusText:=Connected.
    IdSMTP1Connected
    Start Send Message ----------------------------
    IdSSLIOHandlerSocketOpenSSL1StatusInfo AMsg:=SSL status: "before/connect initialization"
    IdSSLIOHandlerSocketOpenSSL1StatusInfo AMsg:=SSL status: "before/connect initialization"
    IdSSLIOHandlerSocketOpenSSL1StatusInfo AMsg:=SSL status: "SSLv3 write client hello A"
    IdSSLIOHandlerSocketOpenSSL1StatusInfo AMsg:=SSL status: "SSLv3 read server hello A"
    IdSSLIOHandlerSocketOpenSSL1StatusInfo AMsg:=SSL status: "SSLv3 read server certificate A"
    IdSSLIOHandlerSocketOpenSSL1StatusInfo AMsg:=SSL status: "SSLv3 read server key exchange A"
    IdSSLIOHandlerSocketOpenSSL1StatusInfo AMsg:=SSL status: "SSLv3 read server done A"
    IdSSLIOHandlerSocketOpenSSL1StatusInfo AMsg:=SSL status: "SSLv3 write client key exchange A"
    IdSSLIOHandlerSocketOpenSSL1StatusInfo AMsg:=SSL status: "SSLv3 write change cipher spec A"
    IdSSLIOHandlerSocketOpenSSL1StatusInfo AMsg:=SSL status: "SSLv3 write finished A"
    IdSSLIOHandlerSocketOpenSSL1StatusInfo AMsg:=SSL status: "SSLv3 flush data"
    IdSSLIOHandlerSocketOpenSSL1StatusInfo AMsg:=SSL status: "SSLv3 read server session ticket A"
    IdSSLIOHandlerSocketOpenSSL1StatusInfo AMsg:=SSL status: "SSLv3 read finished A"
    IdSSLIOHandlerSocketOpenSSL1StatusInfo AMsg:=SSL status: "SSL negotiation finished successfully"
    IdSSLIOHandlerSocketOpenSSL1StatusInfo AMsg:=SSL status: "SSL negotiation finished successfully"
    IdSSLIOHandlerSocketOpenSSL1StatusInfo AMsg:=Cipher: name = ECDHE-RSA-RC4-SHA; description = ECDHE-RSA-RC4-SHA SSLv3 Kx=ECDH Au=RSA Enc=RC4(128) Mac=SHA1
    ; bits = 128; version = TLSv1/SSLv3;

    回覆刪除
  4. 看不出錯誤在哪邊
    你的帳號資料有輸入正確嗎?

    回覆刪除
  5. 謝謝您的回覆, 下載並安裝了..但顯然不是這個問題
    再研究研究看看好了, 3Q

    回覆刪除

一山不容二虎之 EDBClient - Key violation 記事

關聯式資料庫裡有個很基本的特性:PRIMARY KEY 條件約束。 一個資料表只能有一個 PRIMARY KEY 條件約束,並且任何加入 PRIMARY KEY 條件約束的資料行都不可接受 Null 值。因為 PRIMARY KEY 條件約束保證唯一的資料,它們通常...