使用 Delphi 从 Outlook 收件箱收集电子邮件
Collecting emails from Outlook Inbox with Delphi
我写了一些代码来读取 Outlook 收件箱中的电子邮件并收集附件。
这工作得很好。我正在使用 Outlook 2019/Office 365。
我可以同时使用 Mail.SenderEmailAddress
或 Mail.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
和许多其他项目。所有这些项目都支持不同的属性集,并非所有项目都具有 Sender
、SenderEmailAddress
或 Attachments
属性。如果您只对邮件感兴趣,那么您需要检查邮件的 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;
我写了一些代码来读取 Outlook 收件箱中的电子邮件并收集附件。
这工作得很好。我正在使用 Outlook 2019/Office 365。
我可以同时使用 Mail.SenderEmailAddress
或 Mail.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
和许多其他项目。所有这些项目都支持不同的属性集,并非所有项目都具有 Sender
、SenderEmailAddress
或 Attachments
属性。如果您只对邮件感兴趣,那么您需要检查邮件的 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;