我试图让它工作的代码只是在邮件主题中添加一个'C‘,或者删除它,如果它已经存在的话。下面是对产生同样问题的原始问题的简化。我正在为UI使用.NET框架4.7.2和外接程序快捷区域(我认为这并不重要)。
ThisAddIn
类包含以下内容:
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
事件只有以下代码:
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对象。我的问题是:
我很感激你的帮助!
编辑
我已将按钮的代码更改为:
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);
}
}
仍然会犯同样的错误。我唯一没有发布的是应用程序,在那里发布它似乎不是一个好主意。但是,在异常之后,我可以再次保存。所以每一次尝试都能奏效。
发布于 2022-07-19 15:43:42
如果不需要对象来触发事件,就不要让对象处于活动状态。否则,您可能会遇到Exchange的同步问题。这也是在多个线程上使用代码(修改对象)的可能指示。相反,您可以从处理按钮单击的区域类中获取当前选定的项。
注意,在外接程序快捷表单区域中,您可以使用ExplorerObj
或InspectorObj
属性来获取显示窗体区域的项。
发布于 2022-07-19 16:22:15
如果您不使用Marshal.ReleaseComObject
,它将在几秒钟后的某个未定时间由GC发布。如果对象仍然活着(在GC释放之前),Outlook缓存它并返回相同的陈旧对象。这不是问题,但是Exchange喜欢在对象保存后调整它们。例如,以下顺序将导致所看到的错误:
修改对象server
修改
G 212
解决方案是在使用对象时立即释放它们,以便在下次需要修改对象时重新打开它们。
请注意,如果选择了一条消息,即使您使用Marshal.ReleaseComObject
释放消息,Outlook也可能缓存它本身。在这方面,约会比消息更糟糕--您可能需要选择不同的文件夹,然后回来刷新Outlook缓存。
https://stackoverflow.com/questions/73037345
复制相似问题