C# 在Outlook中获取已发送的邮件加载项

C# 在Outlook中获取已发送的邮件加载项,c#,email,outlook,outlook-addin,C#,Email,Outlook,Outlook Addin,我在尝试从Outlook插件获取发送的邮件时遇到了一些问题 在onItemSend事件中,我打开一个对话框,其中显示一些字段,其中包含收件人、主题等消息信息,以及一个将这些信息保存到数据库中的按钮。另一个要求是保存已发送消息的副本,这就是我被卡住的地方 我可以使用SaveAs方法保存消息,但问题是当我打开消息时,它显示: 此消息尚未发送。此消息将通过 Microsoft Exchange 导致用户出现一些问题,使他们认为邮件未发送 在我的搜索过程中,我发现另一个人也有同样的问题,解决方法是在Po

我在尝试从Outlook插件获取发送的邮件时遇到了一些问题

在onItemSend事件中,我打开一个对话框,其中显示一些字段,其中包含收件人、主题等消息信息,以及一个将这些信息保存到数据库中的按钮。另一个要求是保存已发送消息的副本,这就是我被卡住的地方

我可以使用SaveAs方法保存消息,但问题是当我打开消息时,它显示:

此消息尚未发送。此消息将通过 Microsoft Exchange

导致用户出现一些问题,使他们认为邮件未发送

在我的搜索过程中,我发现另一个人也有同样的问题,解决方法是在PostItem创建为sent状态后,将邮件用作PostItem而不是MailItem。此外,我们应该将MessageClass属性设置为IPM.Note并删除PR_图标索引

下面是我用来执行上述步骤的代码。我找到了这段代码并做了一点修改:

PostItem postItem = this._email.Application.CreateItem(OlItemType.olPostItem);
postItem.MessageClass = "IPM.Note";
PropertyAccessor pa = postItem.PropertyAccessor;
pa.SetProperty("http://schemas.microsoft.com/mapi/proptag/0x10800003", -1);
postItem.Save();

NameSpace session = postItem.Session;
string postItemEntryID = postItem.EntryID;
Marshal.ReleaseComObject(postItem);
Marshal.ReleaseComObject(pa);

MailItem newMessage = session.GetItemFromID(postItemEntryID) as MailItem;
newMessage.BCC = this._email.BCC;
newMessage.Body = this._email.Body;
newMessage.BodyFormat = this._email.BodyFormat;
newMessage.CC = this._email.CC;
newMessage.HTMLBody = this._email.HTMLBody;

//Hard coded path just for illustration
newMessage.SaveAs("C:\\Temp\\MSG\test.msg", OlSaveAsType.olMSG); 
上面的代码创建postitem对象,设置一些属性并正确保存到路径,但它存在以下问题:

  • 执行positem.save后,要创建positem邮件,它会在收件箱文件夹中创建一条已读邮件

  • 保存邮件后,我比较了文件和重要的大小,原始邮件大小为580kb,postitem保存的邮件大小为52kb。似乎它没有复制这条信息

  • 它丢失了嵌入在消息中的一些图像,例如显示红色X的签名图像

  • 我如何获取/创建一封邮件,其中包含确切的邮件内容、收件人、附件、属性等(克隆类型)以及已发送状态,而无需在收件箱文件夹中创建另一封邮件


    谢谢你

    我不想用“positem”这个词再进一步了,不知怎么的,它看起来对我来说并不完美

    问题是您正在复制发送的项目。因此副本上说它还没有被发送。 如果您不需要保存在“已发送邮件”文件夹中的“普通”副本,您只需更改保存邮件的文件夹即可

    Set mailitem.SaveSentMessageFolder = someother Folder '(which is defined as Outlook.folder)
    
    如果这是不可能的,那么我将检查(在这个OutlookSession中)“sent items”文件夹,并对其中的每个新项目执行复制操作。如果你不知道如何让我知道,那么我会复制一些代码带你上路


    另一个问题是因为我很好奇:为什么你打开表单并等待别人点击ok按钮,而不是直接将数据保存到数据库中?

    我不会对Outlook试图发送的邮件这样做。你可以

  • 处理“已发送邮件”文件夹上的Items.ItemAdd事件。此时,邮件已发送,所有与发件人相关的属性都已设置

  • 您可以通过删除unsent标志来“修复”已创建的MSG文件。您可以使用-call.GetMessageFromMsgFile/RDOMail.Sent=true/RDOMail.Save来完成此操作。请记住,可能尚未设置发件人信息


  • 嗨,麦克斯,谢谢你的建议。考虑到你的好奇心,我会在表单上显示另一个字段,用户将在其中添加注释,从一些下拉列表中选择一些数据,然后当用户点击ok按钮时,它将保存所有用户选择和消息本身。我只是没有把所有发生的事情都写在那张表格上:)谢谢,对“已发送邮件”文件夹的“检查(在本次了望会议中)”与迪米特里的建议是一样的,当然他有更好的解释。此外,只有在用户没有更改“已发送邮件”文件夹,或者甚至没有使用vba.Hi Dmitry逐个更改文件夹的情况下,此操作才会起作用!只是关于你的第一个建议的一个问题…我在某处读到,用户可以更改“已发送邮件”文件夹。如果用户更改此文件夹,我是否能够收到已发送的邮件?是否必须在itemAdd事件之前设置已发送文件夹?如果我更改发送文件夹的位置,它会覆盖用户的选项吗?感谢您的建议您可以跟踪Application.ItemSend事件并检查MailItem.SaveSentMessageFolder属性是否指向Namespace.GetDefaultFolder返回的预期已发送邮件文件夹(使用Namespace..CompareEntryId)。然后,您也可以跟踪该文件夹上的ItemAdd事件,或者将自定义文件夹的条目id保存在自定义属性(MailItem.UserProperties)中,并将SaveSentMessageFolder属性重置为默认的Sent Items文件夹。处理该文件夹上的ItemAdd时,您可以使用custom属性打开自定义文件夹并将邮件移动到该文件夹。嗨,Dmitry,您能否解释如何“同时跟踪该文件夹上的ItemAdd事件?”。这是否意味着要将“Public WithEvents justinreserve1 As Outlook.Items”之类的内容定义为Outlook.Items,然后将其用于该文件夹?您可以有一个Items对象列表,而不是一个指向Items对象的变量,这样您就可以有任意数量的项目都被引用,以确保它们不会被释放。你在用C#还是VB?我在用VB。听起来很有趣,你有没有一个链接,我可以在那里找到更多的信息?请,我必须实现这样的东西。你能给我提供源代码,或者告诉我在哪里可以找到解决方案,我需要将一些电子邮件存储到我们的数据库中。你是怎么做到的?请看一下。在本例中,它展示了如何获取传入的电子邮件并对其进行处理。如果需要发送项目,请添加如下处理程序:this.itemsendhndler=new Microsoft.Office.Interop.Outlook.ApplicationEvents\u 11\u ItemSendEventHandler(Application\u ItemSend);this.Application.ItemSend+=itemsendhndler;。如果您还需要什么,请告诉我。:)