C# VSTO:在已发送邮件中创建假电子邮件时出现问题

C# VSTO:在已发送邮件中创建假电子邮件时出现问题,c#,outlook,vsto,C#,Outlook,Vsto,我想在“已发送邮件”文件夹中创建一封假电子邮件。为实现这一目标: a) 我正在拍摄一份未发送状态的邮件副本 b) 将GUID分配为UserProperty c) 更改MessageClass=IPM.Post并保存 d) 信息:此处仍然存在UserProperty e) 发送邮件 在“已发送邮件”文件夹的ItemAdd事件处理程序中: a) 我正在检查物品是否已过帐 b) 尝试使用set-UserProperty标识当前对象(这已经失败,没有可用的UserProperties->问题1) c)

我想在“已发送邮件”文件夹中创建一封假电子邮件。为实现这一目标:

a) 我正在拍摄一份未发送状态的邮件副本

b) 将GUID分配为UserProperty

c) 更改MessageClass=IPM.Post并保存

d) 信息:此处仍然存在UserProperty

e) 发送邮件

  • 在“已发送邮件”文件夹的ItemAdd事件处理程序中:

    a) 我正在检查物品是否已过帐

    b) 尝试使用set-UserProperty标识当前对象(这已经失败,没有可用的UserProperties->问题1)

    c) 要通过更改MessageClass=IPM.Note并保存将当前positem转换为MailItem吗

  • 即使我在发送后使用subject而不是UserProperty(因为subject存在)来标识,我仍然在senteditems->PROBLEM 2中看到对象是positem(IPM.Post),而不是MailItem(IPM.Note)

    当我在“已发送邮件”中进行查找时,查找特定的邮件,更改MessageClass=IPM。注意并保存,positem将成功更改为MailItem

    关于问题1: 为什么在此事件期间PostItem的UserProperties不可用

    关于问题2: 为什么在此事件期间我无法将帖子项“转换”为邮件项

    我怎样才能解决这个问题

    这是我的代码:

    在本附件中:

                    // ItemSend Event
                    Outlook.Application application = this.Application;
                    application.ItemSend += new Outlook.ApplicationEvents_11_ItemSendEventHandler(ItemSend_BeforeSend);
    
    
    ...
    
    // ItemAdd event
                    outlookNameSpace = this.Application.GetNamespace("MAPI");
                    Sent_items = outlookNameSpace.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderSentMail);
    
                    items = Sent_items.Items;
                    items.ItemAdd += new Outlook.ItemsEvents_ItemAddEventHandler(items_ItemAdd);
    
    ...
    
    // ItemAdd event action
                    void items_ItemAdd(object Item)
                    {
    ...
                                Outlook.PostItem postItem = Item as Outlook.PostItem;
    
                                Outlook.UserProperties postUserProperties = null;
                                Outlook.UserProperty postUserProperty = null;
    
                                // for debug only
                                MessageBox.Show(null ?? postItem.Subject, "TestApp: Info", MessageBoxButtons.OK);
    
    
                                try
                                {
                                    // start of test part
    
                                    postUserProperties = postItem.UserProperties;
                                    StringBuilder builder = new StringBuilder();
    
                                    for (int i = 1; i <= postUserProperties.Count; i++) // count is 0 here so no UserProperties !!!
                                    {
                                        postUserProperty = postUserProperties[i];
                                        if (postUserProperty != null)
                                        {
                                            builder.AppendFormat("Name: {0} \tValue: {1} \n\r",
                                                postUserProperty.Name, postUserProperty.Value);
                                            Marshal.ReleaseComObject(postUserProperty);
                                            postUserProperty = null;
                                        }
                                    }
                                    if (builder.Length > 0)
                                    {
                                        System.Windows.Forms.MessageBox.Show(builder.ToString(),
                                            "The UserProperties collection");
                                    }
                                    // end of test part
    ...
    }
    
    // ItemSend_BeforeSend event action
                    void ItemSend_BeforeSend(object item, ref bool cancel)
                    {
    ...
    
     Outlook.Application objOutlook = new Outlook.Application();
                    Outlook.MailItem email = (Outlook.MailItem)objOutlook.Session.OpenSharedItem(MjFileMsg);
    
                    // add we item guid to object in order to identify afterwards
                    var mailUserProperty = email.UserProperties.Add("WeItemGuid", Outlook.OlUserPropertyType.olText, false, 1);
    
                    createdWeItemGuid = Guid.NewGuid().ToString().ToLower();
                    mailUserProperty.Value = createdWeItemGuid;
    
                    email.MessageClass = "IPM.Post";
                    email.Save();
    
                    // debug only: check if value is present after changing messageclass (yes, it is present!)
                    Outlook.UserProperty testProp = email.UserProperties["WeItemGuid"];
                    var testVal = testProp.Value;
    
                    email.Send();
    ...
    }
    
    
    
    

    重置消息类后是否保存消息?请记住,您还需要删除
    PR\u ICON\u INDEX
    属性

    您无法将
    positem
    动态转换为
    MailItem
    ,因为Outlook仍然引用原始的
    positem
    对象。只有在您的代码和Outlook取消引用该对象并稍后重新打开该对象后,它才会看到您所做的更改

    如果使用是一种选择,那么它很容易(在我的脑海中):


    谢谢你,德米特里,这很有帮助。现在我遇到了另一个问题。当我与真实的收件人一起发送邮件时,收件人确实收到了此邮件,我不希望这样(它应该只是已发送邮件中真实电子邮件的修改副本)。因此,我认为我在ItemSend事件期间删除了所有收件人,并在ItemAdd in Send Items期间再次添加,但现在PostItem不再登录Send Items。我不能在没有收件人的情况下发送帖子,以便将其写入已发送的邮件中吗?请参阅[UPDATE 1]以获取以前的评论。否,如果您尝试发送任何内容,则必须有收件人。您是否真的结束了任何内容?或者只是在“已发送邮件”文件夹中创建一个假邮件?a)我正在起草一封电子邮件,保存一份副本,发送一封(带有加密附件),并希望在“已发送邮件”中放置一个未加密的版本。未加密的邮件当然不应该发送。b) 当有人回复加密邮件时,未加密邮件(可以有相同的主题)应显示在收件箱的对话视图中。
    
                    Outlook.Application objOutlook = new Outlook.Application();
                    Outlook.MailItem email = (Outlook.MailItem)objOutlook.Session.OpenSharedItem(MjFileMsg);
    
                    // remove recipients otherwise PostItem will be sent really to recipients (but obviously causing the PostItem not to be sent !!!)
                    email.To = null;
                    email.CC = null;
                    email.BCC = null;
    
    // This has the same effect like setting To/Cc/Bcc to null:
    /*
                    foreach (Outlook.Recipient Recip in email.Recipients)
                    {
                        Recip.Delete();
                    }
    */
    
                    email.MessageClass = "IPM.Post";
                    email.Save();
                    email.Send();
    
    RDOSession session = new RDOSession();
    session.MAPIOBJECT = outlookNameSpace.MAPIOBJECT;
    RDOFolder folder = session.GetDefaultFolder(rdoDefaultFolders.olFolderSentMail);
    RDOMail msg = folder.Items.Add("IPM.Note");
    msg.Sent = true;
    msg.ReceivedTime = DateRime.Now;
    RDOMail originalMsg = (RDOMail)session.GetRDOObjectFromOUtlookObject(Item);
    originalMsg.CopyTo(msg);
    msg.Sender = session.CurrentUser;
    msg.SentOnBehalfOf = session.CurrentUser;
    msg.Save();