zoukankan      html  css  js  c++  java
  • outlook 插件:导出rss的link地址

    由于对于rss的应用程序不熟悉,所以使用Outlook接收rss。使用过程和平时收邮件没有什么差别。

    唯一的遗憾是鉴于安全考虑,outlook没有全部下载网页,所以每次都要打开浏览器。有时候遇到一些需要详细阅读或要收藏的(比如我预备加入pocket)都要走一遍浏览器。网页多了,就感觉有些烦人了。

    有需求,就找解决方案。

    我的方案:创建一个outlook的插件,保存需要的网址。

    IDE:vs2010。

    outlook:2007

    step 1:创建项目,名称RssLinkExport. 请注意我没有选择c#节点下的outlook插件类型。采用通用的插件模型,这样可以更好控制outlook。

    proj-type

    step 2:选择目标对象Microsoft OutLook。这个是必须的,关系到注册表的设定。

    wiz-2

    step 3:给插件起一个名称,这是给outlook用户看的。

    wiz-3

    step 4:决定安装程序用户是否共享这个组件。建议全部勾选。省得用的时候要重启一下。

    wiz-4

    step 5:汇总信息,finish即可。

    wiz-5

    step 6:开发前,加入必要的reference。因为我们开发的模型是通用的。所以需要增加outlook互操作的dll。默认位置在C:WindowsassemblyGACMicrosoft.Office.Interop.Outlook12.0.0.0__71e9bce111e9429cMicrosoft.Office.Interop.Outlook.dll

    ref-wiz

    step 7:检查是否加入成功Microsoft.Office.Interop.Outlook。

    add-ref 

    step 8: 写代码了。由于代码不多,就都写在Connect类里面了。

    申明变量

    private string rssEntryID; // 用于识别rss目录,按照outlook开发,每个对象都有一个id。
    private Microsoft.Office.Interop.Outlook.Application app; // 缓存outlook的对象
    CommandBarButton exportBtn; // 控件
    Regex reUrl; // 正则对象,筛选url。

    初始化

    public Connect()
    {     

    rssEntryID = null;    
         // 初始化正则表达式。至于为什么要这样写,可以参考rss的数据格式。
         reUrl = new Regex("HREF="(?<key>http:[^"]+)"", RegexOptions.Compiled);
    }
    缓存application对象
    public void OnConnection(object application, Extensibility.ext_ConnectMode connectMode, object addInInst, ref System.Array custom)
    {
        applicationObject = application;
        addInInstance = addInInst;

    // 在启动阶段,缓存应用的对象。如果您熟悉com开发,应该对此很熟悉。
        app = application as Microsoft.Office.Interop.Outlook.Application;
    }
     
    增加工具栏的按钮,需要的时候触发保存。
    public void OnStartupComplete(ref System.Array custom)
    {
        // save rss   ID
         Microsoft.Office.Interop.Outlook.MAPIFolder rssFolder = app.ActiveExplorer().Session.GetDefaultFolder(OlDefaultFolders.olFolderRssFeeds); 
         rssEntryID = rssFolder.EntryID;
         CommandBars commandBars = app.ActiveExplorer().CommandBars;    

    // 判断:万一插件有异常,之前新增控件没有移除的话,就不需要新增了。
         foreach (CommandBarControl control in commandBars["Standard"].Controls)
         {     
             if (control.Caption == "export")
             {                         
                   exportBtn = control as CommandBarButton;  
                   break;
             }
        }
        if (exportBtn == null)
        {
             exportBtn = (CommandBarButton)commandBars["Standard"].Controls.Add(1

    , System.Reflection.Missing.Value

    , System.Reflection.Missing.Value

    , System.Reflection.Missing.Value

    , System.Reflection.Missing.Value);
             exportBtn.Caption = "export";    
        }
        exportBtn.Click += new _CommandBarButtonEvents_ClickEventHandler(exportBtn_Click);
    }
     
    移除control
    public void OnBeginShutdown(ref System.Array custom)  
    {

    // 程序退出前,销毁新增的控件。
         if (exportBtn != null)             
         {
                 exportBtn.Delete(System.Reflection.Missing.Value);
                 exportBtn = null;             
         }
    }
    触发事件
     void exportBtn_Click(CommandBarButton Ctrl, ref bool CancelDefault)         
    {
     
         List<string> urls = new List<string>();
          // 检查当前目录是否rss   
         Microsoft.Office.Interop.Outlook.MAPIFolder selectedFolder = app.ActiveExplorer().CurrentFolder;                 
         Microsoft.Office.Interop.Outlook.MAPIFolder parentFolder = selectedFolder.Parent as Microsoft.Office.Interop.Outlook.MAPIFolder;                 
         if (parentFolder == null) return;                                               
         if (rssEntryID == null || rssEntryID.Equals(parentFolder.EntryID) == false) return;                 
         // 获取界面操作后,选择的对象列表。selection是office的对象。                
         Selection selectdItems = app.ActiveExplorer().Selection;                 
         if (selectdItems == null) return;                 
         foreach (object objSelected in selectdItems)                 
         {                     
               // 转换成PostItem
               Microsoft.Office.Interop.Outlook.PostItem pItem = objSelected as Microsoft.Office.Interop.Outlook.PostItem;                     
               if (pItem == null) continue;                     
               // 获取格式,这是防御性编码,因为我常用的rss对象都是html的。
               OlBodyFormat bodyFmt = pItem.BodyFormat;                     
               string pItemBody = null;                     
               if (bodyFmt == OlBodyFormat.olFormatHTML)                     
               {                         
                 pItemBody = pItem.HTMLBody;                     
               }                     
               else                     
               {                         
                 pItemBody = pItem.Body;                     
               }                     
               // 导出的对象标注蓝色分类,我并没有删除。所以如果已经标注就说明曾经导出过了。                       
               if (pItem.Categories == null)                     
               {                         
                  pItem.Categories = "Blue Category";                         
                  // 这步很关键。否则outlook不会立即刷新界面。                              
                  pItem.Save();                         
                  // 获取url地址                          
                  Match urlMa = reUrl.Match(pItemBody);                         
                  if (urlMa.Success)                         
                  {                             
                    urls.Add(urlMa.Groups["key"].ToString());                         
                  }                     
               }                 
         }                 
         // 把全部url保存到我的文件夹。                               
         if (urls.Count > 0)                 
         {                     
            string baseFolder = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);                     
            string targetFolder = string.Format("{0}\bel", baseFolder);                     
            DirectoryInfo di = new DirectoryInfo(targetFolder);                     
            if (di.Exists == false)                     
            {                         
               di.Create();                     
            }                     
            DateTime dtNow = DateTime.Now;                     
            string targetFile = string.Format("{0}\urls_{1}{2}{3}.txt", targetFolder, dtNow.Year, dtNow.Month, dtNow.Day);                     
            StreamWriter sw = new StreamWriter(targetFile, true);                     
            foreach (string url in urls)                     
            {                         
              sw.WriteLine(url);                     
            }                     
            sw.Close();       
            // 这时候你应该看到url的文本了。         
         }

    }


    step 9:调试。默认的外部程序是vs2010,所以你有必要指向outlook的目录。

    debug

    step 10:插件成功load后,界面显示的控件--“export”。

    outlook-view

    step 11:单击export后,选择的item会显示蓝色分类。

    btn-click

    step 12:vs2010会自动创建发布包,但默认情况不会build,你需要手工build。

    setup-proj

    step 13:这是成功创建的安装程序。

    setup-file

    step 14:试试看吧。

    最后感谢施向阳同学的正则表达式技术支持。

  • 相关阅读:
    javascript中单体模式的实现
    javascript中的继承实现
    如何改变String类的值,保证地址不变!
    测试题答案
    Springboot实现文件(头像)上传
    关于处理登录,到底用拦截器还是过滤器
    关于Spring MVC中的406错误
    SSM开发过程Bug集锦
    String类型日期自动转Date数据类型
    spring的核心配置文件——ApplicationContext.xml的配置
  • 原文地址:https://www.cnblogs.com/febwave/p/4142469.html
Copyright © 2011-2022 走看看