[英]AV when sending email via Outlook and Redemption
这是我的代码:
const
olMailItem = 0;
var
olApp, OlNameSpace, OlItem, rdSafeItem, rdUtils: variant;
begin
olApp:= CreateOleObject ('Outlook.Application');
olNameSpace:= olApp.GetNamespace ('MAPI');
olNameSpace.Logon;
olItem:= olApp.CreateItem (olMailItem);
rdSafeItem:= CreateOleObject ('Redemption.SafeMailItem');
rdSafeItem.Item:= olItem;
rdSafeItem.Subject:= 'Testing';
rdSafeItem.attachments.Add ('c:\windows\win.ini');
rdSafeItem.Recipients.Add ('test@testing.com');
rdSafeItem.Send;
rdUtils:= CreateOleObject ('Redemption.MAPIUtils');
rdUtils.DeliverNow;
olNameSpace.Logoff;
varclear (rdUtils);
varclear (rdSafeItem);
varclear (olItem);
varclear (olNameSpace);
varclear (olApp);
end;
发送电子邮件后,我在地址A70D6D13收到访问冲突消息(此地址似乎是恒定的)。 如果我使用F8逐步执行整个过程,则在“ end”语句之后,CPU窗口将显示在地址A70D6D13上,所有内存均显示为????。
我正在使用Delphi 7,Outlook 2003,Redemption 4.8.0.1184此代码缺少什么?
编辑:我发现了其他一些代码片段,可以通过Outlook / Redemption发送邮件。 这是一个使用OutlookApplication服务器的片段。
begin
outlookapplication1.Connect;
NmSpace:= outlookapplication1.GetNamespace('MAPI');
NmSpace.Logon('', '', False, False);
oItem:= outlookapplication1.CreateItem(olMailItem);
sItem:= CreateOleObject('Redemption.SafeMailItem');
oItem.Subject:= 'my subject';
oItem.save;
sItem.Item:= oItem;
sItem.Recipients.Add('test@test.com');
sItem.Attachments.Add('C:\windows\win.ini');
sItem.save;
SItem.send;
outlookapplication1.Disconnect;
end;
这也给出了相同的错误。 AV的地址有什么神奇之处? 它必须是解决方案的线索。
TIA,
不行
尝试删除varclear
语句。
您所描述的症状表明您正在设法从例程中的内存中逐出COM对象,然后,当方法变量超出范围时,Delphi会尝试再次释放它们。
更新资料
正如No'am正确评论的那样,Outlook的应用程序COM接口不支持“连接和断开连接”。 让我感到惊讶的是,但是我通常使用Delphi包装器,实际上TOutlookApplication的Connect实现只是返回CreateOleObject或GetActiveObject的结果。 TOutlookApplication的Disconnect方法的实现实际上除了发布接口之外还做其他事情。 如果AutoQuit为true,它将在应用程序的COM接口上调用Quit。
但是,由于它似乎是可选的,所以我认为不致电olApp.Quit不会引起No'am遇到的问题。 把我的答案留作“教育性”材料,这样其他人就不必检查了。
不确定这实际上是造成您问题的原因,但是我在您的代码中缺少的是与Outlook应用程序的连接和断开连接。 尽管显然不需要使用Outlook COM服务器(如所发送的邮件所示),但它们是我所知道的“常规” COM使用模式的一部分。 我完全可以想象,当由var超出范围(在end语句之后)触发时,不连接/断开连接很可能会导致完成代码掉落。
我通常使用的模式是:
Create / CreateOleObject
try
Connect
try
...
finally
Disconnect
end
finally
Free / Release
end
如果使用“直接” COM,则在使用Delphi提供的TxxxApplication包装程序,CreateOleObject和释放接口(将其设置为nil / unssigned)之一时,可以使用Create和Free。
在您的示例中,这意味着添加
olApp.Connect;
在CreateOleObject和olNameSpace分配行之间添加
olApp.Disconnect;
在olNameSpace.LogOff之后;
添加几个try / finally块也不会浪费。
我正在使用Redemption 5.0.0.2174,Delphi 7,Outlook 2003
我修改了您的代码,如下所示,并且能够发送电子邮件而没有任何错误
const
olMailItem = 0;
var
olApp, OlNameSpace, OlItem, rdSafeItem, rdUtils: variant;
begin
olApp:= CreateOleObject ('Outlook.Application');
olNameSpace:= olApp.GetNamespace ('MAPI');
olNameSpace.Logon;
olItem:= olApp.CreateItem (olMailItem);
rdSafeItem:= CreateOleObject ('Redemption.SafeMailItem');
rdSafeItem.Item:= olItem;
rdSafeItem.Subject:= 'Testing';
rdSafeItem.attachments.Add ('c:\windows\win.ini');
rdSafeItem.Recipients.Add ('test@testing.com');
rdSafeItem.Recipients.ResolveAll; // added
rdSafeItem.Send;
// rdUtils:= CreateOleObject ('Redemption.MAPIUtils');
// rdUtils.DeliverNow;
olNameSpace.Logoff;
// varclear (rdUtils);
// varclear (rdSafeItem);
// varclear (olItem);
// varclear (olNameSpace);
// varclear (olApp);
end;
首先,没有理由使用DeliverNow-MS在OUtlook 2002中将其破坏: http : //www.dimastr.com/redemption/faq.htm#1
其次,如果您删除了Logoff语句,是否有效? 如果Outlook已经在运行,则需要小心-如果用户正在运行,则不想杀死它。
您会在end语句中看到错误,这意味着在清理一些临时变量时可能会抛出该错误。 可能是清理rdSafeItem.Recipients
的临时变量或与CreateOleObject
使用的某些中间变量。 您可以做的是将代码切成小段,在那些较小的过程中(至少是使用中间变量的过程)而不是在main方法中进行所有与com相关的工作。 这可以使查找问题更容易,甚至可以解决问题。
像这样:
function CreateOutlookApp: OleVariant;
begin
Result := CreateOleObject ('Outlook.Application');
end;
function GetAndLogonNamespace(const olApp: OleVariant): OleVariant;
begin
Result := olApp.GetNamespace ('MAPI');
Result.Logon;
end;
function GetSafeMailItem(const olApp: OleVariant): OleVariant;
const
olMailItem = 0;
var
olItem: OleVariant;
begin
olItem:= olApp.CreateItem (olMailItem);
Result := CreateOleObject ('Redemption.SafeMailItem');
Result.Item:= olItem;
Result.Subject:= 'Testing';
Result.attachments.Add ('c:\windows\win.ini');
Result.Recipients.Add ('test@testing.com');
end;
procedure SendTestMail;
var
olApp, olNameSpace, rdSafeItem: OleVariant
begin
OutputDebugString('CreateOutlookApp');
olApp := CreateOutlookApp;
OutputDebugString('GetAndLogonNamespace');
olNameSpace := GetAndLogonNamespace(olApp);
OutputDebugString('GetSafeMailItem');
rdSafeItem := GetSafeMailItem(olApp);
OutputDebugString('rdSafeItem.Send');
rdSafeItem.Send;
OutputDebugString('DeliverNow');
DeliverNow; //implement this yourself
OutputDebugString('LogoffNamespace');
LogoffNamespace(olNamespace); //implement this yourself
OutputDebugString('Cleaning up');
end;
编辑:添加了OutputDebugStrings,因为该错误似乎仅在没有调试器的情况下运行应用程序时发生。 当您发现有问题的函数时,可以在其中添加更多OutputDebugStrings。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.