outlook 插件:导出rss的link地址
由于对于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地址的更多相关文章
- 如何使用.NET开发全版本支持的Outlook插件产品(三)——全面控制
插件项目所有代码都已经上传至 https://github.com/VanPan/TestOutlookAdding 进阶基础--COM查看 首先,对于Outlook对象模型,MSDN早就有非常详细的 ...
- 如何使用.NET开发全版本支持的Outlook插件产品(一)——准备工作
这半年一直在做Outlook的插件,因为不会VC++,所以想找一款基于.NET,用C#开发Outlook插件的技术方案.没想到,光技术选型这件事,就用各种技术手段验证了将近一个月,还花费了大量的精力做 ...
- php不使用插件导出excel
php不使用插件导出excel的简单方法,首先获取需要导出的数据的数组,数组的格式在下面. 之后就是定义文件名称和需要导出的excel的样式,最后就是循环数组,输出数据了 代码: $filename= ...
- 最近给几个CRM软件配套开发了Outlook插件,讲讲Outlook插件开发注意事项
原始出处:www.cnblogs.com/Charltsing/p/OutlookAddinsTips.html联系QQ:564955427 从去年到现在,写了四五个Outlook插件,其中两个是给C ...
- Eclipse插件(导出UML图,打开文件资源管理器插件,静态代码分析工具PMD,在eclipse上安装插件)
目录 能够导出UML图的Eclipse插件 打开文件资源管理器插件 Java静态代码分析工具PMD 如何在eclipse上安装插件 JProfiler性能分析工具 从更新站点安装EclEmma 能够导 ...
- 自定义TexturePacker插件导出自己的plist文件
原地址:http://www.cppblog.com/sunicdavy/archive/2014/02/06/205645.html cocos2dx引擎使用plist文件, 一种特殊的xml格式作 ...
- jquery插件导出excel和pdf(解决中文乱码问题)
参考文件:http://jackyrong.iteye.com/blog/2169683 https://my.oschina.net/aruan/blog/418980 https://segmen ...
- jquery插件导出word:jquery.wordexport.js
前言 今天项目中遇到一个需求把我们系统中的统计数据导出来(主要是表格).其实实现的的方法有很多,而此次针对我的系统第一获取数据有点慢,加上前不久写了一个在线阅读pdf,故此这次也想用前端的方式来导出. ...
- 如何使用.NET开发全版本支持的Outlook插件产品(四)——进阶探讨
插件项目所有代码都已经上传至 https://github.com/VanPan/TestOutlookAdding 如何定制Ribbon在不同界面的显示 实际使用过程中出现的问题 这个问题的来自十分 ...
随机推荐
- linux 下RTL8723/RTL8188调试记录(命令行)【转】
本文转载自:http://blog.h5min.cn/wuhongxin123/article/details/41820877 本文是在正确安装好wifi驱动后对系统进行的配置. 1. 配置wp ...
- HDU2121 Ice_cream’s world II —— 最小树形图 + 不定根 + 超级点
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2121 Ice_cream’s world II Time Limit: 3000/1000 MS (J ...
- 2强类型DataSet (2011-12-30 23:16:59)转载▼ 标签: 杂谈 分类: Asp.Net练习笔记 http://blog.sina.com.cn/s/blog_9d90c4140101214w.html
强类型DataSet (2011-12-30 23:16:59) 转载▼ 标签: 杂谈 分类: Asp.Net练习笔记 using System; using System.Collections.G ...
- Linux 下的静态(函数)库、动态(函数)库
0. 基本 在命名上,静态库的名字一般是 libxxx.a,动态库的名字一般是 libxxx.so,有时 libxxx.so.major.minor,xxx 是该 lib 的名字,major 是主版本 ...
- nginx中查看关于php的配置和php-fpm的重启等操作
1.查看当前使用的php的配置信息 在php项目的根目录下新建findini.php文件,内容如下: <?php phpinfo(); ?> 然后在页面上访问就可以看到如下页面: 搜索Lo ...
- python 面向对象一 OOP
一.面向对象和面相过程 面向对象编程——Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数. 面 ...
- springboot(四)拦截器和全局异常捕捉
github代码:https://github.com/showkawa/springBoot_2017/tree/master/spb-demo/spb-brian-query-service 全部 ...
- LuoguP1606 [USACO07FEB]荷叶塘Lilypad Pond 【最短路】By cellur925
最短路好题!] 参考资料:学长 https://blog.csdn.net/TSOI_Vergil/article/details/52975779 学长太强了!!!%%% 题目传送门 ======= ...
- python代码覆盖率coverage简介与用法
如果衡量单元测试对相应代码的测试重量,覆盖率是一个必要非充分条件,因此统计代码的覆盖率,检视单测是否充分,就尤为的重要.这里针对python-unittest的单测的覆盖率coverage进行使用说明 ...
- Poj 3264 Balanced Lineup RMQ模板
题目链接: Poj 3264 Balanced Lineup 题目描述: 给出一个n个数的序列,有q个查询,每次查询区间[l, r]内的最大值与最小值的绝对值. 解题思路: 很模板的RMQ模板题,在这 ...