1

我正在使用 Delphi XE3,下面是我的示例应用程序:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    function Send(const FromAddr, ToAddr, Subject: String; const AttachFiles: array
        of string; const MsgBody: String): boolean;
  end;

var
  Form1: TForm1;

implementation

uses Winapi.Mapi;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  Send('', 'lmengyew@gmail.com', 'test', [], '');
end;

function TForm1.Send(const FromAddr, ToAddr, Subject: String; const
    AttachFiles: array of string; const MsgBody: String): boolean;
var Msg: TMapiMessage;
    lpSender, lpRecipient: TMapiRecipDesc;
    Attach: array of TMapiFileDesc;
    SMTP: TFNMapiSendMail;
    MAPIModule: HModule;
    i: integer;
    S: string;
begin
  Result := False;
  FillChar(Msg, SizeOf(Msg), 0);

  Msg.lpszSubject := PAnsiChar(UTF8String(Subject));
  Msg.lpszNoteText := PAnsiChar(UTF8String(MsgBody));

  if FromAddr <> '' then begin
    lpSender.ulRecipClass := MAPI_ORIG;
    lpSender.lpszName     := PAnsiChar(UTF8String(FromAddr));
    lpSender.lpszAddress  := PAnsiChar(UTF8String(FromAddr));
    lpSender.ulReserved   := 0;
    lpSender.ulEIDSize    := 0;
    lpSender.lpEntryID    := Nil;
    Msg.lpOriginator      := @lpSender;
  end;

  if ToAddr <> '' then begin
    lpRecipient.ulRecipClass := MAPI_TO;
    lpRecipient.lpszName     := PAnsiChar(UTF8String(ToAddr));
    lpRecipient.lpszAddress  := PAnsiChar(UTF8String(ToAddr));
    lpRecipient.ulReserved   := 0;
    lpRecipient.ulEIDSize    := 0;
    lpRecipient.lpEntryID    := Nil;
    Msg.nRecipCount          := 1;
    Msg.lpRecips             := @lpRecipient;
  end;

  SetLength(Attach, Length(AttachFiles));
  FillChar(Attach[0], Length(Attach) * SizeOf(TMapiFileDesc), 0);
  i := 0;
  for S in AttachFiles do begin
    Attach[i].nPosition := Cardinal($FFFFFFFF);
    Attach[i].lpszPathName := PAnsiChar(UTF8String(S));
    Inc(i);
  end;
  Msg.nFileCount := Length(AttachFiles);

  if Msg.nFileCount = 0 then
    Msg.lpFiles := nil
  else
    Msg.lpFiles := @Attach[0];

  MAPIModule := LoadLibrary(PChar(MAPIDLL));

  if MAPIModule <> 0 then begin
    try
      @SMTP := GetProcAddress(MAPIModule, 'MAPISendMail');
      if @SMTP <> nil then
        Result := SMTP(0, Application.Handle, Msg, 0, 0) = SUCCESS_SUCCESS;
    finally
      FreeLibrary(MAPIModule);
    end;
  end;
end;

end.

在此处输入图像描述

当我单击 Button1 时,它将提示确认对话框作为打印屏幕。我的问题是如何在不提示确认对话框的情况下立即发送邮件?这有可能实现吗?

4

2 回答 2

5

这很简单。不要使用MAPI. :-)

在没有用户干预的情况下通过发送邮件MAPI是恶意软件/间谍软件所做的,因此 Windows 会阻止它以防止这种情况发生。您无法绕过该安全性,因为它是专门为防止您这样做而添加的。

想象一下,如果可以的话,你正在写一些不好的东西。您可以扫描用户的计算机,获取您想要的任何文件(如财务文件、个人信息等),然后在未经用户许可的情况下通过电子邮件发送到任何地方。或者您可以开始从用户电子邮件帐户发送病毒和垃圾邮件。哎呀!您正在做的正是过去发生的事情,这正是现在询问用户如何通过MAPI.

您可以让用户为您的软件配置其传出帐户,然后使用TIdSMTP(或任何其他 SMTP 组件)通过该帐户发送邮件。这允许用户确认您的应用程序将发送邮件,并提供电子邮件所需的任何凭据(服务器名称、电子邮件帐户)和安全信息(用户名、密码等)。

于 2013-06-29T04:19:13.100 回答
1

对的,这是可能的。在您的代码中,您使用的是 MAPI - 您必须放弃该方法并使用 Delphi 存在的一些 SMTP 组件。我可以推荐你两个:

Indy (IdSMTP) - Delphi 自带,这里的使用示例

Overbyte ICS (SmtpCli) - 站点在这里,例如使用示例,在安装组件后查看目录中的MailSnd演示。Samples\Delphi\MailNewsDemos

于 2013-06-29T04:23:15.387 回答