MailItem.发送错误'项目被移动或删除'检查用户是否已发送邮件时
本文关键字:是否 用户 检查 移动 项目 错误 MailItem 删除 | 更新日期: 2023-09-27 17:49:50
当我执行以下代码时,出现错误the item is moved or deleted
Outlook.Application outlookApp = new Outlook.Application();
Outlook.MailItem mailItem = (Outlook.MailItem)outlookApp.CreateItem(Outlook.OlItemType.olMailItem);
mailItem.Subject = mailSubject;
mailItem.To = "";
mailItem.CC = "";
mailItem.Attachments.Add(totalPath);
mailItem.Body = mailBody;
mailItem.Importance = Outlook.OlImportance.olImportanceNormal;
mailItem.Display(true);
//Mail is send succesfully?
Bool sent = true;
if (!mailItem.Sent)
{
sent = false;
}
当我检查mailItem时出现错误。发送属性。
我的问题是.Sent
如何工作?我正在尝试向最终用户显示电子邮件消息,然后检查他们是否已发送电子邮件。
调用Display方法(传递true)后,邮件项可能不再存在。可以将其移动到发件箱文件夹中,以便通过传输提供程序进行进一步处理。
Sent属性被设置了一次,而不是你想要的。此外,在调用Display方法后立即检查Sent属性值并不是一个好主意。邮件项目可以标记为由传输提供程序处理,尚未发送。相反,您需要在代码中处理ItemSend事件。但是检查主题行并不是一个稳定的解决方案。至少用户可以在显示检查器窗口时更改预设值。
在调用MailItem类的display方法之前,您可以向MailItem添加一个用户属性(您自己的ID)。然后在ItemSend事件处理程序中,您可以检出该值并在需要时删除它。因此,您可以确定项目将被发送(而不是实际发送)。
如果您需要确保邮件项目被发送,我建议处理Items类的ItemAdd事件(参见Folder类的相应属性)。例如,当发送Outlook项目时,发送的副本将放置到Outlook中的"已发送项目"文件夹中。您可以处理该文件夹的ItemAdd事件,以确保项目确实已发送。考虑在显示Outlook项目之前添加一个用户属性,并在ItemAdd事件处理程序中检查它,以唯一地标识项目。
请注意,您可以指定一个自定义文件夹来放置已发送的邮件。MailItem类的SaveSentMessageFolder属性允许设置一个Folder对象,该对象表示发送后电子邮件副本将保存在其中的文件夹。因此,您可以将发送的邮件移动到您自己的自定义文件夹
我是这样解决这个问题的:
type
TOutlookFolderItemsEvent = procedure(ASender: TObject; const Item: IDispatch) of object;
TOutlookFolderItems = class(TOleServer)
private
FIntf: _Items;
FOnItemAdd: TOutlookFolderItemsEvent;
protected
procedure InitServerData; override;
procedure InvokeEvent(DispID: TDispID; var Params: TVariantArray); override;
public
procedure Disconnect; override;
procedure Connect; override;
procedure ConnectTo(svrIntf: _Items);
property OnItemAdd: TOutlookFolderItemsEvent read FOnItemAdd write FOnItemAdd;
end;
TMyForm = class(TForm)
OutlookApplication1: TOutlookApplication;
private
FMyEntryID: String;
FItems: TOutlookFolderItems;
procedure ItemsItemAdd(ASender: TObject; const Item: IDispatch);
procedure MySendEmail;
end;
procedure TMyForm.MySendEmail;
var
Mi: MailItem;
EntryID: TGUID;
begin
OutlookApplication1.Disconnect;
OutlookApplication1.Connect;
OutlookApplication1.Application.ActiveExplorer.WindowState := olMaximized;
CreateGuid(EntryID);
FMyEntryID:= GUIDToString(EntryID);
Mi.UserProperties.Add('MyEntryID', olText, True, olText).Value := FMyEntryID;
Mi.Save;
Mi.Display(0);
// Add the following code to OutlookApplication's OnItemSend
// to get a more accurate SaveSentMessageFolder
// (as it may change when selecting from different From accounts)
FItems := TOutlookFolderItems.Create(Self);
FItems.ConnectTo(Mi.SaveSentMessageFolder.Items);
FItems.OnItemAdd := ItemsItemAdd;
end;
procedure TMyForm.ItemsItemAdd(ASender: TObject; const Item: IDispatch);
var
S: String;
I: MailItem;
P: UserProperty;
begin
I := Item as MailItem;
P := I.UserProperties.Find('MyEntryID', True);
if (P = nil) or (P.Value <> FMyEntryID) then Exit; // Not the email we're waiting for
// MailItem is known to be sent and in SentFolders here.
// Add here any relevant code.
end;
{ TOutlookFolderItems }
procedure TOutlookFolderItems.Connect;
begin
end;
procedure TOutlookFolderItems.ConnectTo(svrIntf: _Items);
begin
Disconnect;
FIntf := svrIntf;
ConnectEvents(FIntf);
end;
procedure TOutlookFolderItems.Disconnect;
begin
if Fintf <> nil then
begin
DisconnectEvents(FIntf);
FIntf := nil;
end;
end;
procedure TOutlookFolderItems.InitServerData;
const
CServerData: TServerData = (
ClassID: '{00063052-0000-0000-C000-000000000046}';
IntfIID: '{00063041-0000-0000-C000-000000000046}';
EventIID: '{00063077-0000-0000-C000-000000000046}';
LicenseKey: nil;
Version: 500);
begin
ServerData := @CServerData;
end;
procedure TOutlookFolderItems.InvokeEvent(DispID: TDispID; var Params: TVariantArray);
begin
case DispID of
-1: Exit; // DISPID_UNKNOWN
61441: if Assigned(FOnItemAdd) then
FOnItemAdd(Self, Params[0] {const IDispatch});
end;
end;