首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >导致和修复Outlook中的“由于消息已更改而无法执行操作”的原因

导致和修复Outlook中的“由于消息已更改而无法执行操作”的原因
EN

Stack Overflow用户
提问于 2022-07-19 12:57:36
回答 2查看 140关注 0票数 0

我试图让它工作的代码只是在邮件主题中添加一个'C‘,或者删除它,如果它已经存在的话。下面是对产生同样问题的原始问题的简化。我正在为UI使用.NET框架4.7.2和外接程序快捷区域(我认为这并不重要)。

ThisAddIn类包含以下内容:

代码语言:javascript
运行
复制
    private static Explorer _explorer;

    private void ThisAddIn_Startup(object sender, System.EventArgs e)
    {
        {initializing code}
        _explorer = Application.ActiveExplorer();
    }

    public static MailItem GetMail()
    {
        var selection = _explorer.Selection;
        if (selection.Count == 0)
            return null;
        return selection[1];
    }

表单中的button-click事件只有以下代码:

代码语言:javascript
运行
复制
    private void button1_Click(object sender, EventArgs e)
    {
        var mail = ThisAddIn.GetMail();
        if (mail.Subject.StartsWith("C"))
            mail.Subject = mail.Subject.TrimStart('C');
        else
            mail.Subject = "C" + mail.Subject;
        mail.Save();
    }

对于来自我个人邮箱的邮件来说,这实际上很好,但是对于Exchange的邮件却会抛出异常,所以我可以通过单击下面的按钮来加载:

单击该按钮一次可以正常工作,但再次单击该按钮时总是会抛出一个System.Runtime.InteropServices.COMException,该函数无法执行,因为消息已被更改。作为信息。我明白了,因为它确实被改变了。纵观StackOverflow,我读到,我必须用System.Runtime.InterServices.Marshal.ReleaseComObject()来释放COM对象。我的问题是:

  • 为什么要在2022年显式地释放对象?我真的觉得我在做一些事情,outdated.
  • How?这真的是正确的方法吗?
  • 什么(我要发布)?那些邮件?_explorer?所有的?我对此感到特别困惑,因为无论我试图发布什么,它似乎都无法修复它。同样,我应该在哪里发布"it“-在ThisAddIn还是表单中?

我很感激你的帮助!

编辑

我已将按钮的代码更改为:

代码语言:javascript
运行
复制
private void button1_Click(object sender, EventArgs e)
    {
        Explorer explorer = null;
        Selection selection = null;
        MailItem mail = null;
        try
        {
            explorer = (Explorer)ExplorerObj;
            if (explorer == null)
                return;
            selection = explorer.Selection;
            if (selection.Count <= 0)
                return;
            mail = selection[1];
              if (mail.Subject.StartsWith("C"))
                mail.Subject = mail.Subject.TrimStart('C');
            else
                mail.Subject = "C" + mail.Subject;
            mail.Save();
        }
        finally
        {
            if (mail != null && Marshal.IsComObject(mail))
                Marshal.ReleaseComObject(mail);
            if (selection != null && Marshal.IsComObject(selection))
                Marshal.ReleaseComObject(selection);
            if (explorer != null && Marshal.IsComObject(explorer))
                Marshal.ReleaseComObject(explorer);
        }
    }

仍然会犯同样的错误。我唯一没有发布的是应用程序,在那里发布它似乎不是一个好主意。但是,在异常之后,我可以再次保存。所以每一次尝试都能奏效。

EN

回答 2

Stack Overflow用户

发布于 2022-07-19 15:43:42

如果不需要对象来触发事件,就不要让对象处于活动状态。否则,您可能会遇到Exchange的同步问题。这也是在多个线程上使用代码(修改对象)的可能指示。相反,您可以从处理按钮单击的区域类中获取当前选定的项。

注意,在外接程序快捷表单区域中,您可以使用ExplorerObjInspectorObj属性来获取显示窗体区域的项。

票数 1
EN

Stack Overflow用户

发布于 2022-07-19 16:22:15

如果您不使用Marshal.ReleaseComObject,它将在几秒钟后的某个未定时间由GC发布。如果对象仍然活着(在GC释放之前),Outlook缓存它并返回相同的陈旧对象。这不是问题,但是Exchange喜欢在对象保存后调整它们。例如,以下顺序将导致所看到的错误:

修改对象server

  • Exchange
  1. OST provider将更改推送给

修改

  1. ,更改从服务器拖到OST
  2. ,再次从(1)中修改相同的对象。

G 212

解决方案是在使用对象时立即释放它们,以便在下次需要修改对象时重新打开它们。

请注意,如果选择了一条消息,即使您使用Marshal.ReleaseComObject释放消息,Outlook也可能缓存它本身。在这方面,约会比消息更糟糕--您可能需要选择不同的文件夹,然后回来刷新Outlook缓存。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73037345

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档