Outlook 插件开发小结

Outlook 插件开发小结

  最近实习在做outlook插件开发,阅读了一些VSTO的相关概念和知识。遂将整理所得与大家分享和交流。PS:这篇博客为本人的第一篇正式技术博客,如有错误和不妥之处请读者见谅。

  

 I.基本介绍

  1.VSTO外接程序体系结构

             

 

  2.Outlook add-in注册表项

    1.Microsoft Office 2010 应用程序可加载在 HKEY_LOCAL_MACHINE 或 HKEY_CURRENT_USER 下注册的外接程序。默认情况下,2007 Microsoft Office system 中的应用程序只能加载在 HKEY_CURRENT_USER 下注册的外接程序。

    2.外接程序注册表项位于所有应用程序(Visio 除外,它的 根 为 HKEY_CURRENT_USER or HKEY_LOCAL_MACHINE)的以下注册表项之下:Root\Software\Microsoft\Office\应用程序名称\Addins\外接程序ID(外接程序ID一般为项目名)

    3.Outlook 窗体区域的注册表项:Root\Software\Microsoft\Office\Outlook\FormRegions\消息类

 

  3.安装部署

    1. ClickOnce 部署:仅当前用户可以注册外接程序。这是因为 ClickOnce 只支持在 HKEY_CURRENT_USER 下创建密钥。

    2. Windows Installer部署:无限制

 

  4.定制项

   UI方面

   1.自定义UI

   2.窗体区域/ribbon:与outlook界面相整合

   逻辑方面

   1.与outlook PIA或其他office PIA进行交互

   2.自定义属性:用于用户自定义数据和扩展功能

 

  5.outlook对象模型

   Application 对象

   Application 对象表示 Outlook 应用程序,它是 Outlook 对象模型中最高级的对象。

 

   Explorer 对象

   Explorer 对象表示显示包含项(如电子邮件、任务或约会)的文件夹内容的窗口。Explorer 对象包括可用来修改窗口的方法和属性,以及窗口更改时所引发的事件。

 

   Inspector 对象

   Inspector 对象表示显示单个项(如电子邮件、任务或约会)的窗口。Inspector 对象包括可用来修改窗口的方法和属性,以及窗口更改时所引发的事件。

 

   MAPIFolder 对象

   MAPIFolder 对象表示包含电子邮件、联系人、任务及其他项的文件夹。Outlook 提供 16 个默认 MAPIFolder 对象。

 

   MailItem、AppointmentItem、TaskItem、ContactItem分别对应邮件项、约会项、任务项、联系人项

 

  6.卸载

    1.手动删除(控制面板\程序\卸载程序)

    2.删除注册表(其实并未完整卸载,只是outlook不能检测到。控制面板\程序中仍有该插件信息)

    3.禁用插件(推荐:使outlook将插件禁用,但保留在加载项栏中。想重用时可以手动启用。)

    后两项都能用代码完成。

  

 II.实例讲解

  以下demo在VS 2010下完成。

 

  1.VS 为office拓展程序开发提供了很好的开发项。创建OutlookAddIn:File->New->Project->Visual C#->Office->2010(2007)->Outlook 2010 Add-in.

   

  2.命名好工程名确认后,系统会自动生成ThisAddIn类以及一些相应的事件。而ThisAddIn类就是整个拓展程序的一个抽象表示。

  

  3.现在,我们可以添加自己的定制项。这里我首先添加一个窗体区域(FormRegion),窗体区域的特点是可以将该区域嵌入到outlook的工作区。右击工程名->Add->New Item->Outlook Form Region.点击确认后会进入FormRegion的导航设置  框。分别有一下几项:

    一.创建方式:创建新窗体区域/从已有窗体区域导入(这里选择前者)

    二.窗体样式:按窗体位置和区域分有四种样式(这里选择第二项:adjoining加在工作窗体的底部)

    三.添加描述和呈现喜好(这里选择默认)

    四.选择呈现该窗体区域的消息类。由于我们是要做一个简单的联系人的拓展程序(下面会介绍),所以我们呈现该窗体区域的消息类选择Contact。

  设置完成点击Finish窗体区域就会成功添加。这时会出现一个自定义控件,我们可以设置里面的控件和样式。

  

  现在介绍一下我们的拓展程序。这里我们是做一个跟联系人有关的拓展程序:为联系人添加附加属性。我们知道联系人默认的属性是有限的,为了方便用户自定义属性,Outlook为我们设置了UserProperties方便用户设置各种自定义属性。这里我们就要  用它设置我们的定制项。这里我们帮联系人添加父母及其生日的附加属性。为简单起见我们需要两个textBox和两个DataTimePicker。布局完成如下:

  

  4.接下来,我们需要处理拓展程序的逻辑部分。主要思路是定义自定义属性、绑定属性、属性变更处理。主要代码及注释如下:

  1         // 自定义的属性名字  2         private const string PROPERTY_NAME_MOTHER_NAME = "PROPERTY NAME MOTHER NAME";  3         private const string PROPERTY_NAME_MOTHER_BIRTHDAY = "PROPERTY NAME MOTHER BIRTHDAY";  4         private const string PROPERTY_NAME_FATHER_NAME = "PROPERTY NAME FATHER NAME";  5         private const string PROPERTY_NAME_FATHER_BIRTHDAY = "PROPERTY NAME FATHER BIRTHDAY";  6   7         // 自定义属性对象  8         private Outlook.UserProperty _MotherNameProperty = null;  9         private Outlook.UserProperty _MotherBirthdayProperty = null; 10         private Outlook.UserProperty _FatherNameProperty = null; 11         private Outlook.UserProperty _FatherBirthdayProperty = null; 12  13         // 对应的Contact对象 14         public Outlook.ContactItem _Contact = null; 15  16         // 标记是否内容修改 17         private bool _Changed = false; 18  19         // Occurs before the form region is displayed. 20         // Use this.OutlookItem to get a reference to the current Outlook item. 21         // Use this.OutlookFormRegion to get a reference to the form region. 22         private void FormRegion1_FormRegionShowing(object sender, System.EventArgs e) 23         { 24             // 获得FormRegion所对应的Contact对象 25             _Contact = ((Microsoft.Office.Tools.Outlook.FormRegionControl)sender).OutlookItem as Outlook.ContactItem; 26             //_Contact = Globals.ThisAddIn.Application.ActiveInspector().CurrentItem; 27  28             // 从联系人的自定义属性中,获得母亲姓名属性 29             _MotherNameProperty = _Contact.UserProperties.Find(PROPERTY_NAME_MOTHER_NAME, Type.Missing); 30             if (_MotherNameProperty != null) 31             { 32                 // 如果存在这个属性,则取出Value为控件赋值 33                 tbMotherName.Text = _MotherNameProperty.Value as String; 34             } 35             else 36             { 37                 // 不存在则创建这个属性 38                 _MotherNameProperty = _Contact.UserProperties.Add(PROPERTY_NAME_MOTHER_NAME, Outlook.OlUserPropertyType.olText, Type.Missing, Type.Missing); 39             } 40  41             // 母亲生日,原理相同 42             _MotherBirthdayProperty = _Contact.UserProperties.Find(PROPERTY_NAME_MOTHER_BIRTHDAY, Type.Missing); 43             if (_MotherBirthdayProperty != null) 44             { 45                 dtpMotherBirthday.Value = (DateTime)_MotherBirthdayProperty.Value; 46             } 47             else 48             { 49                 _MotherBirthdayProperty = _Contact.UserProperties.Add(PROPERTY_NAME_MOTHER_BIRTHDAY, Outlook.OlUserPropertyType.olDateTime, Type.Missing, Type.Missing); 50             } 51  52             // 父亲姓名 53             _FatherNameProperty = _Contact.UserProperties.Find(PROPERTY_NAME_FATHER_NAME, Type.Missing); 54             if (_FatherNameProperty != null) 55             { 56                 tbFatherName.Text = _FatherNameProperty.Value as String; 57             } 58             else 59             { 60                 _FatherNameProperty = _Contact.UserProperties.Add(PROPERTY_NAME_FATHER_NAME, Outlook.OlUserPropertyType.olText, Type.Missing, Type.Missing); 61             } 62  63             // 父亲生日 64             _FatherBirthdayProperty = _Contact.UserProperties.Find(PROPERTY_NAME_FATHER_BIRTHDAY, Type.Missing); 65             if (_FatherBirthdayProperty != null) 66             { 67                 dtpFatherBirthday.Value = (DateTime)_FatherBirthdayProperty.Value; 68             } 69             else 70             { 71                 _FatherBirthdayProperty = _Contact.UserProperties.Add(PROPERTY_NAME_FATHER_BIRTHDAY, Outlook.OlUserPropertyType.olDateTime, Type.Missing, Type.Missing); 72             } 73  74             // 将这四个控件绑定change事件,只有在修改之后,我们才会将值回写到Contact对应的属性中去 75             tbMotherName.TextChanged += new EventHandler(content_Changed); 76             dtpMotherBirthday.ValueChanged += new EventHandler(content_Changed); 77             tbFatherName.TextChanged += new EventHandler(content_Changed); 78             dtpFatherBirthday.ValueChanged += new EventHandler(content_Changed); 79  80             // 在Write事件中,把修改的值保存到属性中去 81             _Contact.Write += new Microsoft.Office.Interop.Outlook.ItemEvents_10_WriteEventHandler(contact_Write); 82         } 83  84         void content_Changed(object sender, EventArgs e) 85         { 86             // 有修改时,将_Change置为true 87             _Changed = true; 88         } 89  90         void contact_Write(ref bool Cancel) 91         { 92             if (_Changed) 93             { 94                 // 保存值到属性中去 95                 _MotherNameProperty.Value = tbMotherName.Text.Trim(); 96                 _MotherBirthdayProperty.Value = dtpMotherBirthday.Value; 97                 _FatherNameProperty.Value = tbFatherName.Text.Trim(); 98                 _FatherBirthdayProperty.Value = dtpFatherBirthday.Value; 99             }100 101         }102 103         // Occurs when the form region is closed.104         // Use this.OutlookItem to get a reference to the current Outlook item.105         // Use this.OutlookFormRegion to get a reference to the form region.106         private void FormRegion1_FormRegionClosed(object sender, System.EventArgs e)107         {108             // 关闭事件绑定109             _Contact.Write -= new Microsoft.Office.Interop.Outlook.ItemEvents_10_WriteEventHandler(contact_Write);110 111             // 释放对象112             System.Runtime.InteropServices.Marshal.ReleaseComObject(_Contact);113             _Contact = null;114         }

  

  现在,拓展程序已经可以调试了。运行后outlook程序会自动启动并加载此拓展项。打开联系人信息工作区会看到刚才的窗体区域被成功地加了进去。

  

  

  好了。我们联系人的自定义属性已经做好了。为了实例的完整性,现在我们再加一个ribbon控件,使其附加在本地outlook的ribbon菜单项内。其功能为:一.显示联系人信息(主要是我们刚才添加的附加属性信息);二.拓展程序卸载/禁用。

  5添加ribbon:右击工程名->Add->New Item->Ribbon (Visual Designer).点击确认后会看到一个ribbon控件被添加了进来。值得注意的是RibbonType属性,它决定着ribbon的显示位置默认为Mail.Read。由于我们要将该ribbon显示在主窗体的  ribbon项集中,因此其RibbonType应勾选Explore(同理如何想让该ribbon显示在联系人窗体的ribbon项中可勾选Contact)。现在我们要为其添加两个RibbonButton:分别为Show Contacts Info和Unistall。

  

  6.针对Show Contacts Info为了显示联系人信息,我们需要添加一个窗体来进行显示。于是我们可以添加一个UserControl名为ContactsInfoDisplay,其形式如下:

  

  为了显示联系人信息,我们可以传入一个ContactItem作为其构造函数的参数。然后获取其对象中的相关属性。代码如下: 

 1 public ContactsInfoDisplay(Microsoft.Office.Interop.Outlook.ContactItem contact) 2         { 3             InitializeComponent(); 4             this.name.Text = contact.LastName+" "+contact.FirstName; 5             this.phone.Text = contact.MobileTelephoneNumber; 6             this.email.Text = contact.Email1Address; 7             //获取自定义属性 8          this.father.Text = string.Format("{0}({1})", contact.UserProperties.Find("PROPERTY NAME FATHER NAME").Value, contact.UserProperties.Find("PROPERTY NAME FATHER BIRTHDAY").Value); 9             this.mother.Text = string.Format("{0}({1})", contact.UserProperties.Find("PROPERTY NAME MOTHER NAME").Value, contact.UserProperties.Find("PROPERTY NAME MOTHER BIRTHDAY").Value);10         }

  7.针对Unistall,我们有两种策略(第一部分提到)。

         一:删除注册表:第一部分提到过outlook加载插件时先检查注册表里的特定目录下的项。如果删除该项,outlook就不会检测到从而也就不会加载。代码如下:

 1 RegistryKey regKey = null; 2             RegistryKey regSubKey = null; 3             try 4             { 5                 //Read the key  6                 regKey = Microsoft.Win32.Registry.CurrentUser; 7                 //获取outlook插件目录下的子键 8                 regSubKey = regKey.OpenSubKey(string.Format(@"Software\Microsoft\Office\Outlook\Addins"), true); 9                 //获取当前插件名10                 regSubKey.DeleteSubKey(Assembly.GetExecutingAssembly().GetName().Name);11                 System.Windows.Forms.MessageBox.Show("插件卸载成功,下次启动生效!");12             }13             catch (Exception e)14             {15                 System.Windows.Forms.MessageBox.Show(e.Message);16             }

   二:禁用插件:由于第一种方法只是处理注册表,因此卸载的不是很彻底。还有很多遗留项。因此推荐使用第二种方法。使outlook将插件禁用,但保留在加载项栏中。想重用时可以手动启用。其相应的代码也很简单。

1             Microsoft.Office.Core.COMAddIn addin= Globals.ThisAddIn.Application.COMAddIns.Item("OutlookAddInDemo");2             addin.Connect = false; 

  

  到现在我们的实例已经完整的介绍完了,运行结果如图。完整工程源代码下载:http://files.cnblogs.com/maxliu/OutlookAddInDemo.rar

 

来自: http://www.migantech.com/blog/codes/2012/07/23/outlook-插件开发小结/
 
 
QQ 交流群:138178635 6休
  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值