qt8gt0bxhw|20009F4EEE83|RyanMain|subtext_Content|Text|0xfbff320100000000ac00000001000700
Internet Explorer 7 introduced the Windows RSS Platform. The Windows RSS Platform will be a core part of Windows Vista, but with IE7 it is now avilable on XP as well. The new functionality in IE7 to consume RSS feeds is made capable by the Windows RSS platform. This new functionality exists in Outlook 2007 also, giving you the ability to consume RSS feeds in Outlook folders ala Newsgator style, which can also synchronize with the Windows RSS Platform.
What makes this all so cool is that you now have the ability to have a single common store for subscribed RSS feeds. Well, this is the goal I suppose, although it will take some time for RSS Reader vendors to switch over - if that ever happens. Newsgator/FeedDemon has a utility for synching the Newsgator online feed store with the Windows RSS Platform.
Accessing the Windows RSS Platform is a simple task. The RSS Platform is exposed by a COM-based API found in msfeeds.dll (in the System32 directory). Add a reference to the COM dll and add a using directive for the namespace in the generated interop assembly and it's all easy work to use. Although, do keep in mind that this is a COM based reference so you'll need to take care to properly release all objects.
Let's say we want to populate a TreeView control with the feeds found in the local RSS store. An easy enough task, take a look:
using System.Runtime.InteropServices;
using Microsoft.Feeds.Interop;
//..
private void loadFeeds()
{
TreeNode rootnode = treeView1.Nodes.Add("Feeds");
IFeedsManager feedmgr = null;
IFeedFolder rootfolder = null;
try
{
// instanciate a new FeedManager
feedmgr = new FeedsManagerClass();
// get reference to the root feed store folder
// there is always a root
rootfolder = (IFeedFolder)feedmgr.RootFolder;
// call method to recursively add subfolders and feeds to treeview
addNode(rootnode, rootfolder);
treeView1.ExpandAll();
}
finally
{
Marshal.ReleaseComObject(rootfolder);
Marshal.ReleaseComObject(feedmgr);
}
}
private void addNode(TreeNode parentnode, IFeedFolder folder)
{
// check to see if the current folder has subfolders
if (folder.Subfolders != null)
{
foreach (IFeedFolder subfolder in (IFeedsEnum)folder.Subfolders)
{
TreeNode foldernode = parentnode.Nodes.Add(subfolder.Name);
// recursively add subfolders under current folder
addNode(foldernode, subfolder);
}
}
// if current folder has feeds add them under the folder node
if (folder.Feeds != null)
{
foreach (IFeed feed in (IFeedsEnum)folder.Feeds)
{
TreeNode feednode = parentnode.Nodes.Add(feed.Name);
feednode.Tag = feed;
}
}
}
Once you've gotten the list of feeds it is just as easy to get the items from a feed. In the example above I placed a reference to the feed in the tag of the TreeNode objects. Let's grab that on the TreeView's AfterSelect event and get the items from the feed to fill a ListView.
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
{
listView1.Items.Clear();
if (e.Node.Tag != null)
{
IFeed feed = e.Node.Tag as IFeed;
if (feed != null)
{
foreach (IFeedItem item in (IFeedsEnum)feed.Items)
{
ListViewItem li = new ListViewItem();
li.Text = item.Title;
li.SubItems.Add(item.PubDate.ToShortDateString());
if (!item.IsRead) li.Font = new Font(li.Font, FontStyle.Bold);
li.Tag = item;
listView1.Items.Add(li);
}
}
}
}
So now as a last task, when an item in the ListView is selected let's display the text for the item in a webbrowser control.
private void listView1_SelectedIndexChanged(object sender, EventArgs e)
{
if (listView1.SelectedItems.Count > 0 && listView1.SelectedItems[0].Tag != null)
{
ListViewItem li = listView1.SelectedItems[0];
IFeedItem item = li.Tag as IFeedItem;
if (item != null)
{
// let's mark the item as read
item.IsRead = true;
li.Font = new Font(li.Font, FontStyle.Regular);
// set the item's text in the webbrowser
webBrowser1.DocumentText = item.Description;
}
}
}
So, that's easy enough. Just as easy to do other things as well, such as add a new feed to the local store.
private void addRyanFarleysFeed() // ;-)
{
IFeedsManager feedmgr = null;
IFeedFolder rootfolder = null;
IFeedFolder folder = null;
IFeed feed = null;
try
{
// instanciate a new FeedManager
feedmgr = new FeedsManagerClass();
// get reference to the root feed store folder
rootfolder = (IFeedFolder)feedmgr.RootFolder;
// if we wanted to add the feed to an existing folder in the store
// we could use the following (for example, if we wanted to store
// the feed in a folder called "My Feeds")
folder = (IFeedFolder)rootfolder.GetSubFolder("My Feeds");
// if you didn't want to add it in a subfolder (ie: in the root instead)
// then you'd just use the reference to the root folder
feed = (IFeed)folder.CreateFeed("{ public virtual blog; }", "http://ryanfarley.com/blog/rss.aspx");
// now force an async download of the items in the feed
feed.AsyncDownload();
}
finally
{
Marshal.ReleaseComObject(feed);
Marshal.ReleaseComObject(folder);
Marshal.ReleaseComObject(rootfolder);
Marshal.ReleaseComObject(feedmgr);
}
}
So now in the course of about 10 minutes you've created your own simple RSS Reader that uses the Windows RSS Platform as the backend. Here's a screenshot of the sample I threw together using the same code I outlined above:
(click for larger view)
There's a whole lot more the Feed API can do, including downloading enclosures and more.