问题描述
我们正在开发 Outlook VSTO 插件。
现在我正在尝试将一些信息附加到用户正在撰写的会议邀请中。我希望内容像单击 Teams-meeting 按钮那样显示在正文中,其中格式化文本和链接附加到正文的末尾。
由于内容是 HTML 并且 Outlook 对象模型没有公开 AppointmentItems 的 HTMLBody 属性,我尝试通过 Redemption 设置它:
// dispose logic left out for clarity but everything except outlookApplication and outlookAppointment is disposed after use
Application outlookApplication = ...;
AppointmentItem outlookAppointment = ...; // taken from the open inspector
NameSpace outlookSession = outlookApplication.Session;
RDOSession redemptionSession = RedemptionLoader.new_RDOSession();
redemptionSession.MAPIOBJECT = outlookSession.MAPIOBJECT;
var rdoAppointment = (RDOAppointmentItem)redemptionSession.GetRDOObjectFromOutlookObject(outlookAppointment);
string newBody = transform(rdoAppointment.HTMLBody); // appends content right before HTML </body> tag
rdoAppointment.BodyFormat = (int)OlBodyFormat.olFormatHTML;
rdoAppointment.HTMLBody = newBody;
问题
Outlook 检查器窗口未随附加内容更新。如果我再次尝试运行代码,我可以在调试器中看到附加的内容,但在 Outlook 中看不到。
我尝试过的事情:
- 保存 RDOApppointmentItem
- 还将内容添加到 Body 属性
- 使用 SafeAppointmentItem 而不是 RDOApppointmentItem;不起作用,因为 HTMLBody 是只读属性
- 通过 RDOApppointment.Fields 设置 PR_HTML
- 通过 WordEditor 粘贴 HTML(见下文)
尝试使用 WordEditor
根据建议,我还尝试通过 WordEditor 插入 HTML:
// dispose logic left out for clarity but everything except inspector is disposed after use
string htmlSnippet = ...;
Clipboard.SetText(htmlSnippet,TextDataFormat.Html);
Inspector inspector = ...;
Document wordDoc = inspector.WordEditor;
Range range = wordDoc.Content;
range.Collapse(WdCollapseDirection.wdCollapseEnd);
object placement = WdOLEPlacement.wdInLine;
object dataType = WdPasteDataType.wdPasteHTML;
range.PasteSpecial(Placement: ref placement,DataType: ref dataType);
...但我只是收到错误 System.Runtime.InteropServices.COMException (0x800A1066): Kommandoen lykkedes ikke.
(=“命令失败”)。
我还尝试使用 PasteAndFormat 而不是 PasteSpecial:
range.PasteAndFormat(WdRecoveryType.wdFormatOriginalFormatting);
...但这也给了System.Runtime.InteropServices.COMException (0x800A1066): Kommandoen lykkedes ikke.
。
我在这里做错了什么?
编辑:如果我使用 Clipboard.SetText(htmlSnippet,TextDataFormat.Text);
然后使用普通的 range.Paste();
,HTML 会按预期插入到文档的末尾(但 HTML 元素按字面插入,所以没有用)。所以一般方法似乎没问题,我似乎无法让 Outlook/Word 翻译 HTML。
版本信息
Outlook 365 MSO 32 位 救赎5.26
解决方法
由于约会正在显示,请使用 Word 对象模型 - Inspector.WordEditor
返回 Document
Word 对象。
根据 Dmitrys 的建议,这里有一个可行的解决方案:
- 在检查器窗口中显示插入的内容。
- 正确处理 HTML 内容的链接和格式(只要您不超出 Words HTML 引擎的有限功能)。
using System;
using System.IO;
using System.Text;
using Outlook = Microsoft.Office.Interop.Outlook;
using Word = Microsoft.Office.Interop.Word;
namespace VSTO.AppendHtmlExample
{
public class MyExample
{
public void AppendAsHTMLViaFile(string content)
{
// TODO: Remember to release COM objects range and wordDoc and delete output file in a finally clause
Outlook.Inspector inspector = ...;
string outputFolderPath = ...;
string outputFilePath = Path.Combine(outputFolderPath,"append.html");
Word.Document wordDoc = inspector.WordEditor;
File.WriteAllText(outputFilePath,$"<html><head><meta charset='utf-8'/></head><body>{content}</body></html>",Encoding.UTF8);
Word.Range range = wordDoc.Content;
range.Collapse(Word.WdCollapseDirection.wdCollapseEnd);
object confirmConversions = false;
object link = false;
object attachment = false;
range.InsertFile(fileName,ConfirmConversions: ref confirmConversions,Link: ref link,Attachment: ref attachment);
}
}
}