使用 Redemption.SafeMailItem 时出错 - OLE 错误 8004010E(MAPI_E 资源不足)
Error when using Redemption.SafeMailItem - OLE error 8004010E(MAPI_E NOT ENOUGH RESOURCES)
在我工作的公司中,我们使用兑换来发送来自旧 Delphi 客户的电子邮件。我们用了很多年了,升级到Office365-outlook 1906后就开始出现这个错误。
我们所有的软件版本都会出现这个问题,从 5 年前的版本到我们几天前编译的版本。
该错误是随机发生的,但是一旦发生,它将一直持续到整个机器重新启动。所以通常重启后几个小时可以再次发送邮件,但最终还是会再次出现错误。
创建uSafeMailItem时出现错误
Office365以前版本(Outlook 1906之前)不会出现该错误
我们记录的错误是
OLE 错误 8004010E,ProgID:"UnikOR.uSafeMailItem" 又名 MAPI_E 资源不足(UnikOR.uSafeMailItem 等于 Redemption.SafeMailItem)
经过这么多天的调查,我们似乎已经得出结论,要么是救赎,要么更可能是我们使用救赎的方式什么的?
我们测试了 outlook 和 windows
的组合
Windows 和 outlook 版本
Windows 10 企业 1803
- Outlook 1904(工作)
- Outlook 1906(失败)
Windows 10 企业 1809
- Outlook 1904(工作)
- Outlook 1906(失败)
Windows 10 企业 1903
- Outlook 1904(工作)
- Outlook 1906(失败)
我们已经通过名为 VMMap 的工具检查了 outlook 中的可用内存
我还可以看到 outlook 有一些死进程挂起。但我不确定这是否与救赎有关
我还启用了 Outlook 日志记录并收到了一个日志文件 (OUTLOOK-20190806T1236220570-v2.etl)。但是,我似乎没有发现任何可能与 Redemption 及其调用 outlook 的方式相关的内容。
我们还查看了 Procmon 和 Fuslogvw,但没有任何运气。
下面的这段代码创建了对象
function TSendEmail.SendOutlookEmailUsingRedemption(Outlook: Olevariant; OutlookEmailFileName: string; var Email: TStream; var Subject: string; var HasAttachments: Boolean; UseOutlookSignatur: Boolean): TMailSendResult;
var
Utils: IMAPIUtils;
RDOSession: IRDOSession;
SentMailFolder: IRDOFolder;
RDOMailItem: IRDOMail;
MailInSentFolder: IRDOMail;
Body: string;
I: Integer;
Insp: Variant;
TempInsp: Variant;
MailItem: Variant;
OutlookEntryID: string;
S: string;
SafeItem: ISafeMailItem;
SL: TStringList;
TempBody: string;
OutlookSignatur: string;
begin
Result := msrOK;
FMailData.MailAttachments.PrepareNotes;
try
MailItem := Outlook.CreateItem(olMailItem);
SafeItem := CreateOLEObject('UnikOR.uSafeMailItem') as ISafeMailItem; // do not localize
Variant(SafeItem).Item := MailItem;
function TSendEmail.SendOutlookEmail(var Email: TStream; var Subject: string; var HasAttachments: Boolean; UseOutlookSignatur: Boolean): TMailSendResult;
var
Outlook: Olevariant;
OutlookEmailFileName: string;
OutlookEntryID: string;
begin
try
OutlookEmailFileName := FTempPath + 'OutlookEmail.msg'; // do not localize
try
Outlook := GetActiveOleObject('Outlook.Application'); // do not localize
except
Outlook := CreateOleObject('Outlook.Application'); // do not localize
end;
if FMailData.UseOutlookRedemption then
SendOutlookEmailUsingRedemption(Outlook, OutlookEmailFileName, Email, Subject, HasAttachments, UseOutlookSignatur)
else
SendOutlookEmailUsingMapi(Outlook, OutlookEmailFileName, Email, Subject, HasAttachments, UseOutlookSignatur);
我们希望它将电子邮件发送到目标电子邮件地址,但是我们的系统使用回退方法来打印文档并向我们发送以下错误“错误:OLE 错误 8004010E,ProgID:"UnikOR.uSafeMailItem""
每次创建可创建的 Redemption 对象时,它都会通过调用 MAPIInitialize
来初始化 MAPI 系统。当它被销毁时,它调用MAPIUnitialize
。 Outlook 不喜欢让 MAPI 系统不断循环 - 经验法则是初始化 MAPI 系统一次并保持初始化状态。您可以创建一个 Redemption 对象(例如另一个 SafeMailItem
对象或 RDOSession
)一次,并在您的应用程序的整个生命周期内保持其活动状态。
在我工作的公司中,我们使用兑换来发送来自旧 Delphi 客户的电子邮件。我们用了很多年了,升级到Office365-outlook 1906后就开始出现这个错误。
我们所有的软件版本都会出现这个问题,从 5 年前的版本到我们几天前编译的版本。
该错误是随机发生的,但是一旦发生,它将一直持续到整个机器重新启动。所以通常重启后几个小时可以再次发送邮件,但最终还是会再次出现错误。
创建uSafeMailItem时出现错误 Office365以前版本(Outlook 1906之前)不会出现该错误
我们记录的错误是 OLE 错误 8004010E,ProgID:"UnikOR.uSafeMailItem" 又名 MAPI_E 资源不足(UnikOR.uSafeMailItem 等于 Redemption.SafeMailItem)
经过这么多天的调查,我们似乎已经得出结论,要么是救赎,要么更可能是我们使用救赎的方式什么的?
我们测试了 outlook 和 windows
的组合Windows 和 outlook 版本
Windows 10 企业 1803
- Outlook 1904(工作)
- Outlook 1906(失败)
Windows 10 企业 1809
- Outlook 1904(工作)
- Outlook 1906(失败)
Windows 10 企业 1903
- Outlook 1904(工作)
- Outlook 1906(失败)
我们已经通过名为 VMMap 的工具检查了 outlook 中的可用内存
我还可以看到 outlook 有一些死进程挂起。但我不确定这是否与救赎有关
我还启用了 Outlook 日志记录并收到了一个日志文件 (OUTLOOK-20190806T1236220570-v2.etl)。但是,我似乎没有发现任何可能与 Redemption 及其调用 outlook 的方式相关的内容。
我们还查看了 Procmon 和 Fuslogvw,但没有任何运气。
下面的这段代码创建了对象
function TSendEmail.SendOutlookEmailUsingRedemption(Outlook: Olevariant; OutlookEmailFileName: string; var Email: TStream; var Subject: string; var HasAttachments: Boolean; UseOutlookSignatur: Boolean): TMailSendResult;
var
Utils: IMAPIUtils;
RDOSession: IRDOSession;
SentMailFolder: IRDOFolder;
RDOMailItem: IRDOMail;
MailInSentFolder: IRDOMail;
Body: string;
I: Integer;
Insp: Variant;
TempInsp: Variant;
MailItem: Variant;
OutlookEntryID: string;
S: string;
SafeItem: ISafeMailItem;
SL: TStringList;
TempBody: string;
OutlookSignatur: string;
begin
Result := msrOK;
FMailData.MailAttachments.PrepareNotes;
try
MailItem := Outlook.CreateItem(olMailItem);
SafeItem := CreateOLEObject('UnikOR.uSafeMailItem') as ISafeMailItem; // do not localize
Variant(SafeItem).Item := MailItem;
function TSendEmail.SendOutlookEmail(var Email: TStream; var Subject: string; var HasAttachments: Boolean; UseOutlookSignatur: Boolean): TMailSendResult;
var
Outlook: Olevariant;
OutlookEmailFileName: string;
OutlookEntryID: string;
begin
try
OutlookEmailFileName := FTempPath + 'OutlookEmail.msg'; // do not localize
try
Outlook := GetActiveOleObject('Outlook.Application'); // do not localize
except
Outlook := CreateOleObject('Outlook.Application'); // do not localize
end;
if FMailData.UseOutlookRedemption then
SendOutlookEmailUsingRedemption(Outlook, OutlookEmailFileName, Email, Subject, HasAttachments, UseOutlookSignatur)
else
SendOutlookEmailUsingMapi(Outlook, OutlookEmailFileName, Email, Subject, HasAttachments, UseOutlookSignatur);
我们希望它将电子邮件发送到目标电子邮件地址,但是我们的系统使用回退方法来打印文档并向我们发送以下错误“错误:OLE 错误 8004010E,ProgID:"UnikOR.uSafeMailItem""
每次创建可创建的 Redemption 对象时,它都会通过调用 MAPIInitialize
来初始化 MAPI 系统。当它被销毁时,它调用MAPIUnitialize
。 Outlook 不喜欢让 MAPI 系统不断循环 - 经验法则是初始化 MAPI 系统一次并保持初始化状态。您可以创建一个 Redemption 对象(例如另一个 SafeMailItem
对象或 RDOSession
)一次,并在您的应用程序的整个生命周期内保持其活动状态。