如何运用netoffice,开发兼容多个版本的outlook插件

###需求描述
用户使用outlook发送邮件时,如果收件人包含公司外的人员,则弹出提醒,确认是否发送。
###思考
首先思考到outlook插件,基于C#开发的话,会依赖.netframework等版本环境,并且outlook版本也很多兼容性,所以和领导确认了一下,仅做win7及以上操作系统,.netframework 4.0以上版本。
###开始干活
因为第一次做outlook插件,而且很久没有接触过C#开发,所以第一想法还是借助百度。
虽然搜索资料很多,但是大部分都是用的VSTO来实现的outlook插件,下载VS2017然后开始创建项目,发现创建这个时候outlook版本就已经有要求了,心里一凉,觉得兼容性应该很麻烦。

看了一些别人的博客,然后很快用VSTO实现了第一个版本,本地测试后,发现一切正常,本地是outlook2010版本,然后再另外两个同事那里安装测试,悲剧就开始了,首先是.netframwork版本不能低于4.0,然后提示缺少vs office tools工具,很是头疼。。。期间折腾了下载VS的各种版本等等,特别无语。

###摸索
因为一直在做java开发,也不清楚C#的outlook插件兼容性要怎么解决,还是一直百度,基本看遍了网上相关的论坛,帖子,微软的MSDN等等。后来发现有人遇到了同样的兼容性问题,然后了解到有个开源的netoffice,这里附上旧的地址,链接:https://archive.codeplex.com/?p=netoffice 新的地址已经迁移到GitHub:https://github.com/NetOfficeFw/NetOffice

依仗着谷歌浏览器自带的页面翻译,把这个工具对应的问题讨论、等等都看了一遍。然后参考着官网的例子,终于写出了2.0版本的功能。

###参考步骤

  1. 首先在vs里创建一个类库的项目

  2. 添加引用选择下载好的NetOffice.dll,Office.dll,Outlook.dll,extensibility.dll
    编写代码内容如下:

    using System;
    using System.Runtime.InteropServices;
    using System.Collections.Generic;
    using System.Windows.Forms;
    using NetOffice;
    using NetOffice.Tools;
    using Outlook = NetOffice.OutlookApi;
    using NetOffice.OutlookApi.Enums;
    using NetOffice.OutlookApi.Tools;
    using Office = NetOffice.OfficeApi;
    using NetOffice.OfficeApi.Enums;
    using NetOffice.OfficeApi.Tools;namespace test008
    {
    [COMAddin("test008", "test008", 3), ProgId("test008.Addin"), Guid("9774342E-E2F0-4557-9137-8DA2B7720285")]
    [RegistryLocation(RegistrySaveLocation.CurrentUser)]
    public class Addin : Outlook.Tools.COMAddin
    {public Addin(){this.OnStartupComplete += new OnStartupCompleteEventHandler(Addin_OnStartupComplete);this.OnDisconnection += new OnDisconnectionEventHandler(Addin_OnDisconnection);}private void Addin_OnStartupComplete(ref Array custom)
    {Outlook.Application application = this.Application;application.ItemSendEvent += new Outlook.Application_ItemSendEventHandler(ItemSend_BeforeSend);}
    private void ItemSend_BeforeSend(object Item, ref bool Cancel)
    {Outlook.MailItem mailItem = (Outlook.MailItem)Item;if (mailItem != null){String toEmails = GetSMTPAddressForRecipients(mailItem);if (!"".Equals(toEmails)){String otherCompanyEmails = "";//用于存放是否包含外部人员邮箱,默认为空String[] regMatch = { "*****.cn" };//用于存放公司已有的邮箱后缀,全部为小写。String[] emails = toEmails.ToLower().Split(';');if (emails != null && emails.Length > 0){int emailCount = emails.Length;for (int i = 0; i < emailCount; i++){if ("".Equals(emails[i].Trim())){continue;}Boolean isExistOtherCompany = true;//默认认为都是公司外部人员邮箱for (int k = 0; k < regMatch.Length; k++){if (emails[i].IndexOf(regMatch[k]) >= 0){isExistOtherCompany = false; //匹配到公司邮箱则跳出循环继续下一个判断break;}}if (isExistOtherCompany){otherCompanyEmails = otherCompanyEmails + emails[i] + ";";}}if (!"".Equals(otherCompanyEmails)){DialogResult dr = MessageBox.Show("您的收件人中包含其他公司人员邮箱:" + otherCompanyEmails.Replace(';', ' ') + ",确认发送吗?", "温馨提示", MessageBoxButtons.OKCancel);if (dr == DialogResult.OK){//用户选择确认的操作Cancel = false;}else if (dr == DialogResult.Cancel){//用户选择取消的操作Cancel = true;}}}}}}
    //获取收件人和抄送人员的邮箱信息,并自动用;间隔
    private String GetSMTPAddressForRecipients(Outlook.MailItem mailItem)
    {String result = "";const string PR_SMTP_ADDRESS ="http://schemas.microsoft.com/mapi/proptag/0x39FE001E";Outlook.Recipients recips = mailItem.Recipients;foreach (Outlook.Recipient recip in recips){Outlook.PropertyAccessor pa = recip.PropertyAccessor;string smtpAddress =pa.GetProperty(PR_SMTP_ADDRESS).ToString();result = result + smtpAddress + ";";}return result;
    }private void Addin_OnDisconnection(ext_DisconnectMode RemoveMode, ref Array custom)
    {
    }protected override void OnError(ErrorMethodKind methodKind, System.Exception exception)
    {MessageBox.Show("An error occurend in " + methodKind.ToString(), "test008");
    }[RegisterErrorHandler]
    public static void RegisterErrorHandler(RegisterErrorMethodKind methodKind, System.Exception exception)
    {MessageBox.Show("An error occurend in " + methodKind.ToString(), "test008");
    }
    }
    }
    

###又遇到问题了
按照网上其他帖子说法,编写之后,修改项目的属性,在生成里面,需要勾选为COM互操作注册,但是我这个如果勾选,则项目启动会提示一个引入的错误,网上建议说要调整互操作类型选项。
另外因为项目的目标框架定为了.net Framework 3.5 ,所以引入的文件没有修改嵌入互操作类型选项,修改XML文件也没有生效,所以取消勾选为COM互操作注册选项,不知道会不会引发其他问题,然后本地调试启动了outlook之后,本地功能生效了,outlook加载项中,会出现我创建好的test008dll。

###继续遇到新问题
高兴了一小会之后,发现,怎么把这个生成的dll文件给其他人注册使用呢?第一个想法想到了注册表,然后一顿折腾,根本不行。之后又尝试了wix,install sheild之类的N多的打包工具,然后也没有达到我想要的效果。
后来又看微软的官网,等等,继续逛netoffice的问题,最后看到一个人提交一个问题,说自己的dll插件注册之后没有生效。莫非是我注册的不对了?
查看N多信息之后,最后发现是用错了命令,.netframework 4.0会有一个regAsm.exe的文件,直接执行regAsm.exe ***.dll文件即可。。。。各种-_-||。。。
最后又看了下bat文件的语法怎么编写执行,最终终于写出了一个安装脚本,然后在其他人电脑上运行,暂时没发现问题。

最后感谢下netoffice的作者,提供了一个这么好的工具。
如果你也遇到类似问题不知道怎么处理,可以留言沟通交流下。

欢迎扫描关注公众号

如何运用netoffice,开发兼容多个版本的outlook插件相关推荐

  1. AngularJS开发指南7:AngularJS本地化,国际化,以及兼容IE低版本浏览器

    AngularJS本地化,国际化 国际化,简写为i18n,指的是使产品快速适应不同语言和文化. 本地化,简称l10n,是指使产品在特定文化和语言市场中可用. 对开发者来说,国际化一个应用意味着将所有的 ...

  2. 【Android 应用开发】 Android 各种版本简介 ( Support 支持库版本 | Android Studio 版本 | Gradle 版本 | jcenter 库版本 )

    初学者遇到 Android Studio, 导入工程后, 会出现各种奇葩错误, 如果管理好各个插件, gradle, SDK, SDK Tools, 各种官方依赖库 的版本, 会将错误大大的减少; 这 ...

  3. 兼容IE低版本的文件上传解决方案

    兼容IE低版本的文件上传解决方案 参考文章: (1)兼容IE低版本的文件上传解决方案 (2)https://www.cnblogs.com/zhou195/p/9253895.html 备忘一下.

  4. 【Qt】Qt 开发桌面程序 ( Qt 版本 5.14.2 | 编辑 Qt 桌面按钮控件 | 修改按钮文本 | 为按钮添加点击事件 | 系统调用 | 去掉系统调用命令窗口 )

    文章目录 一.添加按钮控件 二.修改按钮文本 三.为按钮添加点击事件 ( 弹出对话框 ) 四.为按钮添加点击事件 ( 打开记事本 ) 五.为按钮添加点击事件 ( 打开计算器 ) 六.去掉系统调用时弹出 ...

  5. position:fixed 兼容浏览器低版本

    项目中遇到的坑,写篇博客做个笔记纪念下,position: fixed一般来说都兼容各个浏览器,但是要兼容浏览低版本问题,就得用-webkit-transform: translateZ(0);这段代 ...

  6. [vue] 你知道vue2.0兼容IE哪个版本以上吗?

    [vue] 你知道vue2.0兼容IE哪个版本以上吗? 双向绑定的原理是基于Object,defineProperty的,ie8及以下不兼容这个api.另外还有一些特性至少在ie10才能用,我们已经弃 ...

  7. brew安装指定版本mysql,Mac 系统为 Valet 开发环境安装指定版本 MySQL

    Mac 系统为 Valet 开发环境安装指定版本 MySQL 由 学院君 创建于1年前, 最后更新于 5个月前 版本号 #3 1547 views 1 likes 0 collects 在 Mac 系 ...

  8. Thinkphp开发无需挂机开源版本支付系统原码带云端ZFB和WX免输入金额跳转支付

    无需挂机 支付宝微信免输金额 跳转支付 反正贼牛p Thinkphp开发无需挂机开源版本支付系统码带云端ZFB和WX免输入金额跳转支付

  9. 版本兼容业务(版本一致、强制升级、版本兼容)

    版本兼容业务(版本一致.强制升级.版本兼容) /** * 根据版本号查询apk兼容性 * 三种情况: * a.不用升级 版本一致 * b.建议升级 版本低,当前版本兼容 * c.强制升级 版本低且不被 ...

最新文章

  1. 第9章 中断和动态时钟显示
  2. 淘宝直播在智能互动领域的探索及落地
  3. plsql打开sql窗口快捷键_巧用Navicat for MySQL的快捷键
  4. Java基础语法之方法的参数传递与综合案例
  5. 不要再被Python洗脑了!!
  6. swift4.0闭包
  7. Grunt自动化工具相关
  8. the JDBC Driver has been forcibly unregistered
  9. Echarts——自定义仪表盘图表
  10. SM干货篇:你应该具备的提问技巧!
  11. 如何成为一个牛逼的程序员?
  12. java excel 批注_Java 添加、修改、读取、复制、删除Excel批注
  13. 产品设计杂谈--微信篇
  14. 2022年4月蓝桥杯软件类省赛:真题+解析
  15. HAL库STM32CuBe实现按键扫描芯片STM32F407
  16. 智源AI日报(2022-09-02):我是如何从头开始写一篇顶级论文的
  17. 拥抱新技术?你需要考虑的方面
  18. 【web前端】引入CSS(选择器)
  19. 根据IP地址获取物理位置
  20. java中判断是不是数字

热门文章

  1. 喜报|中新赛克OceanMind独家赞助的DSE期刊被ESCI收录
  2. Altium Designer 20设置铜皮到板框的距离(设置内缩)
  3. ESP32C3基于Arduino框架下的 ESP32 RainMaker开发示例教程
  4. ORACLE exp时出现1455错误,全网唯一正解,建议收藏
  5. 2020年中国钓具市场现状分析,出口持续增长,整体企业众多,格局未明「图」
  6. 干货:Hulu教你赴美工作怎么拿签证!
  7. Zabbix+分布式数据库TiDB实现分布式数据库监控
  8. 数学之美:拼音输入法的数学原理
  9. linux下Git代理设置
  10. 鼠标移上去触动hover致使div向上移动几个相素(动画transition轻轻的移动)