使用 Delphi 从 Outlook 收件箱收集电子邮件

Collecting emails from Outlook Inbox with Delphi

我写了一些代码来读取 Outlook 收件箱中的电子邮件并收集附件。

这工作得很好。我正在使用 Outlook 2019/Office 365。

我可以同时使用 Mail.SenderEmailAddressMail.Sender.Address 来获取发件人的电子邮件地址。

将我的应用程序部署到另一台装有 Outlook 2016 的计算机时,出现此错误:

EOleError: Method 'Sender' not supported by automation object

Mail.SenderEmailAddress

也一样

Outlook 2016或2019码流相同。参见 Outlook versions, build numbers and other trivia

您能否帮助理解为什么我在客户的计算机上出现此类错误以及如何解决该问题?

您是否知道 free/commercial 可以顺利完成此操作的库或组件?

这与我关于 Sending Outlook Email with Delphi 的另一个问题有某种联系。

try
  Outlook:=GetActiveOleObject('Outlook.Application') ;
except
  Outlook:=CreateOleObject('Outlook.Application') ;
end;

try
  oNameSpace := Outlook.GetNamespace('MAPI');
  oNameSpace.Logon;

  Inbox:= oNameSpace.GetDefaultFolder(6);
  iNbMail:= Inbox.Items.Count;

  for i:= iNbMail downto 1 do
  begin
    if VarIsNull(Inbox.Items[i]) or VarIsEmpty(Inbox.Items[i])  then
      Continue;

    Mail:= Inbox.Items[i];
    EmailAddress:= Mail.Sender.Address;
    // EmailAddress:= Mail.SenderEmailAddress;
          
    UnReadFlag:= Mail.UnRead;
    iNbAttach := Mail.Attachments.Count;

    for j := iNbAttach downto 1 do
    begin
      Attachment:= Mail.Attachments[j];
      if ExtractFileExt(Attachment.FileName) = '.pdf' then
      begin
        SaveName:= TPath.Combine(InboxFolder, Attachment.FileName);
        Attachment.SaveAsFile(SaveName);
      end;
    end;
    Mail.UnRead:= False;
  end;
finally
  Outlook:= Unassigned;
  oNameSpace:= Unassigned;
  Inbox:= Unassigned;
  Mail:= Unassigned;
end;

Outlook 中的收件箱文件夹不限于仅包含邮件消息。遍历其项目时,您会遇到各种项目 类,如 MailItem, PostItem, MeetingItem, TaskRequestItem 和许多其他项目。所有这些项目都支持不同的属性集,并非所有项目都具有 SenderSenderEmailAddressAttachments 属性。如果您只对邮件感兴趣,那么您需要检查邮件的 Class 属性:

const
  olMail = [=10=]00002B;

{ ... }

for i := iNbMail downto 1 do
begin
  Mail := Inbox.Items[i];
  if Mail.Class <> olMail then
    Continue;

  { here we can assume we're working with MailItem instance }
  
end;

我怀疑 Outlook 曾经 returns 为 null 或空项目,因此您在代码中所做的检查毫无意义。如果您对其他项目感兴趣 类,请查看 OlObjectClass 枚举。

我不确定您为什么更喜欢使用 late-binding,因为 Delphi 已经带有导入的类型库 Outlook2010.pas 以强类型方式自动化 Outlook。该库位于安装文件夹的 OCX\Servers 子文件夹中。如果您需要支持 2010 之前的 Outlook 版本,您可以使用 unit OutlookXP 甚至 Outlook2000 代替。使用类型库迭代邮件项的代码可能如下所示:

uses
  System.SysUtils, System.Variants, Winapi.ActiveX, Outlook2010;

function GetOutlookApplication: OutlookApplication;
var
  ActiveObject: IUnknown;
begin
  if Succeeded(GetActiveObject(OutlookApplication, nil, ActiveObject)) then
    Result := ActiveObject as OutlookApplication
  else
    Result := CoOutlookApplication.Create;
end;

procedure ProcessInboxItems;
var
  Outlook: OutlookApplication;
  Inbox: Folder;
  Index: Integer;
  LItems: Items;
  LMailItem: MailItem;
begin
  Outlook := GetOutlookApplication;
  Outlook.Session.Logon(EmptyParam, EmptyParam, EmptyParam, EmptyParam);

  Inbox := Outlook.Session.GetDefaultFolder(olFolderInbox);
  LItems := Inbox.Items;
  for Index := LItems.Count downto 1 do
  begin
    if Supports(LItems.Item(Index), MailItem, LMailItem) then
    begin
      { do whatever you wish with LMailItem }
    end;
  end;
end;