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

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

有需求,就找解决方案。

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

IDE:vs2010。

outlook:2007

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

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

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

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

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

step 6:开发前,加入必要的reference。因为我们开发的模型是通用的。所以需要增加outlook互操作的dll。默认位置在C:\Windows\assembly\GAC\Microsoft.Office.Interop.Outlook\12.0.0.0__71e9bce111e9429c\Microsoft.Office.Interop.Outlook.dll

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

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的目录。

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

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

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

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

step 14:试试看吧。

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

outlook 插件:导出rss的link地址的更多相关文章

  1. 如何使用.NET开发全版本支持的Outlook插件产品(三)——全面控制

    插件项目所有代码都已经上传至 https://github.com/VanPan/TestOutlookAdding 进阶基础--COM查看 首先,对于Outlook对象模型,MSDN早就有非常详细的 ...

  2. 如何使用.NET开发全版本支持的Outlook插件产品(一)——准备工作

    这半年一直在做Outlook的插件,因为不会VC++,所以想找一款基于.NET,用C#开发Outlook插件的技术方案.没想到,光技术选型这件事,就用各种技术手段验证了将近一个月,还花费了大量的精力做 ...

  3. php不使用插件导出excel

    php不使用插件导出excel的简单方法,首先获取需要导出的数据的数组,数组的格式在下面. 之后就是定义文件名称和需要导出的excel的样式,最后就是循环数组,输出数据了 代码: $filename= ...

  4. 最近给几个CRM软件配套开发了Outlook插件,讲讲Outlook插件开发注意事项

    原始出处:www.cnblogs.com/Charltsing/p/OutlookAddinsTips.html联系QQ:564955427 从去年到现在,写了四五个Outlook插件,其中两个是给C ...

  5. Eclipse插件(导出UML图,打开文件资源管理器插件,静态代码分析工具PMD,在eclipse上安装插件)

    目录 能够导出UML图的Eclipse插件 打开文件资源管理器插件 Java静态代码分析工具PMD 如何在eclipse上安装插件 JProfiler性能分析工具 从更新站点安装EclEmma 能够导 ...

  6. 自定义TexturePacker插件导出自己的plist文件

    原地址:http://www.cppblog.com/sunicdavy/archive/2014/02/06/205645.html cocos2dx引擎使用plist文件, 一种特殊的xml格式作 ...

  7. jquery插件导出excel和pdf(解决中文乱码问题)

    参考文件:http://jackyrong.iteye.com/blog/2169683 https://my.oschina.net/aruan/blog/418980 https://segmen ...

  8. jquery插件导出word:jquery.wordexport.js

    前言 今天项目中遇到一个需求把我们系统中的统计数据导出来(主要是表格).其实实现的的方法有很多,而此次针对我的系统第一获取数据有点慢,加上前不久写了一个在线阅读pdf,故此这次也想用前端的方式来导出. ...

  9. 如何使用.NET开发全版本支持的Outlook插件产品(四)——进阶探讨

    插件项目所有代码都已经上传至 https://github.com/VanPan/TestOutlookAdding 如何定制Ribbon在不同界面的显示 实际使用过程中出现的问题 这个问题的来自十分 ...

随机推荐

  1. 不同节点 IP 时间同步 分布式时间同步系统的参考时间获取技术分析

    linux linux下时间同步的两种方法分享_LINUX_操作系统_脚本之家 http://www.jb51.net/LINUXjishu/73979.html 分布式时间同步系统的参考时间获取技术 ...

  2. FunsionCharts Demo

    原文路径:http://www.cnblogs.com/xuhongfei/archive/2013/04/12/3016882.html 一.简介 Ø FusionCharts 是InfoSoft  ...

  3. Servlet8

    一.Annotation 进行配置不需要 web.xml 新建new Servlet 时,不需要在web.xml 文件中生成Servlet的相关信息 import java.io.IOExceptio ...

  4. YTU 2858: 编程题AB-骨牌铺方格

    2858: 编程题AB-骨牌铺方格 时间限制: 1 Sec  内存限制: 128 MB 提交: 87  解决: 23 题目描述 在2×n的一个长方形方格中,用一个1× 2的骨牌铺满方格,输入n ,输出 ...

  5. ubuntu LNMP环境下安装Redis,以及php的redis扩展

    1.下载 sudo wget http://download.redis.io/releases/redis-4.0.9.tar.gz 2.解压 sudo tar zvxf redis-4.0.9.t ...

  6. 一.C语言:关键字、标识符和注释

      一.关键字 C语言提供的有特殊含义的符号,共32个. 在Xcode中关键字全部高亮显示,关键字全部都为小写.如return.int等. 二.标识符 定义:标识符是程序员在程序中自定义的一些符号和名 ...

  7. BZOJ1266:上学路线route (最短路+最小割)

    可可和卡卡家住合肥市的东郊,每天上学他们都要转车多次才能到达市区西端的学校.直到有一天他们两人参加了学校的信息学奥林匹克竞赛小组才发现每天上学的乘车路线不一定是最优的. 可可:“很可能我们在上学的路途 ...

  8. Python实现跨文件全局变量的方法

    Python 中 global 关键字可以定义一个变量为全局变量,但是这个仅限于在一个模块(py文件)中调用全局变量,在另外一个py文件 再次使用 global x 也是无法访问到的,因为在这个py模 ...

  9. 将Mozilla ThunderBird最小化到系统托盘(转载)

    转自:http://be-evil.org/mozilla-thunderbird-minize-to-tray.html Mozilla ThunderBird是一款非常不错的邮件客户端,但是其在默 ...

  10. 第四代增强 NEW BADI的定义及实现

    NEW BADI 是在第四代增强框架下创建的BADI,是相对于第三代增强Classic Badi 而言的. 根据第四代增强的基本概念,所有显式增强Enhancement options 都必须放在增强 ...