天道酬勤,学无止境

C# VSTO 插件 - 将纯文本电子邮件转换为 HTML(C# VSTO Add-in - Convert plain text email to HTML)

问题

我们为 Outlook 2010/2007 编写了一个 VSTO 插件。

在某一时刻,我们的插件必须将纯文本电子邮件从功能区控件转换为 HTML。 这会导致 Outlook 中出现一些奇怪的行为:

  1. 我们正在使用 MailItem COM 对象
  2. 我们设置 MailItem.HTMLBody
  3. 电子邮件被转换为 HTML,但由于某种原因字体是 Times New Roman at 10pt

Outlook 中的默认字体是 Calibri 11pt,这使得我们的电子邮件转换对用户来说看起来很奇怪。 当您使用 Outlook 中的现有按钮转换为 HTML 时,它会按预期工作,但在使用我们的插件按钮时则不会。

所以我们尝试了以下方法:

  • 提前设置 MailItem.BodyFormat
  • 用以下内容包裹我们的电子邮件文本: <span style='font-size:11.0pt;font-family:"Calibri","sans-serif"'></span> (我们从查看新 Outlook 的源代码中得到这个想法电子邮件)

<span>标签包裹在电子邮件正文中可以将字体更改为 Calibri,但字体大小保持在 10pt ...

有一个更好的方法吗? 另一种解决方法?

编辑,工作代码:

        if (_mailItem.BodyFormat != OlBodyFormat.olFormatHTML)
        {
            _mailItem.GetInspector.CommandBars.ExecuteMso("MessageFormatHtml");
        }

_mailItem 是 Microsoft.Office.Interop.Outlook.MailItem。

回答1

你有两种方法:

  1. 通过Inspector.CommandBars.ExecuteMso("MessageFormatHtml")以编程方式“单击”内置按钮
  2. 关闭检查器,转换消息格式,保存电子邮件并重新打开它。

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • 手动安装我的 word 插件 VSTO (Ribbon)? 用 C# 构建(install manually my word add-in VSTO (Ribbon)? built with c#)
    问题 是否可以手动安装我的 word 插件? Visual Studio 正在为 word 插件准备一个安装文件,它运行良好,但我想构建更复杂的安装文件。 如果我知道如何手动完成,那么构建我自己的安装程序将非常容易。 回答1 当然有可能。 如果您使用 Visual Studio 2013,您有两个常用选项来部署您的插件。 一种是使用发布,也称为 Click-Once,这基本上会为您完成所有繁重的工作,并为您留下一个可执行文件,只需双击它即可帮助您将其部署到目标机器上。 另一种方法是使用InstallShield。 转到文件 > 添加 > 新项目 > 其他项目类型 > 设置和部署 > Installshield ... 您很可能没有安装 install shield,所以一旦您尝试选择该项目,就会弹出一个网页,要求您注册(快速且免费)以下载和安装 Install-Shield 限量版 - 这样做,速度非常快。 完成后,您可以将安装项目添加到您的解决方案中。 现在这部分非常人性化,并允许您根据自己的喜好构建自定义安装。 请注意,他们所说的免费“限量版”为您提供了很多功能,因此对于轻量级单词插件来说应该足够了。 现在,将重点放在 Word 插件上,安装的整个想法是将大约 4 个注册表值放入部署的机器中以指向您编译的 dll,并对其进行描述。
  • C# VSTO Add-in - Convert plain text email to HTML
    We have written a VSTO addin for Outlook 2010/2007. At one point, our addin must convert plain text emails to HTML from a ribbon control. This causes some strange behavior in Outlook: We're using the MailItem COM object We set MailItem.HTMLBody Email is converted to HTML, but for some reason the font is Times New Roman at 10pt The default font in Outlook is Calibri 11pt, which makes our email conversion look pretty strange to the user. It works as expected when you use the existing button in Outlook to convert to HTML, but not when using our addin's button. So we tried the following: Set
  • 创建没有 VSTO 的 Excel 加载项(Create Excel Add-in without VSTO)
    问题 我使用 VS 2010 创建了一个带有 C# 的 Excel 2007 加载项。 该加载项是基于 TaskPane 的 UI。 效果很好,喜欢。 但是,我的用户没有管理员访问权限并且无法安装加载项,因为需要 VSTO。 有没有办法创建/移植这个加载项到一个普通的基于 COM 的加载项,而没有这个对 VSTO 的停止引用? 回答1 他们不一定仅仅因为您使用 vsto 就需要管理员权限。 确保插件是“每用户”而不是“每台机器”安装的。 回答2 或者您可以将其打包为 .msi,以便用户安装时,它将安装在系统帐户下。 即使您将其转换为 COM,您也必须注册(regasm)dll,并且无论如何都需要管理员权限。 最好不要通过COM路由... :)
  • 是否可以从 Visual Studio 2010 创建 Office 2003 VSTO 加载项?(Is it possible to create an Office 2003 VSTO add-in from Visual Studio 2010?)
    问题 我们现有适用于 Word 2003 和 Excel 2003 的 VS 2008 VSTO 加载项。我们目前无法升级 Office 版本。 我们刚刚尝试将我们的解决方案升级到 VS 2010,它可以很好地转换和编译,但是在构建和运行加载项时,我们收到一条消息,指出未安装所需的 Office 版本。 有没有办法解决这个问题(无需升级到 Office 2007 或 2010),以便我们可以使用 VS 2010 来构建这个加载项? 回答1 不,不幸的是这是不可能的。 VSTO 2010 不会编译为 Office 2003 设计的解决方案。它旨在与 2007/2010 一起使用。 要为 Office 2003 创建解决方案,您需要在 VS2003 上安装 VSTO 2005 或在 VS2008 上安装 VSTO 2005 SE / VSTO 2008(在后者的情况下,您也可以为 Office 2007 进行开发)。 回答2 不可以。Office 版本绑定到 VSTO 版本,而 VSTO 版本绑定到 Visual Studio 版本。 由于 VSTO 2010 不支持 Office 2003,因此您无法迁移。 此外,您需要注意打开文件扩展名可能会打开不正确的 Office 版本。 例如,在启动时,更高版本的 Office 会将自己注册到注册表中。 如果您正在开发 Excel 2003
  • Outlook VSTO C# 发布到 html url(Outlook VSTO C# Make post to html url)
    问题 我正在使用 VS2010 C# 为 Outlook 2010 制作一个插件。 我的插件的目标是在从功能区按下自定义按钮时从新电子邮件中获取收件人、抄送、BC 并将其发布到外部 url(接收发布请求)。 类似于 html/jsp 中的表单如何将输入发布到不同的页面(url)。 到目前为止,我可以获取 To,CC,BC 并将其存储在字符串变量中。 但我不知道如何向外部网址发帖。 任何帮助将不胜感激。 谢谢。 到目前为止,这是我的函数代码: public void makePost(object Item, ref bool Cancel) { Outlook.MailItem myItem = Item as Outlook.MailItem; if (myItem != null) { string emailTo = myItem.To; string emailCC = myItem.CC; string emailBCC = myItem.BCC; if (emailTo == null && emailCC == null && emailBCC == null) { MessageBox.Show("There are no recipients to check."); } else { string emailAdresses = string.Concat
  • excel VSTO 加载项能否与 excel 2007 和 2010 兼容?(Can an excel VSTO add-in be compatible with excel 2007 and 2010?)
    问题 是否可以使用 VSTO 开发可部署到 excel 2007 和 2010 的 excel 加载项? 任何指向有关此主题的详细资源的链接也将不胜感激 - 我似乎无法在 google 上找到任何专门解决此问题的内容。 我正在使用 Visual Studio 2010 开发 C# excel 加载项。 回答1 我已经为 Word 回答了这个问题,但它也适用于 Excel: 如果要部署到 Office 2010 和 2007,则必须添加对v12.0程序集( Microsoft.Office.Interop.Excel和Office )的引用。 现在仍然存在您的插件需要 2007 PIA 的问题,但如果目标计算机上只有 Office 2010,它们将无法安装(因为它们将 Office 2007 作为先决条件)。 要解决此问题,您必须为这两个 dll(在引用属性中)设置Embed Interop Assemblies = true ,并为无法再直接引用的类型使用dynamic 。 这会导致 Intellisense 找不到方法等的一些“怪异”,但这应该不是一个大问题 - 至少现在不再需要 PIA 并且您的插件将在 2007 和 2010 上部署(您必须照顾安装程序也是如此,但那是另外一回事了)。 这有点混乱,但是如果您正在使用 VSTO,我想您已经习惯了这种东西:-)
  • 在实时(未保存)Excel数据和C#对象之间进行交互的最快方法(Fastest way to interface between live (unsaved) Excel data and C# objects)
    问题 我想知道最快的方法是在打开的Excel工作簿和c#对象之间读写数据。 背景是我要开发从Excel使用的ac#应用程序,并使用excel中保存的数据。 业务逻辑将驻留在c#应用程序中,而数据将驻留在Excel工作簿中。 用户将使用Excel,并在excel工作簿上单击一个按钮(或执行类似操作)以启动c#应用程序。 然后,C#应用程序将从Excel工作簿中读取数据,处理数据,然后将数据写回到Excel工作簿中。 可能需要读取并写回到excel工作簿的数据块很多,但它们通常是相对较小的大小,例如10行20列。 有时,可能需要处理大量数据,大约50,000行40列。 我知道使用VSTO相对容易做到这一点,但是我想知道最快(但仍然健壮且优雅)的解决方案是什么,并对速度有所了解。 我不介意该解决方案建议使用第三方产品还是使用C ++。 显而易见的解决方案是使用VSTO或interop,但我不知道与我当前用于读取数据的VBA相比性能如何,或者是否还有其他解决方案。 专家交流说,VSTO比VBA慢得多,但这是几年前的事,我不知道性能是否有所提高。 http://www.experts-exchange.com/Microsoft/Development/VSTO/Q_23635459.html 谢谢。 回答1 如果C#应用程序是独立应用程序,那么您将始终涉及跨进程封送处理
  • C# 在 VSTO 加载项中运行 Outlook 实例(C# Get running Outlook instance in VSTO add-in)
    问题 我正在尝试在 Excel 加载项中获取 Outlook 应用程序对象。 如果有一个正在运行的 Outlook 实例,它应该得到它,如果没有,它应该使用 Outlook 对象模型创建一个。 这是我现在拥有的代码: public static Outlook.Application GetApplicationObject() { Outlook.Application application = null; if (Process.GetProcessesByName("OUTLOOK").Count() > 0) { application = Marshal.GetActiveObject("Outlook.Application") as Outlook.Application; } else { application = new Outlook.Application(); } return application; } 我的问题:它找到 Outlook 进程,但无法获取它们,抛出以下错误消息: 操作不可用(来自 HRESULT 的异常:0x800401E3 (MK_E_UNAVAILABLE)) 我试着一步一步调试它,并监视任务管理器。 我可以看到我有一个 Outlook 实例,但它只是任务栏右侧的一个图标。 这是否意味着该实例尚未完全加载,并且无法访问它以从中获取
  • 如何从 MS Project VSTO 加载项中侦听 Project Change 事件?(How do I listen for a Project Change event from an MS Project VSTO Add-in?)
    问题 我的外接程序有一个应用程序事件 ProjectBeforeTaskChange,可从 ThisAddIn 类获得。 我需要的是 ProjectAfterTaskChange 事件,但这并不存在。 有没有办法从应用程序级加载项中侦听 Project Change 事件? 我的最终目标是在特定文本字段更改时设置三个数字字段。 回答1 ProjectBeforeTaskChange是用于监视字段更改的正确事件。 “Before”一词指的是处理程序可以通过将 Cancel 参数设置为 True 来阻止更改。 当用户对任务字段进行更改时触发该事件。 这是一个 vb.net 示例,它在 Text1 字段更改时递增 Number1 和 Number2 字段: Private Sub Application_ProjectBeforeTaskChange(tsk As MSProject.Task, Field As MSProject.PjField, NewVal As Object, ByRef Cancel As Boolean) Handles Application.ProjectBeforeTaskChange If Field = MSProject.PjField.pjTaskText1 Then Select Case NewVal Case Is = "In-work"
  • 使用C#为Excel创建加载项(Creating add-in for Excel using C#)
    问题 我想在Excel中使用C#类方法。 有人可以指导我怎么做吗? C#组件将是excel加载项。 如何为该外接程序创建安装程序,以便我只需要给要在客户端计算机上安装外接程序的用户提供安装程序。 用户不需要执行其他任何步骤,例如注册C#dll。 回答1 您将需要创建类型为Excel 2007加载项(或Excel 2003加载项)的新Visual Studio项目。 可以在以下位置找到此选项(在Visual Studio 2008中): New Project dialog -> Project types -> Visual C# -> Office 该加载项将需要安装在目标计算机上。 加载项将能够挂接到Excel对象模型中,因此可以访问任何已加载的电子表格等。 加载项还可以将按钮添加到Excel工具栏/功能区。 回答2 (免责声明:我开发了Excel-Dna库。) 您应该看看Excel-Dna-http://excel-dna.net。 该库允许用C#,VB.NET或F#编写的托管程序集通过本机.xll接口将高性能的用户定义函数(UDF)和宏公开给Excel。 该项目是开源的,可免费用于商业用途。 使用Excel-Dna,您可以创建一个.xll加载项文件,用户可以将其作为加载项打开,而无需进行任何进一步的安装或注册。 Excel-Dna加载项可以公开RTD服务器和Excel
  • VBA VS。 VSTO有什么区别,我应该升级吗?(VBA VS. VSTO what is the difference, should I upgrade?)
    问题 我是 KISS 原则(保持简单)的忠实粉丝,并且是 Excel 用户的长期 VBA。 然而,我能找到的关于 VBA 与 VSTO(Office 的 Visual Studio 工具)的所有文章似乎都非常复杂。 首先,我厌倦了 Excel 内置的非常糟糕的 IDE,我正在寻找一个新的。 使用 Visual Studio 作为 IDE 的 VSTO 似乎是唯一的选择。 所以我试图了解 VBA 和 VSTO 之间有什么区别,以了解是否值得我学习使用 VSTO? 回答1 您使用哪种工具集很大程度上取决于个人喜好,但需要考虑以下几点: 1. 性能:对于大多数与 Excel 相关的任务,由于额外的互操作层,VSTO 与 VBA 相比执行速度非常慢。 2. UDF:VSTO 不支持 UDF 3.对象模型:使用VSTO使用Excel对象模型比使用VBA更难,因为没有.NET宏记录器给你提示。 4. IDE:通过 VSTO,您可以访问最新的 Visual Studio IDE(假设您拥有 Visual Studio 许可证) 5. .Net 框架:VSTO 让你可以访问非常丰富和强大的 .NET 框架 6. 学习曲线:VB.NET 是一种与 VBA 不同的语言,.NET 框架和对象模型的差异意味着转换并不像它想象的那么简单。 7. 如果你想走 Visual Studio/.NET 路线
  • How to call a VSTO AddIn method from a separate C# project?
    I have a C# Excel Add-in project "MyExcelAddIn" that has a public method Foo() to do something complex. For testing purposes, the add-in also defines a toolbar button which is wired to Foo() so I can test this and verify that clicking the button calls Foo() and does what I want it to do. This is fine. Now I want to call this method from a C# Windows Forms project. In the Windows Forms project I can create an Excel instance and make it visible and verify that my VSTO add-in is running as I can see the button and it works. But I can't work out how to call Foo() programatically from the Windows
  • 为 Mac 版 Microsoft Office 2016 创建加载项?(Creating an add-in for Microsoft Office 2016 for Mac?)
    问题 我可以看到 Office 2016 for Mac 现在支持加载项。 我如何着手开发一个? 是否可以将现有的 VSTO 开发的用于 Windows 的 COM 加载项转换为 Mac 版本? 回答1 不,没有将基于 VSTO 的加载项(即 COM 加载项)转换为 Office 应用程序的工具。 您需要从头开始开发 Office 应用程序(加载项)。 仅供参考,MS 在 Build#15 会议上将 Office Apps 重新命名为 Office Add-ins。 有关详细信息,请参阅 MSDN 中的 Office 应用程序入门。 回答2 是的,您可以在 Office 2016 for Mac 上使用和开发 Office Addins。 以下是有关如何在 iPad 和 Mac 上旁加载 Office 加载项进行测试的一些说明 如果您使用的是 Mac 但没有 Office 2016,您可以使用 Office 365 在线测试和调试您的加载项(应该可以从任何带有 Web 浏览器的计算机访问)。 这些加载项与 VSTO 的不同,因为它们是使用 Web 技术(HTML、CSS 和 Javascript)构建的。 这有很多好处(默认情况下跨平台、大型开发人员社区等)。 我不知道有什么方法可以将旧格式转换为新格式。 有关更多详细信息,请参阅新插件 API 的开发人员文档。 回答3
  • 在 VSTO 插件中存储一些数据的最佳方法是什么?(What is the best way to store some data in VSTO addin?)
    问题 我开发了一个 Outlook 插件,它必须是开或关。 为此,我声明了一个静态变量,如下所示, 这个插件.cs public static bool isAddInOn = false; 功能区按钮.cs private void btnRibbon_Click(object sender, RibbonControlEventArgs e) { if (ThisAddIn.isAddInOn ) { ThisAddIn.isAddInOn = false; btnRibbon.Label = "Disabled"; } else { ThisAddIn.isAddInOn = true; btnRibbon.Label = "Enabled"; } } 这是工作。 但是当我关闭 Outlook 并再次打开它时,静态变量再次重置。 这意味着当我默认打开 Outlook 时,我的加载项处于禁用状态。 我只想将该值存储在某个地方。 所以我可以在 Outlook 重新打开时检查该值。 设想: 1)开放的前景 2)通过单击其徽标(在功能区中)启用加载项 3)现在关闭展望 4) 当我再次打开 Outlook 时,它必须启用 那么我怎样才能做到这一点? 回答1 设置可以作为隐藏(关联)项目存储在文件夹中,例如收件箱或日历文件夹。 例如,Outlook 将类别列表存储为日历文件夹中的隐藏项目
  • 来自打开窗口的 c# VSTO Outlook 电子邮件正文(c# VSTO Outlook email body from opened window)
    问题 我的 Outlook 的 VSTO 应用程序有问题。 我想从选定的电子邮件中处理电子邮件正文。 对于“默认”列表之外的选定电子邮件,此代码工作正常: Object selItem = Globals.ThisAddIn.Application.ActiveExplorer().Selection[1]; Outlook.MailItem mailItem = (Outlook.MailItem)selItem; return mailItem.Body; 但是,如果用户双击打开列表中的电子邮件,则该电子邮件会显示在新窗口中。 如果在此窗口中(在功能区上)执行加载项,则仍会使用列表中的电子邮件(现在在后台)。 有没有办法找出插件是否在单独的窗口中启动,然后从中获取电子邮件正文? 问候, 弗洛里安 回答1 巧合的是,我刚刚处理了类似的事情。 我的情况并不相同,但因为我可以轻松拼凑出您正在寻找的内容,请参见下文。 我还没有测试过这个,显然你必须处理将正确的引用传递给你的 Outlook 应用程序,但由于我立即可用,我认为它会传递它并希望你会发现它有帮助。 private static void ribbonButton_Click(object sender, RibbonControlEventArgs e) { Outlook.Application application =
  • 通过 RequestComAddInAutomationService 在 C# .NET 中进行 VSTO 单元测试 Office AddIn(VSTO Unit Testing Office AddIn in C# .NET via RequestComAddInAutomationService)
    问题 在过去的几周里,我研究并阅读了各种 StackOverflow 问题以及其他教程和文档(注意下面的一些),以尝试找到一种对 VSTO 插件进行单元测试的方法。 不幸的是,它总是在我的测试中导致E_NOINTERFACE异常。 我使用的代码是下面-内的ThisAddIn部分类的一种提取物重写RequestComAddinAutomationService ,另一个描述测试实用程序接口,测试本身,以及另外的组件提取物证明外接程序组件和它的内部是到测试可见. 我的问题是:为什么这不起作用? 我很确定这遵循了普遍接受的 VSTO 测试实践。 如果以下不再可能,应该如何测试 VSTO? .NET 远程处理/IPC 是唯一的解决方案吗? 这个插件.cs public partial class ThisAddin { #region Testing Utilities private AddinHelper _comAddinObject; protected override object RequestComAddInAutomationService() { // This is being called when I debug/run my project, but not when I run the tests return _comAddinObject ?? (
  • 如果我为 office 2007 编写加载项,它是否适用于 2010、2013?(If I write an add-in for office 2007 will it work for 2010, 2013?)
    问题 我目前正在重写一些为 office 2003 编写的 VBA 宏。我想知道我是否为 2007 年编写了一个 C# 加载项,它是否适用于 2010 年甚至 2013 年。或者如果我写了它们如果它们也适用于 2007 和 2013 年,则适用于 2010 年。 我目前可以访问 2007,但如果需要,我可以访问 2010,还没有 2013。 那么,基本上,office的版本对插件的影响有多大? 回答1 如果您使用Visual Studio Tools for Office 2010 (VSTO 4.0)那么它将与Office 2007 ,Office 2010 and with Office 2013兼容。如果您使用上述以外的早期版本,那么您只能将其用于特定的办公版本。作为示例VSTO 3.0仅支持office 2003 and 2007 ,如下表所示。 有关更多信息,请查看 Visual Studio Tools for Office 和 Visual Studio 2010 Tools for Office Runtime 兼容性显示如下: 我希望这会对你有所帮助。 回答2 您可以查看 Netoffice,它是 MS Office 的包装器,可让您为所有受支持的 MS Office 版本创建插件。 您不需要 VSTO,您可以在自己的代码中检查您的 AddIn 正在运行的
  • install manually my word add-in VSTO (Ribbon)? built with c#
    Is it possible to manually install my word add-in? Visual Studio is preparing an installation file for word add-in and it worked great but i want to build more complex installation file. if i knew how to do it manually it would be very easy to build my own installer.
  • C# Get running Outlook instance in VSTO add-in
    I am trying to get an Outlook Application object in my add-in for Excel. If there's a running Outlook instance, it should get that, if there isn't any, it should create one, using the Outlook object model. This is the code I have right now: public static Outlook.Application GetApplicationObject() { Outlook.Application application = null; if (Process.GetProcessesByName("OUTLOOK").Count() > 0) { application = Marshal.GetActiveObject("Outlook.Application") as Outlook.Application; } else { application = new Outlook.Application(); } return application; } My problem: it finds Outlook processes, but
  • Detecting text changes in Word 2016 from VSTO add-in
    This question is very closely related to How to get the “KeyPress” event from a Word 2010 Addin (developed in C#)? (and in fact includes the sample code from the answer to that question), but this is specifically about developing in Visual Studio (Professional) 2015 for Word 2016 running in Windows 10. I’m trying to detect when text changes in a Word document from a VSTO add-in. I understand from How to get the “KeyPress” event from a Word 2010 Addin (developed in C#)? (Nov 14, 2011) Capturing keydown event of MS Word using C# (Oct 21, 2012) How to raise an event on MS word Keypress (Oct 24