<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" media="screen" href="/styles/xslt/rss.xslt"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:c9="http://channel9.msdn.com">
<channel>
	<title>Channel 9</title>
    <atom:link rel="self" type="application/rss+xml" href="http://channel9.msdn.com/Niners/c4f.Sean-Campbell/Posts/RSS"></atom:link>
    <itunes:summary></itunes:summary>
    <itunes:author>Microsoft</itunes:author>
    <itunes:subtitle></itunes:subtitle>
    <image>
      <url>http://mschnlnine.vo.llnwd.net/d1/Dev/App_Themes/C9/images/feedimage.png</url>
      <title>Channel 9</title>
      <link>http://channel9.msdn.com/Niners/c4f.Sean-Campbell/Posts</link>
    </image>
    <itunes:image href=""></itunes:image>
    <itunes:category text="Technology"></itunes:category>
    <description>Channel 9 keeps you up to date with the latest news and behind the scenes info from Microsoft that developers love to keep up with. From LINQ to SilverLight – Watch videos and hear about all the cool technologies coming and the people behind them.</description>
    <link>http://channel9.msdn.com/Niners/c4f.Sean-Campbell/Posts</link>
    <language>en</language>
    <pubDate>Thu, 23 May 2013 12:32:39 GMT</pubDate>
    <lastBuildDate>Thu, 23 May 2013 12:32:39 GMT</lastBuildDate>
    <generator>Rev9</generator>
    <c9:totalResults>6</c9:totalResults>
    <c9:pageCount>1</c9:pageCount>
    <c9:pageSize>25</c9:pageSize>
  <item>
      <title>Creating a Research Helper</title>
      <description><![CDATA[<span id="c4fmetadata">
<table border="0" cellpadding="1" cellspacing="0" width="100%">
<tbody>
<tr class="entry_overview">
<td width="50">&nbsp;</td>
<td><span class="entry_description">This is a tool that searches a variety of search engines with a keystroke.</span></td>
</tr>
<tr>
<td colspan="2">
<div class="entry_author">Sean Campbell</div>
<div class="entry_company"><a href="http://www.3leafdev.com/Home.aspx">3 Leaf Development</a></div>
<br>
<div class="entry_details"><b>Difficulty: </b><span class="entry_details_input">Intermediate</span></div>
<div class="entry_details"><b>Time Required:</b> <span class="entry_details_input">
1-3 hours</span></div>
<div class="entry_details"><b>Cost: </b><span class="entry_details_input">Free</span></div>
<div class="entry_details"><b>Software: </b><span class="entry_details_input"><a href="http://msdn.com/express/">Visual Studio Express Editions</a></span></div>
<div class="entry_details"><b>Hardware: </b><span class="entry_details_input"></span></div>
<div class="entry_details"><b>Download: </b>Lost!
</div>
</td>
</tr>
</tbody>
</table>
</span>
<p>I like productivity at my fingertips, so for this post, I'm going to walk through a tool that I've created to save time for online researching.&nbsp; This tool can be made to launch by simply using a shortcut key while you're in any application.
</p>
<h5>ResearchHelp</h5>
<p>One common task is to look up some term in a variety of search engines.&nbsp; For example, I might come across the phrase &quot;Visual Studio Team System&quot;.&nbsp; Often I search Google to find the key sites, Google Groups to see what people are saying about it in the newsgroups,
 Feedster to get the recent buzz from the blogs, etc.&nbsp; To facilitate searching quickly, I put together a simple utility that I can also launch from a key stroke.&nbsp; With a simple CTRL&#43;C to copy the phrase, and CTRL&#43;SHIFT&#43;Y, I can get the following:
</p>
<p><img src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/914147/Produc1.gif" width="485">
</p>
<p>This application dynamically creates tabs for my configured search engines, and then uses the new WebBrowser control to display the results.&nbsp; Dissecting this application shows a number of the new features in Visual Studio 2005. I'll use Visual C# 2005 Express
 Edition for this example. Depending on the language I wanted, I could have used any of the Visual Studio Express Editions to create a similar sample. Beta 2 of the Express editions can be downloaded from
<a href="http://msdn.microsoft.com/express">http://msdn.microsoft.com/express</a>.&nbsp;
</p>
<p>First, the form is divided into two sections using the new SplitContainer control.&nbsp; This control is a combination of 2 panels, and a splitter.&nbsp; It's much easier to work with than the Visual Studio .NET 2003 Splitter control, which got tricky depending on
 the order in which you added the panels and splitter to the form. </p>
<p>The top panel contains a section that lets you enter the search information.&nbsp; This is populated by default with whatever's in the clipboard.
</p>
<p>Next, you see the new ToolStrip control.&nbsp; This control makes it trivial to set up professional &quot;Office&quot; style toolbars, that support docking, floating, repositioning, and other features.&nbsp; This toolbar just has a couple of buttons on it, but you can also
 add drop-downs, text boxes, labels, and a variety of other controls.&nbsp; To wire up code for an item on the toolbar, you simply double-click it in the designer.&nbsp; This ToolStrip contains two buttons.&nbsp; The first will open the currently selected page in a new browser
 window, which is useful when you've found something interesting, and you want the full features of Internet Explorer.&nbsp; The second button provides simple &quot;Back&quot; button functionality.
</p>
<p>Below the toolbar is a Tab control.&nbsp; The tabs are actually created at run-time when the search is performed, and a WebBrowser control is added to each tab to display the results.
</p>
<p>The code for this application was very straightforward to write.&nbsp; First, the application contains a list of configured search engines using a custom SearchInfo class:
</p>
<p><b>Visual C#</b></p>
<pre class="csharpcode"><span class="kwrd">private</span> SearchInfo[] searches = { <br>    <span class="kwrd">new</span> SearchInfo(<span class="str">&quot;Google Web&quot;</span>, <span class="str">&quot;http://www.google.com/search?q=&quot;</span>),<br>    <span class="kwrd">new</span> SearchInfo(<span class="str">&quot;Google Groups&quot;</span>, <span class="str">&quot;http://groups-beta.google.com/groups?q=&quot;</span>),<br>    <span class="kwrd">new</span> SearchInfo(<span class="str">&quot;Google News&quot;</span>, <span class="str">&quot;http://news.google.com/news?q=&quot;</span>),<br>    <span class="kwrd">new</span> SearchInfo(<span class="str">&quot;Feedster&quot;</span>, <span class="str">&quot;http://www.feedster.com/search.php?q=&quot;</span>),<br>    <span class="kwrd">new</span> SearchInfo(<span class="str">&quot;Technorati&quot;</span>, <br>        <span class="str">&quot;http://www.technorati.com/cosmos/search.html?rank=&amp;url=&quot;</span>)<br>};</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre class="csharpcode"><span class="kwrd">Private</span> searches <span class="kwrd">As</span> SearchInfo() = { _<br>    <span class="kwrd">New</span> SearchInfo(<span class="str">&quot;Google Web&quot;</span>, <span class="str">&quot;http://www.google.com/search?q=&quot;</span>), _<br>    <span class="kwrd">New</span> SearchInfo(<span class="str">&quot;Google Groups&quot;</span>, <span class="str">&quot;http://groups-<br>        beta.google.com/groups?q=&quot;</span>), _<br>    <span class="kwrd">New</span> SearchInfo(<span class="str">&quot;Google News&quot;</span>, <span class="str">&quot;http://news.google.com/news?q=&quot;</span>), _<br>    <span class="kwrd">New</span> SearchInfo(<span class="str">&quot;Feedster&quot;</span>, <span class="str">&quot;http://www.feedster.com/search.php?q=&quot;</span>), _<br>    <span class="kwrd">New</span> SearchInfo(<span class="str">&quot;Technorati&quot;</span>, <br>        <span class="str">&quot;http://www.technorati.com/cosmos/search.html?rank=&amp;url=&quot;</span>) _<br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>If you have other search engines that you want to use, you can just add them here.
</p>
<p>The Form_Load event does a couple of things.&nbsp; First, it registers a shortcut for the application:
</p>
<p><b>Visual C#</b></p>
<pre class="csharpcode"><span class="kwrd">string</span> shortcutPath = <br>     Environment.GetFolderPath(Environment.SpecialFolder.Programs) <br>     &#43; <span class="str">@&quot;\ResearchHelp.lnk&quot;</span>;<br><span class="kwrd">if</span> (!System.IO.File.Exists(shortcutPath))<br>{<br>    WshShell shell = <span class="kwrd">new</span> WshShell();<br>    IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(shortcutPath);<br>    shortcut.Hotkey = <span class="str">&quot;CTRL&#43;SHIFT&#43;Y&quot;</span>;<br>    shortcut.TargetPath = Assembly.GetExecutingAssembly().Location;<br>    shortcut.Description = <span class="str">&quot;ResearchHelp&quot;</span>;<br>    shortcut.Save();<br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre class="csharpcode"><span class="kwrd">Dim</span> shortcutPath <span class="kwrd">As</span> <span class="kwrd">String</span> = _<br>     Environment.GetFolderPath(Environment.SpecialFolder.Programs) _<br>     &amp; <span class="str">&quot;\ResearchHelp.lnk&quot;</span><br><span class="kwrd">If</span> <span class="kwrd">Not</span> System.IO.File.Exists(shortcutPath) <span class="kwrd">Then</span><br>    <span class="kwrd">Dim</span> shell <span class="kwrd">As</span> WshShell = <span class="kwrd">New</span> WshShell()<br>    <span class="kwrd">Dim</span> shortcut <span class="kwrd">As</span> IWshShortcut = <br>        <span class="kwrd">CType</span>(shell.CreateShortcut(shortcutPath), IWshShortcut)<br>    shortcut.Hotkey = <span class="str">&quot;CTRL&#43;SHIFT&#43;Y&quot;</span><br>    shortcut.TargetPath = <span class="kwrd">Assembly</span>.GetExecutingAssembly().Location<br>    shortcut.Description = <span class="str">&quot;ResearchHelp&quot;</span><br>    shortcut.Save()<br><span class="kwrd">End</span> If</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>And then, some new methods on the Clipboard class are used to see if the Clipboard contains a search string:
</p>
<p><b>Visual C#</b></p>
<pre class="csharpcode"><span class="kwrd">if</span> (Clipboard.ContainsText)<br>{<br>    topicTextBox.Text = Clipboard.GetText();<br>}<br></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre class="csharpcode"><span class="kwrd">If</span> Clipboard.ContainsText() <span class="kwrd">Then</span><br>    topicTextBox.Text = Clipboard.GetText()<br><span class="kwrd">End</span> <span class="kwrd">If</span>
</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>You can see that this makes it very simple to see if the clipboard contains data in a certain format, and then extract that data in a more strongly typed way.
</p>
<p>When the search button is clicked, the application iterates through all the SearchInfo objects, and creates corresponding tabs and WebBrowser instances to show the results.&nbsp; With the new WebBrowser control in Visual Studio 2005, you can see that the browser
 is simple to work with: </p>
<p><b>Visual C#</b></p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> searchButton_Click(<span class="kwrd">object</span> sender, EventArgs e)<br>{<br>    searchTab.Controls.Clear();<br>    <span class="kwrd">foreach</span> (SearchInfo si <span class="kwrd">in</span> searches)<br>    {<br>        TabPage tp = <span class="kwrd">new</span> TabPage(si.Description);<br>        WebBrowser wb = <span class="kwrd">new</span> WebBrowser();<br>        searchTab.Controls.Add(tp);<br>        tp.Controls.Add(wb);<br>        wb.Dock = DockStyle.Fill;<br>        wb.ScriptErrorsSuppressed = <span class="kwrd">true</span>;<br>        wb.Navigate(si.BaseURL &#43; topicTextBox.Text);<br>    }<br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre class="csharpcode"><span class="kwrd">Private</span> <span class="kwrd">Sub</span> searchButton_Click(<span class="kwrd">ByVal</span> sender <span class="kwrd">As</span> System.<span class="kwrd">Object</span>, _<br>     <span class="kwrd">ByVal</span> e <span class="kwrd">As</span> System.EventArgs) <span class="kwrd">Handles</span> searchButton.Click<br>    searchTab.Controls.Clear()<br>    <span class="kwrd">For</span> <span class="kwrd">Each</span> si <span class="kwrd">As</span> SearchInfo <span class="kwrd">In</span> searches<br>        <span class="kwrd">Dim</span> tp <span class="kwrd">As</span> TabPage = <span class="kwrd">New</span> TabPage(si.Description)<br>        <span class="kwrd">Dim</span> wb <span class="kwrd">As</span> WebBrowser = <span class="kwrd">New</span> WebBrowser()<br>        searchTab.Controls.Add(tp)<br>        tp.Controls.Add(wb)<br>        wb.Dock = DockStyle.Fill<br>        wb.ScriptErrorsSuppressed = <span class="kwrd">True</span><br>        wb.Navigate(si.BaseURL &amp; topicTextBox.Text)<br>    <span class="kwrd">Next</span><br><span class="kwrd">End</span> Sub</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>The TabPage objects are added to the TabControl, and then the WebBrowser objects are added to each tab.&nbsp; Each browser is set to DockStyle.Fill to fill the available tab space.&nbsp; Finally, the Navigate method is used to perform the actual search and show the
 results.&nbsp; Navigate is an asynchronous method, so all the browser instances can be searching in parallel.
</p>
<h4>Conclusion</h4>
<p>Visual Studio 2005 made it trivial for me to create a utility that I now use all the time.&nbsp; New controls like the SplitContainer, ToolStrip, and WebBrowser made it very quick to put together an easy-to-use interface.&nbsp; Enhancements to the Clipboard class
 make it more intuitive to use, and the WebBrowser is a nice managed wrapper around the browser control. Get started today by downloading one of the Visual Studio 2005 Express Editions from http://msdn.microsoft.com/express.
</p>
<p><b>Parting tip: </b>I'm a big fan of hot-keys instead of mouse clicks.&nbsp; When I'm writing code, I like to keep my hands on the keyboard.&nbsp; One thing that I often do in Visual Studio is CTRL&#43;TAB to switch between my open code windows.&nbsp; It was an interesting
 surprise to see that even this has been enhanced.&nbsp; When I CTRL-TAB now, the following window opens in Visual Studio to make it easy to pick exactly the file I want:
</p>
<p><img src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/914147/Produc2.gif" border="0" height="333" width="354"></p>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/c4f.Sean-Campbell/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:d8b4603bd9a2444aaa229e7600da60a2">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Creating-a-Research-Helper</comments>
      <itunes:summary>



&amp;nbsp;
This is a tool that searches a variety of search engines with a keystroke.



Sean Campbell
3 Leaf Development

Difficulty: Intermediate
Time Required: 
1-3 hours
Cost: Free
Software: Visual Studio Express Editions
Hardware: 
Download: Lost!






I like productivity at my fingertips, so for this post, I&#39;m going to walk through a tool that I&#39;ve created to save time for online researching.&amp;nbsp; This tool can be made to launch by simply using a shortcut key while you&#39;re in any application.
 
ResearchHelp
One common task is to look up some term in a variety of search engines.&amp;nbsp; For example, I might come across the phrase &amp;quot;Visual Studio Team System&amp;quot;.&amp;nbsp; Often I search Google to find the key sites, Google Groups to see what people are saying about it in the newsgroups,
 Feedster to get the recent buzz from the blogs, etc.&amp;nbsp; To facilitate searching quickly, I put together a simple utility that I can also launch from a key stroke.&amp;nbsp; With a simple CTRL&amp;#43;C to copy the phrase, and CTRL&amp;#43;SHIFT&amp;#43;Y, I can get the following:
 

 
This application dynamically creates tabs for my configured search engines, and then uses the new WebBrowser control to display the results.&amp;nbsp; Dissecting this application shows a number of the new features in Visual Studio 2005. I&#39;ll use Visual C# 2005 Express
 Edition for this example. Depending on the language I wanted, I could have used any of the Visual Studio Express Editions to create a similar sample. Beta 2 of the Express editions can be downloaded from
http://msdn.microsoft.com/express.&amp;nbsp;
 
First, the form is divided into two sections using the new SplitContainer control.&amp;nbsp; This control is a combination of 2 panels, and a splitter.&amp;nbsp; It&#39;s much easier to work with than the Visual Studio .NET 2003 Splitter control, which got tricky depending on
 the order in which you added the panels and splitter to the form.  
The top panel contains a section that lets you enter the search information</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Creating-a-Research-Helper</link>
      <pubDate>Tue, 31 Oct 2006 16:49:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Creating-a-Research-Helper</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/914147_100.jpg" height="75" width="100"></media:thumbnail>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/914147_220.jpg" height="165" width="220"></media:thumbnail>      
      <dc:creator>Sean Campbell</dc:creator>
      <itunes:author>Sean Campbell</itunes:author>
      <slash:comments>4</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Creating-a-Research-Helper/RSS</wfw:commentRss>
    </item>
  <item>
      <title>Building Network Utilities</title>
      <description><![CDATA[<span id="c4fmetadata">
<table border="0" cellspacing="0" cellpadding="1" width="100%">
<tbody>
<tr class="entry_overview">
<td width="50">&nbsp;</td>
<td><span class="entry_description">This is a simple utility that will look for devices on the network.</span></td>
</tr>
<tr>
<td colspan="2">
<div class="entry_author">Sean Campbell</div>
<div class="entry_company"><a href="http://www.3leafdev.com/Home.aspx">3 Leaf Development</a></div>
<br>
<div class="entry_details"><b>Difficulty: </b><span class="entry_details_input">Easy</span></div>
<div class="entry_details"><b>Time Required:</b> <span class="entry_details_input">
1-3 hours</span></div>
<div class="entry_details"><b>Cost: </b><span class="entry_details_input">Free</span></div>
<div class="entry_details"><b>Software: </b><span class="entry_details_input"><a href="http://msdn.com/express/">Visual Studio Express Editions</a></span></div>
<div class="entry_details"><b>Hardware: </b></div>
<div class="entry_details"><strong></strong><span class="entry_details_input"></span>&nbsp;</div>
<div class="entry_details"><strong>Source Code:</strong> Lost!!!&nbsp; But check out this
<a href="http://blogs.msdn.com/coding4fun/archive/2007/04/22/2241600.aspx">article which shows off how to do network discovery using simular methods</a>.
<ul>
</ul>
</div>
</td>
</tr>
</tbody>
</table>
</span>
<p>&nbsp;</p>
<p>For this first post, I've decided to dig into the new System.Net.NetworkInformation namespace, and build a simple utility that will look for devices on the network:
</p>
<p><img src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/914076/tweak_1.jpg" width="300" height="300">
</p>
<p>This gave me the opportunity to explore a number of new features in Visual Studio 2005 by using Visual C# Express Edition. Depending on the language I wanted, I could have used any of the Visual Studio Express Editions for this sample. Beta 2 of the Express
 editions can be downloaded from <a href="http://msdn.microsoft.com/express">http://msdn.microsoft.com/express</a>. &nbsp;
</p>
<p>The core of this application is the new Ping class (System.Net.NetworkInformation.Ping).&nbsp; This gives you built-in functionality for sending an ICMP echo request to a network device.
</p>
<p><b>Visual C#</b></p>
<pre class="csharpcode">IPAddress ip = IPAddress.Parse(<span class="str">&quot;192.168.1.1&quot;</span>);<br>Ping ping = <span class="kwrd">new</span> Ping();<br>PingReply pr = ping.Send(ip);</pre>
<style type="text/css">
<!--
.csharpcode
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	margin:0em;
	width:100%}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre class="csharpcode">IPAddress ip = IPAddress.Parse(<span class="str">&quot;192.168.1.1&quot;</span>)<br><span class="kwrd">Dim</span> newPing <span class="kwrd">As</span> Ping = <span class="kwrd">New</span> Ping()<br><span class="kwrd">Dim</span> pr <span class="kwrd">As</span> PingReply = newPing.Send(ip)</pre>
<style type="text/css">
<!--
.csharpcode
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	margin:0em;
	width:100%}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>You can see that the .NET Framework 2.0 makes it trivial to ping a network device.&nbsp; Prior to the .NET Framework 2.0, it was
<a href="http://www.csharphelp.com/archives/archive6.html">substantially more code</a> to accomplish this.
</p>
<p>In addition, I wanted to make this asynchronous so that the pings were being done in the background, and the UI was not blocked, and updated as the results came in.&nbsp; Also, because there could potentially be a very large number of IP addresses, I didn't want
 to fire off pings for <i>all</i> of them at the same time.&nbsp; For my testing, having about 200 pings going at the same time worked well.
</p>
<p>Letting 200 pings go at one time turned out to be trivial to perform using the semaphore class.&nbsp; Here's how it works:
</p>
<p>First, you declare the semaphore class with the maximum number of threads you want to allow.&nbsp; In this case that's 200:
</p>
<p><b>Visual C#</b></p>
<pre class="csharpcode"><span class="kwrd">const</span> <span class="kwrd">int</span> THREAD_COUNT = 200;<br><span class="kwrd">private</span> Semaphore pingBlock = <span class="kwrd">new</span> Semaphore(0, THREAD_COUNT);<br>pingBlock.Release(THREAD_COUNT);</pre>
<style type="text/css">
<!--
.csharpcode
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	margin:0em;
	width:100%}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre class="csharpcode"><span class="kwrd">const</span> int THREAD_COUNT = 200;<br><span class="kwrd">private</span> Semaphore pingBlock = <span class="kwrd">new</span> Semaphore(0, THREAD_COUNT);<br>pingBlock.Release(THREAD_COUNT);</pre>
<style type="text/css">
<!--
.csharpcode
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	margin:0em;
	width:100%}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Now, when the application wants to spawn a new thread to perform a ping, it uses the semaphore to insure that there aren't already 200 pings running.&nbsp; The code can do this as follows:
</p>
<p><b>Visual C#</b></p>
<pre class="csharpcode">pingBlock.WaitOne();</pre>
<style type="text/css">
<!--
.csharpcode
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	margin:0em;
	width:100%}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre class="csharpcode">pingBlock.WaitOne()</pre>
<style type="text/css">
<!--
.csharpcode
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	margin:0em;
	width:100%}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	margin:0em;
	width:100%}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>This call allocates an item in the semaphore.&nbsp; If all 200 are already allocated, then this call will block until one of the items is released.&nbsp; Once WaitOne returns, this thread is unblocked, and can perform the ping.&nbsp; Once the ping has completed, the thread
 needs to release the semaphore object so that another thread can unblock and do its ping.&nbsp; This repeats until all the pings are completed.&nbsp; A semaphore object is released as follows:
</p>
<p><b>Visual C#</b></p>
<pre class="csharpcode">pingBlock.Release();</pre>
<style type="text/css">
<!--
.csharpcode
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	margin:0em;
	width:100%}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre class="csharpcode">pingBlock.Release()</pre>
<style type="text/css">
<!--
.csharpcode
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	margin:0em;
	width:100%}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>To handle all the ping operations, I created a class called &quot;NetScan&quot;.&nbsp; To kick off a set of pings, you call the NetScan.Start method, and pass in the range of IP addresses that you want it to loop through.&nbsp; NetScan handles all the background threads, and
 fires events when each ping has completed, and another event when all of the pings are done.&nbsp; In the .NET Framework 2.0, the syntax for declaring an event is much simpler.&nbsp; In the past, you had to declare a delegate, and an event.&nbsp; Now, you just use the generic
 EventHandler&lt;T&gt;: </p>
<p><b>Visual C#</b></p>
<pre class="csharpcode"><span class="rem">//</span><br><span class="rem">// Fired when each ping completes</span><br><span class="rem">// </span><br><span class="kwrd">public</span> <span class="kwrd">event</span> EventHandler&lt;NetScanCompletedEventArgs&gt; PingComplete;<br><br><span class="rem">//</span><br><span class="rem">// Fired when all pings complete</span><br><span class="rem">//</span><br><span class="kwrd">public</span> <span class="kwrd">event</span> EventHandler&lt;EventArgs&gt; NetScanComplete;<br></pre>
<style type="text/css">
<!--
.csharpcode
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	margin:0em;
	width:100%}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre class="csharpcode"><span class="rem">'</span><br><span class="rem">' Fired when each ping completes</span><br><span class="rem">' </span><br><span class="kwrd">Public</span> <span class="kwrd">Event</span> PingComplete <span class="kwrd">As</span> EventHandler(Of NetScanCompletedEventArgs)<br><br><span class="rem">'</span><br><span class="rem">' Fired when all pings complete</span><br><span class="rem">'</span><br><span class="kwrd">Public</span> <span class="kwrd">Event</span> NetScanComplete <span class="kwrd">As</span> EventHandler(Of EventArgs)<br></pre>
<style type="text/css">
<!--
.csharpcode
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	margin:0em;
	width:100%}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>The syntax for raising an event remains unchanged: </p>
<p><b>Visual C#</b></p>
<pre class="csharpcode">NetScanComplete(<span class="kwrd">this</span>, <span class="kwrd">new</span> EventArgs());</pre>
<style type="text/css">
<!--
.csharpcode
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	margin:0em;
	width:100%}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre class="csharpcode"><span class="kwrd">RaiseEvent</span> NetScanComplete(<span class="kwrd">Me</span>, <span class="kwrd">New</span> EventArgs())</pre>
<style type="text/css">
<!--
.csharpcode
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	margin:0em;
	width:100%}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>The form can then wire up handlers to respond to these events.&nbsp; When each ping completes, an event is raised that lets the user interface show the results of the ping.&nbsp; When all the pings have completed, an event is raised that lets the user interface know
 that all the results are in.&nbsp; This could have been handled with traditional event handlers, but C# 2.0 supports a new feature known as anonymous methods, and I implemented the handler with those.&nbsp; Here's all the code for setting up the event handlers and kicking
 off the ping operations: </p>
<p><b>Visual C#</b></p>
<pre class="csharpcode"><span class="rem">//</span><br><span class="rem">// The NetScan will perform the pings on separate threads</span><br><span class="rem">//</span><br>NetScan ns = <span class="kwrd">new</span> NetScan();<br><br><span class="rem">//</span><br><span class="rem">// Event handler for when each ping completes.</span><br><span class="rem">//</span><br>ns.PingComplete &#43;= <span class="kwrd">delegate</span>(<span class="kwrd">object</span> s, NetScanCompletedEventArgs ev)<br>{<br>    <span class="kwrd">if</span> (ev.Reply.Status == IPStatus.Success)<br>    {<br>        ListViewItem li = <span class="kwrd">new</span> ListViewItem(<span class="kwrd">new</span> <span class="kwrd">string</span>[] {<br>            ev.Reply.Address.ToString(),<br>            ev.Reply.RoundtripTime.ToString(CultureInfo.InvariantCulture)<br>            &#43; <span class="str">&quot; ms&quot;</span> });<br>        resultsListView.Items.Add(li);<br>    }<br>};<br><br><span class="rem">//</span><br><span class="rem">// Event handler for when all pings have completed.</span><br><span class="rem">//</span><br>ns.NetScanComplete &#43;= <span class="kwrd">delegate</span>(<span class="kwrd">object</span> s, EventArgs ev)<br>{<br>    scanButton.Enabled = <span class="kwrd">true</span>;<br>};<br><br><span class="rem">//</span><br><span class="rem">// Disable the &quot;Scan&quot; button while the pings are running, and start the </span><br><span class="rem">// pings.</span><br><span class="rem">//</span><br>scanButton.Enabled = <span class="kwrd">false</span>;<br>ns.Start(<span class="kwrd">new</span> PingRange(startIP, endIP));</pre>
<style type="text/css">
<!--
.csharpcode
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	margin:0em;
	width:100%}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b></p>
<pre class="csharpcode"><span class="rem">'</span><br><span class="rem">' The NetScan will perform the pings on separate threads</span><br><span class="rem">'</span><br><span class="kwrd">Dim</span> ns <span class="kwrd">As</span> NetScan = <span class="kwrd">New</span> NetScan()<br><br><span class="rem">'</span><br><span class="rem">' Event handler for when each ping completes.</span><br><span class="rem">'</span><br><span class="kwrd">AddHandler</span> ns.PingComplete, <span class="kwrd">AddressOf</span> PingComplete<br><br><span class="rem">'</span><br><span class="rem">' Event handler for when all pings have completed.</span><br><span class="rem">'</span><br><span class="kwrd">AddHandler</span> ns.NetScanComplete, <span class="kwrd">AddressOf</span> NetScanComplete<br><span class="rem">'</span><br><span class="rem">' Disable the &quot;Scan&quot; button while the pings are running, and start the ‘ </span><br><span class="rem">' pings.</span><br><span class="rem">'</span><br>scanButton.Enabled = <span class="kwrd">False</span><br>ns.Start(<span class="kwrd">New</span> PingRange(startIP, endIP))<br><br><span class="kwrd">Private</span> <span class="kwrd">Sub</span> PingComplete(<span class="kwrd">ByVal</span> s <span class="kwrd">As</span> <span class="kwrd">Object</span>, <br>    <span class="kwrd">ByVal</span> ev <span class="kwrd">As</span> NetScanCompletedEventArgs)<br><br>    <span class="kwrd">If</span> ev.Reply.Status = IPStatus.Success <span class="kwrd">Then</span><br>        <span class="kwrd">Dim</span> li <span class="kwrd">As</span> ListViewItem = <span class="kwrd">New</span> ListViewItem(<span class="kwrd">New</span> <span class="kwrd">String</span>() <br>            {ev.Reply.Address.ToString(), <br>            ev.Reply.RoundtripTime.ToString(<br>            CultureInfo.InvariantCulture) &#43; <span class="str">&quot; ms&quot;</span>})<br>        resultsListView.Items.Add(li)<br>    <span class="kwrd">End</span> <span class="kwrd">If</span><br><span class="kwrd">End</span> <span class="kwrd">Sub</span><br><br><span class="kwrd">Private</span> <span class="kwrd">Sub</span> NetScanComplete(<span class="kwrd">ByVal</span> s <span class="kwrd">As</span> <span class="kwrd">Object</span>, <span class="kwrd">ByVal</span> ev <span class="kwrd">As</span> EventArgs)<br>    scanButton.Enabled = <span class="kwrd">True</span><br><span class="kwrd">End</span> Sub</pre>
<style type="text/css">
<!--
.csharpcode
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{background-color:#ffffff;
	font-family:consolas,"Courier New",courier,monospace;
	color:black;
	font-size:small}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	margin:0em;
	width:100%}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>You can see that the event handlers for PingComplete and NetScanComplete are just placed in-line in the method body.
</p>
<p>This completes the tour of this application.&nbsp; You can download Visual C# 2005 Express Edition and explore this application for yourself. Get started at http://msdn.microsoft.com/express.</p>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/c4f.Sean-Campbell/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:8afda6a3792649eab8489e7600da6692">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Building-Network-Utilities</comments>
      <itunes:summary>



&amp;nbsp;
This is a simple utility that will look for devices on the network.



Sean Campbell
3 Leaf Development

Difficulty: Easy
Time Required: 
1-3 hours
Cost: Free
Software: Visual Studio Express Editions
Hardware: 
&amp;nbsp;
Source Code: Lost!!!&amp;nbsp; But check out this
article which shows off how to do network discovery using simular methods.








&amp;nbsp; 
For this first post, I&#39;ve decided to dig into the new System.Net.NetworkInformation namespace, and build a simple utility that will look for devices on the network:
 

 
This gave me the opportunity to explore a number of new features in Visual Studio 2005 by using Visual C# Express Edition. Depending on the language I wanted, I could have used any of the Visual Studio Express Editions for this sample. Beta 2 of the Express
 editions can be downloaded from http://msdn.microsoft.com/express. &amp;nbsp;
 
The core of this application is the new Ping class (System.Net.NetworkInformation.Ping).&amp;nbsp; This gives you built-in functionality for sending an ICMP echo request to a network device.
 
Visual C# 
IPAddress ip = IPAddress.Parse(&amp;quot;192.168.1.1&amp;quot;);Ping ping = new Ping();PingReply pr = ping.Send(ip);



Visual Basic 
IPAddress ip = IPAddress.Parse(&amp;quot;192.168.1.1&amp;quot;)Dim newPing As Ping = New Ping()Dim pr As PingReply = newPing.Send(ip)



You can see that the .NET Framework 2.0 makes it trivial to ping a network device.&amp;nbsp; Prior to the .NET Framework 2.0, it was
substantially more code to accomplish this.
 
In addition, I wanted to make this asynchronous so that the pings were being done in the background, and the UI was not blocked, and updated as the results came in.&amp;nbsp; Also, because there could potentially be a very large number of IP addresses, I didn&#39;t want
 to fire off pings for all of them at the same time.&amp;nbsp; For my testing, having about 200 pings going at the same time worked well.
 
Letting 200 pings go at one time turned out to be trivial to perform using the semaphore class.&amp;nbsp</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Building-Network-Utilities</link>
      <pubDate>Tue, 31 Oct 2006 16:35:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Building-Network-Utilities</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/914076_100.jpg" height="75" width="100"></media:thumbnail>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/914076_220.jpg" height="165" width="220"></media:thumbnail>      
      <dc:creator>Sean Campbell</dc:creator>
      <itunes:author>Sean Campbell</itunes:author>
      <slash:comments>34</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Building-Network-Utilities/RSS</wfw:commentRss>
      <category>utility</category>
      <category>Windows</category>
    </item>
  <item>
      <title>Setting Wallpaper</title>
      <description><![CDATA[<span id="c4fmetadata">
<table class="" cellspacing="0" cellpadding="1" width="100%" border="0">
<tbody>
<tr class="entry_overview">
<td class="" width="50">&nbsp;</td>
<td class=""><span class="entry_description">This sample application allows you select an image and set it as wallpaper.</span></td>
</tr>
<tr>
<td class="" colspan="2">
<div class="entry_author">Sean Campbell</div>
<div class="entry_company"><a href="http://www.3leafdev.com/Home.aspx">3 Leaf Development</a></div>
<br>
<div class="entry_details"><b>Difficulty: </b><span class="entry_details_input">Easy</span></div>
<div class="entry_details"><b>Time Required:</b> <span class="entry_details_input">
1-3 hours</span></div>
<div class="entry_details"><b>Cost: </b><span class="entry_details_input">Free</span></div>
<div class="entry_details"><b>Software: </b><span class="entry_details_input"><a href="http://msdn.com/express/">Visual Studio Express Editions</a></span></div>
<div class="entry_details"><b>Hardware: </b><span class="entry_details_input"></span></div>
<div class="entry_details"><b>Download: </b><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/912569/Setting_20Wallpaper_20Code.msi">Download</a>
<ul>
</ul>
</div>
</td>
</tr>
</tbody>
</table>
</span>
<p>&nbsp;</p>
<p>Interacting visually with the Windows Desktop from code is fun, so I decided to see what it would take to change the appearance.&nbsp; This sample application allows you select an image and set it as wallpaper:
</p>
<p><img height="405" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/912569/image001.jpg" width="407">
</p>
<p>It turns out that wallpaper is not directly accessible from managed code, but working with Win32 API's is no problem in this case.&nbsp; Developing this application allowed me to work with methods imported from system DLL's, the registry, the file open dialog,
 a custom enumerated type, and use datasource binding to that enumerated type. </p>
<p>The application allows you to browse to an image, view a preview (resized smaller to fit if necessary), select the display style (Tiled, Stretched, or Centered), and set the image as the Desktop background.&nbsp; This enabled me to work some of the new features
 in Visual Studio 2005 as well. &nbsp;The code samples shown in this article use Visual C# 2005 Express Edition, however any of the Visual Studio Express Editions can be used to create a similar sample. &nbsp;Visual Basic source code is also included with the code download
 for this article. Beta 2 of the Express editions can be downloaded from <a href="http://msdn.microsoft.com/express">
http://msdn.microsoft.com/express</a>. </p>
<p>As seen above, the form consists of a button to browse to an image, a button to set the background to that image, a drop-down list of sizing options, and the currently selected image.&nbsp; Not visible are a SplitContainer control (separating the buttons and
 ComboBox control from the image) and a file open dialog.&nbsp; As seen in the ResearchHelp sample, the SplitContainer control is easy to use and allows the user more control over the layout of the user interface.&nbsp; In the upper panel, the interactive controls have
 been placed, while the lower space is filled with a docked PictureBox control. </p>
<p>Desktop wallpaper can use one of three different sizing styles for display.&nbsp; The Tiled option displays the image at full-size, repeating the image as needed, horizontally and vertically, to fill the screen.&nbsp; The Stretched option displays the image at whatever
 size necessary to fill the screen either horizontally or vertically.&nbsp; Finally, the Centered option places the image at the center of the screen, exactly once, whether if fills the screen or not, even allowing it to go beyond the edges of the screen if it is
 too large.&nbsp; In order to support these three styles in an object-oriented way, an enumerated type was created.&nbsp; This allows us to use the various style options as strongly-typed objects.&nbsp; This is preferable to string or numeric representations that may not
 contain valid values and can cause trouble when passed to a method. </p>
<p><b>Visual C#</b> </p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">enum</span> Style: <span class="kwrd">int</span>
{
    Tiled, Centered, Stretched
}
</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b> </p>
<pre class="csharpcode"><span class="kwrd">Public</span> <span class="kwrd">Enum</span> Style <span class="kwrd">As</span> <span class="kwrd">Integer</span>
    Tiled
    Centered
    Stretched
<span class="kwrd">End</span> Enum</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>The code that actually sets the image as wallpaper accepts the path to the image and a Style reference.&nbsp; Two registry values are set in the Control Panel\Desktop key.&nbsp; Based on which sizing style is requested, numeric codes are set for the WallpaperStyle
 and TileWallpaper values.&nbsp; Using an enumerated type for the style means the value is guaranteed to match one of the three defined options -- no default case is needed.
</p>
<p><b>Visual C#</b> </p>
<pre class="csharpcode">RegistryKey key = Registry.CurrentUser.OpenSubKey(<span class="str">&quot;Control Panel\\Desktop&quot;</span>, <span class="kwrd">true</span>);
<span class="kwrd">switch</span>( style )
{
    <span class="kwrd">case</span> Style.Stretched :
        key.SetValue(<span class="str">@&quot;WallpaperStyle&quot;</span>, <span class="str">&quot;2&quot;</span>) ; 
        key.SetValue(<span class="str">@&quot;TileWallpaper&quot;</span>, <span class="str">&quot;0&quot;</span>) ;
        <span class="kwrd">break</span>;
    <span class="kwrd">case</span> Style.Centered :
        key.SetValue(<span class="str">@&quot;WallpaperStyle&quot;</span>, <span class="str">&quot;1&quot;</span>) ; 
        key.SetValue(<span class="str">@&quot;TileWallpaper&quot;</span>, <span class="str">&quot;0&quot;</span>) ; 
        <span class="kwrd">break</span>;
    <span class="kwrd">case</span> Style.Tiled :
        key.SetValue(<span class="str">@&quot;WallpaperStyle&quot;</span>, <span class="str">&quot;1&quot;</span>) ; 
        key.SetValue(<span class="str">@&quot;TileWallpaper&quot;</span>, <span class="str">&quot;1&quot;</span>) ;
        <span class="kwrd">break</span>;
}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b> </p>
<pre class="csharpcode"><span class="kwrd">Dim</span> key <span class="kwrd">As</span> RegistryKey = My.Computer.Registry.CurrentUser.OpenSubKey(<span class="str">&quot;Control Panel\Desktop&quot;</span>, <span class="kwrd">True</span>)
<span class="kwrd">Select</span> <span class="kwrd">Case</span> selectedStyle
    <span class="kwrd">Case</span> Style.Stretched
        key.SetValue(<span class="str">&quot;WallpaperStyle&quot;</span>, <span class="str">&quot;2&quot;</span>)
        key.SetValue(<span class="str">&quot;TileWallpaper&quot;</span>, <span class="str">&quot;0&quot;</span>)
    <span class="kwrd">Case</span> Style.Centered
        key.SetValue(<span class="str">&quot;WallpaperStyle&quot;</span>, <span class="str">&quot;1&quot;</span>)
        key.SetValue(<span class="str">&quot;TileWallpaper&quot;</span>, <span class="str">&quot;0&quot;</span>)
    <span class="kwrd">Case</span> Style.Tiled
        key.SetValue(<span class="str">&quot;WallpaperStyle&quot;</span>, <span class="str">&quot;1&quot;</span>)
        key.SetValue(<span class="str">&quot;TileWallpaper&quot;</span>, <span class="str">&quot;1&quot;</span>)
<span class="kwrd">End</span> Select</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>At this point, the sizing options have been set, but the actual image path still needs to be set.&nbsp; The SystemParametersInfo function exists in the user32.dll to allow you to set or retrieve hardware and configuration information from your system.&nbsp; The function
 accepts four arguments.&nbsp; The first indicates the operation to take place, the second two parameters represent data to be set, dependant on requested operation, and the final parameter allows you to specify how changes are saved and/or broadcasted.&nbsp; The DllImport
 attribute allows you to specify a DLL, the function to call, and any required arguments.
</p>
<p><b>Visual C#</b> </p>
<pre class="csharpcode">[DllImport(<span class="str">&quot;user32.dll&quot;</span>, CharSet = CharSet.Auto)]
<span class="kwrd">static</span> <span class="kwrd">extern</span> <span class="kwrd">int</span> SystemParametersInfo(
    <span class="kwrd">int</span> uAction, <span class="kwrd">int</span> uParam, <span class="kwrd">string</span> lpvParam, <span class="kwrd">int</span> fuWinIni);
</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b> </p>
<pre class="csharpcode">&lt;DllImport(<span class="str">&quot;user32&quot;</span>)&gt; _
<span class="kwrd">Public</span> <span class="kwrd">Shared</span> <span class="kwrd">Function</span> SystemParametersInfo(<span class="kwrd">ByVal</span> uAction <span class="kwrd">As</span> <span class="kwrd">Integer</span>, _
     <span class="kwrd">ByVal</span> uParam <span class="kwrd">As</span> <span class="kwrd">Integer</span>, <span class="kwrd">ByVal</span> lpvParam <span class="kwrd">As</span> <span class="kwrd">String</span>, <span class="kwrd">ByVal</span> fuWinIni _   
     <span class="kwrd">As</span> <span class="kwrd">Integer</span>) <span class="kwrd">As</span> <span class="kwrd">Integer</span>
<span class="kwrd">End</span> Function</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>In addition to importing the function, you will need to define some constants for use with it.&nbsp; The first constant represents the wallpaper operation to take place in this sample, to be used in the first argument.&nbsp; The other two constants will be combined
 together for the final argument. </p>
<p><b>Visual C#</b> </p>
<pre class="csharpcode"><span class="kwrd">const</span> <span class="kwrd">int</span> SPI_SETDESKWALLPAPER = 20;
<span class="kwrd">const</span> <span class="kwrd">int</span> SPIF_UPDATEINIFILE = 0x01;
<span class="kwrd">const</span> <span class="kwrd">int</span> SPIF_SENDWININICHANGE = 0x02;</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<pre><b>Visual Basic</b></pre>
<pre class="csharpcode"><span class="kwrd">Const</span> SPI_SETDESKWALLPAPER <span class="kwrd">As</span> <span class="kwrd">Integer</span> = 20
<span class="kwrd">Const</span> SPIF_UPDATEINIFILE <span class="kwrd">As</span> <span class="kwrd">Integer</span> = &amp;H1&amp;
<span class="kwrd">Const</span> SPIF_SENDWININICHANGE <span class="kwrd">As</span> <span class="kwrd">Integer</span> = &amp;H2&amp;</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Once the function is imported, you can call it like any other.&nbsp; The operation to be invoked is SPI_SETDESKWALLPAPER.&nbsp; In our sample, the second argument is not needed so set to zero.&nbsp; The third argument is a reference to the image path.&nbsp; Note that the image
 must be in bitmap format.&nbsp; The final argument specifies that the changes should persist, and also be immediately visible.
</p>
<p><b>Visual C#</b> </p>
<pre class="csharpcode">SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, path, SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b> </p>
<pre class="csharpcode">SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, path, SPIF_UPDATEINIFILE <span class="kwrd">Or</span> SPIF_SENDWININICHANGE)</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>At this point, everything is in place to update the desktop wallpaper.&nbsp; The user interface provides a Browse button that defaults to the Windows system directory with a *.bmp filter.&nbsp; About a dozen bitmaps are available here.&nbsp; The drop-down list is databound
 to the Style enumerated type by calling the Enum.GetNames() method in the System namespace.&nbsp; This returns a string array perfect for lists and iteration.
</p>
<p><b>Visual C#</b><code><br>
</code></p>
<pre class="csharpcode">styleComboBox.DataSource = System.Enum.GetNames(<span class="kwrd">typeof</span>(Wallpaper.Style));</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b> </p>
<pre class="csharpcode">styleComboBox.DataSource = System.<span class="kwrd">Enum</span>.GetNames(<span class="kwrd">GetType</span>(Wallpaper.Style))</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>When the user clicks the Set button, the selected ComboBox text must be casted back to the enumerated item object.&nbsp; Note that this method would throw an exception if an invalid string was passed to it, but this isn't a risk with a ComboBox.&nbsp; The conversion
 occurs as follows: </p>
<p><b>Visual C#</b> </p>
<pre class="csharpcode">(Wallpaper.Style)Enum.Parse(<span class="kwrd">typeof</span>(Wallpaper.Style), styleComboBox.Text)</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b> </p>
<pre class="csharpcode"><span class="kwrd">CType</span>(System.<span class="kwrd">Enum</span>.Parse(<span class="kwrd">GetType</span>(Wallpaper.Style), styleComboBox.Text),            
      Wallpaper.Style)</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Conclusion</b> </p>
<p>The Win32 API makes it relatively easy to take advantage of features that aren't available in the .NET Framework.&nbsp; A nice addition would be to use the Save() method of the Bitmap class to automatically convert images to Bitmap format so a user could select
 JPEG or GIF images from the local hard drive.&nbsp; Download Visual C# 2005 Express Edition or Visual Basic 2005 Express Edition and give this application a try. &nbsp;Get started at
<a href="http://msdn.microsoft.com/express">http://msdn.microsoft.com/express</a>.&nbsp;&nbsp;</p>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/c4f.Sean-Campbell/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:d3872e64c60d468399669e7600dac4bc">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Setting-Wallpaper</comments>
      <itunes:summary>



&amp;nbsp;
This sample application allows you select an image and set it as wallpaper.



Sean Campbell
3 Leaf Development

Difficulty: Easy
Time Required: 
1-3 hours
Cost: Free
Software: Visual Studio Express Editions
Hardware: 
Download: Download








&amp;nbsp; 
Interacting visually with the Windows Desktop from code is fun, so I decided to see what it would take to change the appearance.&amp;nbsp; This sample application allows you select an image and set it as wallpaper:
 

 
It turns out that wallpaper is not directly accessible from managed code, but working with Win32 API&#39;s is no problem in this case.&amp;nbsp; Developing this application allowed me to work with methods imported from system DLL&#39;s, the registry, the file open dialog,
 a custom enumerated type, and use datasource binding to that enumerated type.  
The application allows you to browse to an image, view a preview (resized smaller to fit if necessary), select the display style (Tiled, Stretched, or Centered), and set the image as the Desktop background.&amp;nbsp; This enabled me to work some of the new features
 in Visual Studio 2005 as well. &amp;nbsp;The code samples shown in this article use Visual C# 2005 Express Edition, however any of the Visual Studio Express Editions can be used to create a similar sample. &amp;nbsp;Visual Basic source code is also included with the code download
 for this article. Beta 2 of the Express editions can be downloaded from 
http://msdn.microsoft.com/express.  
As seen above, the form consists of a button to browse to an image, a button to set the background to that image, a drop-down list of sizing options, and the currently selected image.&amp;nbsp; Not visible are a SplitContainer control (separating the buttons and
 ComboBox control from the image) and a file open dialog.&amp;nbsp; As seen in the ResearchHelp sample, the SplitContainer control is easy to use and allows the user more control over the layout of the user interface.&amp;nbsp; In the upper panel, the interactive controls have
 </itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Setting-Wallpaper</link>
      <pubDate>Tue, 31 Oct 2006 14:51:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Setting-Wallpaper</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/912569_100.jpg" height="75" width="100"></media:thumbnail>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/912569_220.jpg" height="165" width="220"></media:thumbnail>      
      <dc:creator>Sean Campbell</dc:creator>
      <itunes:author>Sean Campbell</itunes:author>
      <slash:comments>25</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Setting-Wallpaper/RSS</wfw:commentRss>
    </item>
  <item>
      <title>Poor Man&#39;s Power Monitor</title>
      <description><![CDATA[<span id="c4fmetadata">
<table class="" cellspacing="0" cellpadding="1" width="100%" border="0">
<tbody>
<tr class="entry_overview">
<td class="" width="50">&nbsp;</td>
<td class=""><span class="entry_description">This is an application that makes it really easy to know how much power you were using, and specifically where that power was going.</span></td>
</tr>
<tr>
<td class="" colspan="2">
<div class="entry_author">Sean Campbell</div>
<div class="entry_company"><a href="http://www.3leafdev.com/Home.aspx">3 Leaf Development</a></div>
<br>
<div class="entry_details"><b>Difficulty: </b><span class="entry_details_input">Intermediate</span></div>
<div class="entry_details"><b>Time Required:</b> <span class="entry_details_input">
1-3 hours</span></div>
<div class="entry_details"><b>Cost: </b><span class="entry_details_input">Free</span></div>
<div class="entry_details"><b>Software: </b><span class="entry_details_input"><a href="http://msdn.com/express/">Visual Studio Express Editions</a></span></div>
<div class="entry_details"><b>Hardware: </b><span class="entry_details_input"></span></div>
<div class="entry_details"><b>Download: </b><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/912351/Power_20Monitor_20Code.msi">Download</a>
<ul>
</ul>
</div>
</td>
</tr>
</tbody>
</table>
</span>
<p>Note: For this code sample, please make sure to open the project with the Windows Form visible,&nbsp;select performanceCounter1 from the application tray, switch to the Properties Window and change the
<strong>MachineName </strong>property to your computer name.</p>
<p>Laptops are currently outselling desktops, which means a couple of things.&nbsp; It means that users are more mobile, and are using applications while they sit in conference rooms, coffee shops, or airline seats.&nbsp; This also means that for a good percentage of
 the day, you can be away from the wall outlet that gives life to your laptop.&nbsp; I often find that I'm consciously aware of what I run when I'm on a long flight, because I want the battery to last it all the way to my destination.&nbsp; However, my choice of application
 usage is based on in intuition and environmental clues.&nbsp; For example, if the fan's running, and the performance of applications is “chunky”, then I know that I'm loading the system down, and the battery is bleeding dry faster than I would like.&nbsp; However, I
 wanted something a little more scientific than just laying my hands on the machine, and trying to feel the force of the current flowing.&nbsp; There are some really sophisticated pieces of software that will examine the power usage of various applications, but
 I figured by just monitoring a few key performance counters, I could have a pretty good approximation of the drain rate.
</p>
<h4>The Stats</h4>
<p>First, you know that when the CPU is maxed out, you're using a lot of battery.&nbsp; The hard drive is another expensive piece of equipment to use, so physical disk IO is another indication.&nbsp; Finally, network usage – especially wireless network usage – can also
 be a significant drain.&nbsp; There are some other significant factors as well (is your brightness turned up all the way, for example), but much of this information is not readily accessible through software, so it's left out of the mix.&nbsp; Even so, I believe that
 the power monitor developed for this article gives a good indication of how fast you're draining the electron bank.
</p>
<h4>The App</h4>
<p>I wanted an application that made it really easy to know how much power you were using, and specifically where that power was going, so the following user interface was developed:
</p>
<p><img height="138" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/912351/image001.jpg" width="346" border="0">
</p>
<p>This is the power usage while I was simultaneously zipping a directory that contained SQL 2000, and downloading an ISO image over the wireless network.&nbsp; As you can see, the system is hammered, and the power usage monitor indicates that the CPU, disk, and
 networking subsystems are all being stressed.&nbsp; Stop the download, and the networking usage drops off:
</p>
<p><img height="138" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/912351/image002.jpg" width="346" border="0">
</p>
<p>And stop the Zip operation, and the system returns to a more idle state: </p>
<p><img height="138" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/912351/image003.jpg" width="346" border="0">
</p>
<p>Also note the blue bar.&nbsp; This indicates what the average power usage has been for the last minute.&nbsp; As power usage tends to jump around a fair amount as applications are running, and this gives you an instant look what the average usage level has been.
</p>
<h4>The Details</h4>
<p>The application uses a timer control to poll certain system counters on a regular – two second – interval.&nbsp; For CPU data, this is trivial.&nbsp; You can just use the .NET Framework's PerformanceCounter class.&nbsp; For disk IO, the story is a tad more complicated.&nbsp;
 The counter that I wanted to read was the “Physical Disk:% Disk Time:_Total” counter.&nbsp; Unfortunately, as documented
<a href="http://support.microsoft.com/default.aspx?scid=kb;en-us;324548">here</a>, reading that counter from the .NET Framework is broken in v1.0, 1.1, and apparently still in v2.0.&nbsp; However, with just a little WMI code, you can easily get this information:
</p>
<p><b>Visual C#</b> </p>
<pre class="csharpcode">physDiskCounter = <span class="kwrd">new</span> ManagementObject(
                <span class="str">&quot;Win32_PerfRawData_PerfDisk_PhysicalDisk.Name='_Total'&quot;</span>); 

physDiskCounter.Get();
<span class="kwrd">double</span> newCountBase = (<span class="kwrd">double</span>)(<span class="kwrd">ulong</span>)physDiskCounter.Properties[
                       <span class="str">&quot;PercentDiskTime_Base&quot;</span>].Value;
<span class="kwrd">double</span> newCountValue = (<span class="kwrd">double</span>)(<span class="kwrd">ulong</span>)physDiskCounter.Properties[
                       <span class="str">&quot;PercentDiskTime&quot;</span>].Value;
<span class="kwrd">double</span> result = ((prevCountValue - newCountValue) / 
                (prevCountBase - newCountBase)) * 100;
prevCountBase = newCountBase;
prevCountValue = newCountValue;
<span class="kwrd">return</span> result;</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b> </p>
<pre class="csharpcode">physDiskCounter = <span class="kwrd">New</span> ManagementObject(
                  <span class="str">&quot;Win32_PerfRawData_PerfDisk_PhysicalDisk.Name='_Total'&quot;</span>)

physDiskCounter.<span class="kwrd">Get</span>();
<span class="kwrd">double</span> newCountBase = (<span class="kwrd">double</span>)(ulong)physDiskCounter.Properties[
                       <span class="str">&quot;PercentDiskTime_Base&quot;</span>].Value;
<span class="kwrd">double</span> newCountValue = (<span class="kwrd">double</span>)(ulong)physDiskCounter.Properties[
                        <span class="str">&quot;PercentDiskTime&quot;</span>].Value;
<span class="kwrd">double</span> result = ((prevCountValue - newCountValue) /
                (prevCountBase - newCountBase)) * 100;
prevCountBase = newCountBase;
prevCountValue = newCountValue;
<span class="kwrd">return</span> result;</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>This just accesses the raw performance counter values, subtracts off the previous value to get the delta, and returns the results.
</p>
<p>Reading the network information is also a problem, but for a different reason.&nbsp; First, I really want to just monitor the wireless network card, as that's what uses the most power.&nbsp; I certainly don't want things like the loopback adapter included in the mix.&nbsp;
 There are some low level APIs that I could use to find the wireless network adapter, but fortunately version 2.0 of the Framework contains a number of new networking classes that make this easy:
</p>
<p><b>Visual C#</b> </p>
<pre class="csharpcode"><span class="rem">// Look for a &quot;real&quot; network interface, and preferably</span>
<span class="rem">// a WiFi, as it uses the most power.</span>
NetworkInterface[] interfaces = 
    NetworkInterface.GetAllNetworkInterfaces();
<span class="kwrd">foreach</span> (NetworkInterface ni <span class="kwrd">in</span> interfaces)
{
    <span class="kwrd">if</span> (ni.NetworkInterfaceType == NetworkInterfaceType.Wireless80211 ||
        ni.NetworkInterfaceType == NetworkInterfaceType.Ethernet)
    {
        netName = ni.Description.Replace(<span class="str">&quot;(&quot;</span>, <span class="str">&quot;[&quot;</span>).Replace(<span class="str">&quot;)&quot;</span>, <span class="str">&quot;]&quot;</span>);
        speed = ni.Speed / 10;
        <span class="kwrd">if</span> (ni.NetworkInterfaceType == NetworkInterfaceType.Wireless80211)
        {
            <span class="kwrd">break</span>;
        }
    }
} </pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b> </p>
<pre class="csharpcode"><span class="rem">' Look for a &quot;real&quot; network interface, and preferably</span>
<span class="rem">' a WiFi, as it uses the most power.</span>
<span class="kwrd">Dim</span> interfaces() <span class="kwrd">As</span> NetworkInterface =  
    NetworkInterface.GetAllNetworkInterfaces() 
<span class="kwrd">Dim</span> ni <span class="kwrd">As</span> NetworkInterface
<span class="kwrd">For</span> <span class="kwrd">Each</span> ni <span class="kwrd">In</span> interfaces
    <span class="kwrd">If</span> ni.NetworkInterfaceType = NetworkInterfaceType.Wireless80211 <span class="kwrd">Or</span> _
        ni.NetworkInterfaceType = NetworkInterfaceType.Ethernet <span class="kwrd">Then</span>
        netName = ni.Description.Replace(<span class="str">&quot;(&quot;</span>, <span class="str">&quot;[&quot;</span>).Replace(<span class="str">&quot;)&quot;</span>, <span class="str">&quot;]&quot;</span>)
        speed = ni.Speed / 10
        <span class="kwrd">If</span> ni.NetworkInterfaceType = 
            NetworkInterfaceType.Wireless80211 <span class="kwrd">Then</span>
            <span class="kwrd">Exit</span> <span class="kwrd">For</span>
        <span class="kwrd">End</span> <span class="kwrd">If</span>
    <span class="kwrd">End</span> <span class="kwrd">If</span>
Next</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>You can see that the NetworkInterface class exposes a wealth of information about each network interface.&nbsp; Specifically, it's easy to find an 802.11 interface.&nbsp; However (nothing's ever easy), this method returned “Intel 21140-Based PCI Fast Ethernet Adapter
 (Generic) - Packet Scheduler Miniport” for the adapter description.&nbsp; However, the “real” name appears to be “Intel 21140-Based PCI Fast Ethernet Adapter [Generic] - Packet Scheduler Miniport”.&nbsp; Note the brackets instead of parenthesis around the work “Generic”.&nbsp;
 I'm not sure why the NetworkInterface API is returning parenthesis, but it's enough of a difference that if you try to use a PerformanceCounter class, or WMI, to read the counter, it won't find it because the name exactly doesn't match.
</p>
<p>I ran into another problem with the PerformanceCounter as well. &nbsp;It appears that it truncates the instance name to 64 characters, so while I passed in “Intel 21140-Based PCI Fast Ethernet Adapter [Generic] - Packet Scheduler Miniport”, it only took “Intel
 21140-Based PCI Fast Ethernet Adapter [Generic] - Packet S”.&nbsp; The last 17 characters were lopped off, and the PerformanceCounter class threw an exception saying it couldn't find what I was looking for.
</p>
<p>The (relatively) new MSDN Product Feedback Center came to the rescue.&nbsp; I used it to look up the bug, and found that it had
<a href="http://lab.msdn.microsoft.com/productfeedback/viewfeedback.aspx?feedbackid=00cc94e9-274b-43e6-bb5f-f4592ff21ee7">
already been reported</a>, and that it was scheduled to be fixed in Beta 2 of Visual Studio 2005.
</p>
<p>In the end, it was back to WMI to read this performance counter as well. </p>
<h4>That's Smooth</h4>
<p>At this point, I was able to read all the applicable performance counters, and it was time to render the information.&nbsp; When reading performance counters, you want to read them infrequently, as reading performance counters is relatively expensive.&nbsp; However,
 if your bar graph only updates every two seconds, it tends to jump around a lot, making it hard to see how much power you're really using (high one reading, low the next).&nbsp; I wanted to smooth out the movement of the bar, so I used an additional timer control,
 ticking 10 times per second, to move the bar an increment between the last performance counter reading, and the current one.&nbsp; The affect is shown here:
</p>
<p><img height="136" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/912351/image004.gif" width="344" border="0">
</p>
<h4>The Solution is the Problem</h4>
<p>Again, you don't want your power monitor to use a lot of power itself.&nbsp; This application can consume as much as 6% of the CPU while it's running.&nbsp; To me, this is too expensive.&nbsp; To correct for this, I modified the application so that when it's minimized,
 it uses a system tray icon to display the power usage graphics, and with a little logic, the application uses much less power.&nbsp;
</p>
<p>A really good way to reduce the power of many applications is to shut off your rending logic if the application isn't visible.&nbsp; This is really simple to do (but you'd be surprised how few applications bother to do this):
</p>
<p><b>Visual C#</b> </p>
<pre class="csharpcode"><span class="kwrd">if</span> (Visible)
{
    <span class="kwrd">int</span> x = pictureBox1.Width;
    <span class="kwrd">int</span> y = pictureBox1.Height;
    <span class="kwrd">using</span> (Graphics g = pictureBox1.CreateGraphics())
    {
        Render(g, x, y);
    }
}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b> </p>
<pre class="csharpcode"><span class="kwrd">If</span> Visible <span class="kwrd">Then</span>
    <span class="kwrd">Dim</span> x <span class="kwrd">As</span> <span class="kwrd">Integer</span> = pictureBox1.Width
    <span class="kwrd">Dim</span> y <span class="kwrd">As</span> <span class="kwrd">Integer</span> = pictureBox1.Height
    Using g <span class="kwrd">As</span> Graphics = pictureBox1.CreateGraphics()
        Render(g, x, y)
    <span class="kwrd">End</span> Using
<span class="kwrd">End</span> If</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>In other words, if the Form isn't visible, don't render the bar graph on it.&nbsp; This change alone cut the power consumption from 6% of CPU to about 2% of CPU.&nbsp; When the application is minimized, it still renders the bar graph to the system tray using the notification
 icon control: </p>
<p><b>Visual C#</b> </p>
<pre class="csharpcode">Bitmap iconBitmap = <span class="kwrd">new</span> Bitmap(16, 16);
<span class="kwrd">using</span> (Graphics g = Graphics.FromImage(iconBitmap))
{
    Render(g, 16, 16);
    <span class="kwrd">try</span>
    {
        notifyIcon1.Icon = Icon.FromHandle(iconBitmap.GetHicon());
    }
    <span class="kwrd">catch</span> (Exception)
    {
    }
} </pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b> </p>
<pre class="csharpcode"><span class="kwrd">Dim</span> iconBitmap <span class="kwrd">As</span> Bitmap = <span class="kwrd">New</span> Bitmap(16, 16)
Using g <span class="kwrd">As</span> Graphics = Graphics.FromImage(iconBitmap)
    Render(g, 16, 16)
    <span class="kwrd">Try</span>
        notifyIcon1.Icon =
            System.Drawing.Icon.FromHandle(iconBitmap.GetHicon())
    <span class="kwrd">Catch</span>
    <span class="kwrd">End</span> <span class="kwrd">Try</span>
<span class="kwrd">End</span> Using</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>As you can see, it's easy to generate a bitmap, and then use the GetHicon method to display the bitmap in the notification icon.&nbsp; Rendering a 256 pixels to the system tray uses very little power compared rendering 11500 pixels to the form.
</p>
<p>One other thing I quickly noticed was that, because the notification icon just isn't the same resolution, you didn't see a physical change in it 10 times a second, so I realized that I could drop my rendering rate when the power monitor is minimized:
</p>
<p><b>Visual C#</b> </p>
<pre class="csharpcode"><span class="kwrd">private</span> <span class="kwrd">void</span> Form1_VisibleChanged(<span class="kwrd">object</span> sender, EventArgs e)
{
    renderTimer.Interval = Visible ? 100 : 500;    
}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b> </p>
<pre class="csharpcode"><span class="kwrd">Private</span> <span class="kwrd">Sub</span> Form1_VisibleChanged(<span class="kwrd">ByVal</span> sender <span class="kwrd">As</span> <span class="kwrd">Object</span>, <span class="kwrd">ByVal</span> e <span class="kwrd">As</span>  
    EventArgs) <span class="kwrd">Handles</span> <span class="kwrd">Me</span>.VisibleChanged
    renderTimer.Interval = IIf(Visible, 100, 500)
<span class="kwrd">End</span> Sub</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>With these changes in effect, the power monitor now consumes an average of less than 1% of CPU when minimized, while still providing a visual indication of overall power usage.&nbsp; With a simple double-click, you can display the full form for more details.&nbsp;
 This is low enough power consumption that you can leave it running all the time without significantly affecting battery life.
</p>
<p>At this point, I have an application that I can easily use to make intelligent choices about what to run to conserve battery.&nbsp; Also, while the application doesn't monitor individual processes, I have found it useful for identifying power hogs.</p>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/c4f.Sean-Campbell/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:8722f800295142cc8a699e7600db5430">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Poor-Mans-Power-Monitor</comments>
      <itunes:summary>



&amp;nbsp;
This is an application that makes it really easy to know how much power you were using, and specifically where that power was going.



Sean Campbell
3 Leaf Development

Difficulty: Intermediate
Time Required: 
1-3 hours
Cost: Free
Software: Visual Studio Express Editions
Hardware: 
Download: Download








Note: For this code sample, please make sure to open the project with the Windows Form visible,&amp;nbsp;select performanceCounter1 from the application tray, switch to the Properties Window and change the
MachineName property to your computer name. 
Laptops are currently outselling desktops, which means a couple of things.&amp;nbsp; It means that users are more mobile, and are using applications while they sit in conference rooms, coffee shops, or airline seats.&amp;nbsp; This also means that for a good percentage of
 the day, you can be away from the wall outlet that gives life to your laptop.&amp;nbsp; I often find that I&#39;m consciously aware of what I run when I&#39;m on a long flight, because I want the battery to last it all the way to my destination.&amp;nbsp; However, my choice of application
 usage is based on in intuition and environmental clues.&amp;nbsp; For example, if the fan&#39;s running, and the performance of applications is “chunky”, then I know that I&#39;m loading the system down, and the battery is bleeding dry faster than I would like.&amp;nbsp; However, I
 wanted something a little more scientific than just laying my hands on the machine, and trying to feel the force of the current flowing.&amp;nbsp; There are some really sophisticated pieces of software that will examine the power usage of various applications, but
 I figured by just monitoring a few key performance counters, I could have a pretty good approximation of the drain rate.
 
The Stats
First, you know that when the CPU is maxed out, you&#39;re using a lot of battery.&amp;nbsp; The hard drive is another expensive piece of equipment to use, so physical disk IO is another indication.&amp;nbsp; Finally, network usage – espec</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Poor-Mans-Power-Monitor</link>
      <pubDate>Tue, 31 Oct 2006 14:32:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Poor-Mans-Power-Monitor</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/912351_100.jpg" height="75" width="100"></media:thumbnail>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/912351_220.jpg" height="165" width="220"></media:thumbnail>      
      <dc:creator>Sean Campbell</dc:creator>
      <itunes:author>Sean Campbell</itunes:author>
      <slash:comments>8</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Poor-Mans-Power-Monitor/RSS</wfw:commentRss>
    </item>
  <item>
      <title>Outlook from the Managed World</title>
      <description><![CDATA[<span id="c4fmetadata">
<table class="" cellspacing="0" cellpadding="1" width="100%" border="0">
<tbody>
<tr class="entry_overview">
<td class="" width="50">&nbsp;</td>
<td class=""><span class="entry_description">In this article, we will step through creating an email message and a contact using VSTO.</span></td>
</tr>
<tr>
<td class="" colspan="2">
<div class="entry_author">Sean Campbell</div>
<div class="entry_company"><a href="http://blogs.msdn.com/controlpanel/blogs/"></a></div>
<br>
<div class="entry_details"><b>Difficulty: </b><span class="entry_details_input">Easy</span></div>
<div class="entry_details"><b>Time Required:</b> <span class="entry_details_input">
1-3 hours</span></div>
<div class="entry_details"><b>Cost: </b><span class="entry_details_input">Free</span></div>
<div class="entry_details"><b>Software: </b><span class="entry_details_input"><a href="http://msdn.microsoft.com/vstudio/">Visual Studio 2005</a></span></div>
<div class="entry_details"><b>Hardware: </b><span class="entry_details_input"></span></div>
<div class="entry_details"><b>Download: </b>
<ul>
<li><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/909239/HelloWorld_20for_20Outlook_20(CSharp).msi">C# Download</a>
</li><li><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/909239/HelloWorld_20for_20Outlook_20(Visual_20Basic).msi">VB Download</a></li></ul>
</div>
</td>
</tr>
</tbody>
</table>
</span>
<p>When I read the announcement that <b>Visual Studio 2005 Tools for Microsoft Office (VSTO 2005)
</b>had added support for <b>Microsoft Outlook </b>(currently in beta), I downloaded it immediately! After all, my digital universe revolves around email, and being able to easily extend Outlook in custom ways has always been a wish of mine. Writing add-ins
 for Outlook certainly isn't a new capability, but it was never as easy to write useful, secure code as it is now.
</p>
<p>My first step was to download the VSTO Outlook Beta installer. Then, to speed up the learning curve, I downloaded the conveniently supplied snippets. Including the snippets, even this early build is immensely helpful and a great way to jumpstart your creativity.
 As you will see, the extensibility is quite broad, and in fact we will only be able to scratch the surface with this article. Don't worry though; I'll revisit it again in future columns.
</p>
<p>The application we will create today is basically a <i>Hello World </i>for Outlook. We'll step through creating an email message and a contact. The supplied code samples in this article are written in C#, however Visual Basic source code is also included
 with the code download for this article. Developing with VSTO requires a version of Visual Studio greater than Express Edition. The current beta of Visual Studio can be downloaded from
<a href="http://lab.msdn.microsoft.com/vs2005/get/">http://lab.msdn.microsoft.com/vs2005/get/</a>. Of course,
<b>Microsoft Office Professional 2003 </b>(Service Pack 1) is also a requirement for this article, or at least
<b>Outlook 2003 SP1</b>. Be aware that <b>Outlook Express </b>will not function as a replacement for Outlook.
</p>
<p>The first step after installing the above is to create an <b>Outlook Add-in </b>
project in the <b>Office </b>project templates section in Visual Studio. Notice that alongside the Excel and Word templates, there is a new option for
<b>Outlook</b>. Specify a name and click <b>OK</b>. </p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/909239/VSTO-Outlook_1.gif"><img alt="Click here for larger image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/909239/VSTO-Outlook_1_thumb.gif" border="0"></a>
</p>
<p><b>Creating the Outlook Add-in project (click image to zoom)</b> </p>
<p>Actually working with the new features could have proved to be difficult, but it turns out that the object model and available events just make sense. The project template adds a few references for general VSTO and specifically for Outlook. It also creates
 a setup project to simplify deployment. The main class file is <b>ThisApplication.cs</b> and contains a
<b>Startup</b> and <b>Shutdown </b>event handler similar to other VSTO project types.
</p>
<p>To avoid presenting too much material at once, in our example creating these items will occur when the add-in starts up and we will not use a menu or any user input to trigger it. Though not realistic, it makes it easier to step into this new functionality.
 Keep in mind though, that you can create custom menus on the standard menu bar, or respond to events such as the currently active folder, new messages arriving, or an appointment reminder.
</p>
<p>Creating mail items, contacts, and folders is easy using the snippets, but be sure to read the readme that appears after installing them. Though the snippets are installed, they will not appear in the
<b>Insert Snippet </b>menu item until added through the Visual Studio Snippets Manager (<b>Tools | Code Snippets Manager
</b>menu command). </p>
<p>In order to create a new mail message, you will first need to obtain a reference to an
<b>Outlook.MAPIFolder </b>object. This encapsulates an Outlook folder like <b>Inbox</b>,
<b>Draft</b>, <b>Outbox</b>, or user-created folders. In order to get the default
<b>Outbox </b>folder call the <b>GetDefaultFolder</b> method of the <i>MAPI</i> namespace object:
</p>
<p><b>Visual C#</b> </p>
<pre class="csharpcode">Outlook.MAPIFolder outBoxfolder = <span class="kwrd">this</span>.GetNamespace(<span class="str">&quot;MAPI&quot;</span>).GetDefaultFolder( <br>    Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderOutbox);&nbsp;</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b> </p>
<pre class="csharpcode"><span class="kwrd">Dim</span> outBoxfolder <span class="kwrd">As</span> Outlook.MAPIFolder = <br>    <span class="kwrd">Me</span>.GetNamespace(<span class="str">&quot;MAPI&quot;</span>).GetDefaultFolder(    <br>    Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderOutbox)</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Correction</b> (9/7/2005, thanks to Sue Mosher, Outlook MVP): You should actually use the
<b>Application.CreateItem</b> method, which is the standard (and simpler) technique for creating a new item in one of the default folders.
</p>
<p>Once you have a reference to the folder, you can add an item to it. Because the Outbox is generally intended for mail items, that is what we will add, but remember that Outlook supports any item type being added to any folder. To create and add a new mail
 item, call the <b>Items.Add </b>method of the folder object: </p>
<p><b>Visual C#</b> </p>
<pre class="csharpcode">Outlook.MailItem mailItem = (Outlook.MailItem)outBoxfolder.Items.Add(Outlook.OlItemType.olMailItem);<br></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<pre><b>Visual Basic</b></pre>
<pre class="csharpcode"><span class="kwrd">Dim</span> mailItem <span class="kwrd">As</span> Outlook.MailItem = <br>    outBoxfolder.Items.Add(Outlook.OlItemType.olMailItem)</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>At this point you have a mail item to manipulate. You can set the <b>Subject</b>,
<b>Body</b>, and <b>To</b> properties, add a reminder, attach files, display the message, and of course send it:
</p>
<p><b>Visual C#</b> </p>
<pre class="csharpcode">mailItem.Subject = <span class="str">&quot;Coding4Fun Sample&quot;</span>;<br>mailItem.Body = <span class="str">&quot;This email was created using VSTO 2005 Outlook support.&quot;</span>;<br>mailItem.To = <span class="str">&quot;emailaddress@emailaddress&quot;</span>;<br></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b> </p>
<pre class="csharpcode">mailItem.Subject = <span class="str">&quot;Coding4Fun Sample&quot;</span> <br>mailItem.Body = <span class="str">&quot;This email was created using VSTO 2005 Outlook support.&quot;</span><br>mailItem.<span class="kwrd">To</span> = <span class="str">&quot;emailaddress@emailaddress&quot;</span> </pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Sending the message simply requires calling the <b>Send </b>method, while displaying the message is accomplished with the
<b>Display </b>method (modally or not). If you do not call the <b>Send </b>or <b>
Save </b>method, the message will not persist unless you display the message to allow the user to save or send it. This model is consistent with the various item types.
</p>
<p>If you have added the snippets, you can create a mail item in two quick steps: insert the snippet, and then fill in the placeholder fields. You should probably create a new method to contain your message sending code, then right-click and select
<b>Insert Snippet</b>, and navigate to the <b>Outlook | Create </b>sub-menu. You will see all of the above code, including helpful
<i>TODO</i> comments, and commented out <b>Send </b>and <b>Display </b>calls. </p>
<p><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/909239/VSTO-Outlook_2.gif"><img alt="Click here for larger image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/909239/VSTO-Outlook_2_thumb.gif" border="0"></a>
</p>
<p><b>A sample message (click image to zoom)</b> </p>
<p>There is no snippet for adding a task item (yet anyway), so for our final sample, let's create a new task. The API is so well thought-out, that once you can create an email, creating a task is a snap. As before, obtain a reference to the folder, this time
 the <b>Tasks</b> folder. Also as before, remember that any folder will hold a task. This feature is useful for linking items and maintaining isolation between business or project boundaries. Once again, the folder is one of the defaults, so call
<b>GetDefaultFolder</b>, this time with the <b>olFolderTasks </b>enumerated folder name:
</p>
<p><b>Visual C#</b> </p>
<pre class="csharpcode">Outlook.MAPIFolder tasksFolder = <span class="kwrd">this</span>.GetNamespace(<span class="str">&quot;MAPI&quot;</span>).GetDefaultFolder( <br>    Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderTasks);&nbsp;</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b> </p>
<pre class="csharpcode"><span class="kwrd">Dim</span> outBoxfolder <span class="kwrd">As</span> Outlook.MAPIFolder = <br>    <span class="kwrd">Me</span>.GetNamespace(<span class="str">&quot;MAPI&quot;</span>).GetDefaultFolder(<br>    Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderTasks)<br></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Next, add a new instance of a task item. Notice that you are not calling a constructor. Each item type is actually an interface. Items must be created as children of a folder, not as stand-alone objects:
</p>
<p><b>Visual C#</b> </p>
<pre class="csharpcode">Outlook.TaskItem taskItem = (Outlook.TaskItem)tasksFolder.Items.Add(Outlook.OlItemType.olTaskItem);<br></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b> </p>
<pre class="csharpcode"><span class="kwrd">Dim</span> taskItem <span class="kwrd">As</span> Outlook.TaskItem = <br>    outBoxfolder.Items.Add(Outlook.OlItemType.olTaskItem)</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Next, set the appropriate properties. In this case, the task's subject, owner, percentage complete, and status.
<b>Status </b>is an enumerated type representing Complete, Deferred, In Progress, Not Started, and Waiting.
</p>
<p><b>Visual C#</b> </p>
<pre class="csharpcode">taskItem.Subject = <span class="str">&quot;Finish Coding4Fun article!&quot;</span>;<br>taskItem.Owner = <span class="str">&quot;Bob&quot;</span>;<br>taskItem.PercentComplete = 0;<br>taskItem.Status = Microsoft.Office.Interop.Outlook.OlTaskStatus.olTaskInProgress;<br></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b> </p>
<pre class="csharpcode">taskItem.Subject = <span class="str">&quot;Finish Coding4Fun article!&quot;</span><br>taskItem.Owner = <span class="str">&quot;Bob&quot;</span><br>taskItem.PercentComplete = 0<br>taskItem.Status = Microsoft.Office.Interop.Outlook.OlTaskStatus.olTaskInProgress</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>The final step is to save the task. This step must be called, or the task will be lost when Outlook is closed or the object goes out of scope.
</p>
<p><b>Visual C#</b> </p>
<pre class="csharpcode">taskItem.Save();<br></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b> </p>
<pre class="csharpcode">taskItem.Save()</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<h4>Conclusion</h4>
<p>VSTO support for Outlook makes it painless to create add-ins for Outlook in managed code. You can create all of the common entity types such as email messages, contacts, and tasks, respond to events, create HTML folder views, and also add application menus.
 Download <b>Visual Studio 2005</b>, the beta VSTO Outlook installer, then give this application a try. Get started at
<a href="http://lab.msdn.microsoft.com/vs2005/get/">http://lab.msdn.microsoft.com/vs2005/get/</a>.
</p>
<h5>Additional Resources</h5>
<p><a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=74B56C72-7A1F-431F-A29C-58EB39E97A86&amp;displaylang=en">VSTO support for Outlook (Beta)</a>
</p>
<p><a href="http://msdn.microsoft.com/office/understanding/vsto/training/snippets/default.aspx">Outlook Add-in Snippets</a></p>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/c4f.Sean-Campbell/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:b0d5f461f14948caa68a9e7600dbcd39">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Outlook-from-the-Managed-World</comments>
      <itunes:summary>



&amp;nbsp;
In this article, we will step through creating an email message and a contact using VSTO.



Sean Campbell


Difficulty: Easy
Time Required: 
1-3 hours
Cost: Free
Software: Visual Studio 2005
Hardware: 
Download: 

C# Download
VB Download






When I read the announcement that Visual Studio 2005 Tools for Microsoft Office (VSTO 2005)
had added support for Microsoft Outlook (currently in beta), I downloaded it immediately! After all, my digital universe revolves around email, and being able to easily extend Outlook in custom ways has always been a wish of mine. Writing add-ins
 for Outlook certainly isn&#39;t a new capability, but it was never as easy to write useful, secure code as it is now.
 
My first step was to download the VSTO Outlook Beta installer. Then, to speed up the learning curve, I downloaded the conveniently supplied snippets. Including the snippets, even this early build is immensely helpful and a great way to jumpstart your creativity.
 As you will see, the extensibility is quite broad, and in fact we will only be able to scratch the surface with this article. Don&#39;t worry though; I&#39;ll revisit it again in future columns.
 
The application we will create today is basically a Hello World for Outlook. We&#39;ll step through creating an email message and a contact. The supplied code samples in this article are written in C#, however Visual Basic source code is also included
 with the code download for this article. Developing with VSTO requires a version of Visual Studio greater than Express Edition. The current beta of Visual Studio can be downloaded from
http://lab.msdn.microsoft.com/vs2005/get/. Of course,
Microsoft Office Professional 2003 (Service Pack 1) is also a requirement for this article, or at least
Outlook 2003 SP1. Be aware that Outlook Express will not function as a replacement for Outlook.
 
The first step after installing the above is to create an Outlook Add-in 
project in the Office project templates section in Visual Studio. Notic</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Outlook-from-the-Managed-World</link>
      <pubDate>Tue, 31 Oct 2006 10:36:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Outlook-from-the-Managed-World</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/909239_100.jpg" height="75" width="100"></media:thumbnail>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/909239_220.jpg" height="165" width="220"></media:thumbnail>      
      <dc:creator>Sean Campbell</dc:creator>
      <itunes:author>Sean Campbell</itunes:author>
      <slash:comments>19</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Outlook-from-the-Managed-World/RSS</wfw:commentRss>
      <category>Office</category>
      <category>Outlook</category>
      <category>VSTO</category>
    </item>
  <item>
      <title>Redirecting Outlook Reminders</title>
      <description><![CDATA[<span id="c4fmetadata">
<table class="" cellspacing="0" cellpadding="1" width="100%" border="0">
<tbody>
<tr class="entry_overview">
<td class="" width="50">&nbsp;</td>
<td class=""><span class="entry_description">Today's article will guide you through creating an add-in to Outlook 2003 to send alerts to another computer when a reminder is raised.</span></td>
</tr>
<tr>
<td class="" colspan="2">
<div class="entry_author">Sean Campbell</div>
<div class="entry_company"><a href="http://blogs.msdn.com/controlpanel/blogs/"></a></div>
<br>
<div class="entry_details"><b>Difficulty: </b><span class="entry_details_input">Easy</span></div>
<div class="entry_details"><b>Time Required:</b> <span class="entry_details_input">
1-3 hours</span></div>
<div class="entry_details"><b>Cost: </b><span class="entry_details_input">Free</span></div>
<div class="entry_details"><b>Software: </b><span class="entry_details_input"><a href="http://msdn.com/express/">Visual Studio Express Editions</a></span></div>
<div class="entry_details"><b>Hardware: </b><span class="entry_details_input"></span></div>
<div class="entry_details"><b>Download: </b>
<ul>
<li><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/908472/OutlookAlertsCS.msi">C# Download</a>
</li><li><a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/908472/OutlookAlertsVB.msi">VB Download</a></li></ul>
</div>
</td>
</tr>
</tbody>
</table>
</span>
<p>In my last article in this series, I worked with the new Visual Studio 2005 Tools for Microsoft Office (VSTO 2005) newly released support for Microsoft Outlook (currently beta). At that point, it was enough to just get it installed, set up the snippets,
 and take a look at the samples. I created a starter project to demonstrate creating a new mail item and task. Of course it was just a stepping stone to the great things you can do with the beta, but I wanted to do something useful this time.
</p>
<p>I don't know about you, but in my house I have my laptop that floats from room to room, a main desktop in the office, a media center computer, my wife's computer, and other assorted boxes awaiting upgrades or repair. I have Outlook installed on my laptop
 to keep it portable. Obviously, with all of the aforementioned systems, I'm not always sitting in front of my laptop. This means that meeting and task reminders will often go off without me noticing them. Not a good situation!
</p>
<p>As they say, necessity is the mother of invention. &quot;Wouldn't it be nice if I could be alerted on a different computer since Outlook is bound to only one?&quot; I thought. Then, it came to me. The new VSTO 2005 for Outlook support was the answer! Why not register
 for event notifications when a reminder goes off, and raise an alert somewhere else? And from that,
<b>Outlook Alerts </b>was born. </p>
<p>Today's article will guide you through creating an add-in to Outlook 2003 to send alerts to another computer when a reminder is raised. In order to follow this article and run the code, you will need any of the Visual Studio Express editions. The code samples
 in this article are shown in Visual Basic 2005; however, the downloadable source code is available in both VB 2005 and C# 2005. Beta 2 of the Express editions can be downloaded from
<a href="http://msdn.microsoft.com/express">http://msdn.microsoft.com/express</a>. As with last time, Microsoft Office 2003 (Service Pack 1) is also a requirement, or at least Outlook 2003 SP1. Be aware that Outlook Express will not function as a replacement
 for Outlook. </p>
<p>The first step in sending alerts remotely is to detect when reminders and alarms are triggered in Outlook. As it turns out, this is easy to hook into, as the main Application object exposes a
<b>Reminder</b> event. By registering an event handler for this, you are notified every time the Outlook Reminder<b>
</b>dialog appears. The <b>item</b> parameter contains a reference to the item causing the event. This could be a mail item, an appointment, or any other Outlook item supporting reminders. The following method declaration creates a method which will be triggered
 whenever the <b>Reminder</b> event is raised: </p>
<p><b>Visual C#</b> </p>
<pre class="csharpcode"><span class="kwrd">void</span> ThisApplication_Reminder(<span class="kwrd">object</span> item)</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b> </p>
<pre class="csharpcode"><span class="kwrd">Private</span> <span class="kwrd">Sub</span> ThisApplication_Reminder(<span class="kwrd">ByVal</span> item <span class="kwrd">As</span> <span class="kwrd">Object</span>) <span class="kwrd">Handles</span> <span class="kwrd">Me</span>.Reminder</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<pre></pre>
<p>The alerts application has two settings to keep track of. Settings can seem like a challenge. You may not be sure where to store them or what format to use, and writing the code to serialize them and deserialize them can be tedious. Fortunately, the .NET
 2.0 framework makes this trivial. Simply right-click the project in the <b>Solution Explorer</b>, then click
<b>Properties</b>. Choose the <b>Settings</b>tab and you can create and manage any settings you need. You have the ability to create user or application scope settings with arbitrary names, in a variety of data types. For this project, create a
<b>Boolean</b> setting called <b>RemoteRemindersEnabled</b>, and a <b>String</b> setting called
<b>RemoteReminderAddress</b>. The first flag controls whether or not alerts will be sent remotely, while the second flag specifies where to send any alerts. The address should be an IP address or net name. Note that unless the other computer is in the same
 workgroup or domain, it is generally easier to use IP address to guarantee delivery. The
<b>Settings</b>configuration should look like this:</p>
<p><br>
<a href="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/908472/RedirOutlook_1.gif"><img alt="Click here for larger image" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/908472/RedirOutlook_1_thumb.gif" border="0"></a>
</p>
<p><b>(click image to zoom)</b> </p>
<p>Once the settings are created, you can access them in a strongly-typed fashion using the
<b>My </b>namespace in Visual Basic as follows: </p>
<p><b>Visual C#</b> </p>
<pre class="csharpcode">Properties.Settings.Default.RemoteRemindersEnabled</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b> </p>
<pre class="csharpcode">My.Settings.RemoteRemindersEnabled</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>If you use settings, you must provide an easy way to allow users to manage the setting values. Outlook allows you to add menus alongside the built-in menus. This is easy to do and provides a professional look to your add-in. The first step is to obtain a
 reference to the main menu bar and add a top-level menu; in this case, &quot;Add-in Tasks.&quot; The code looks a little messy due to type casting (the
<b>CType </b>call) and the two <b>Type.Missing</b> parameters. These are necessary due to the underlying COM nature of the code:
</p>
<p><b>Visual C#</b> </p>
<pre class="csharpcode">_menuBar = <span class="kwrd">this</span>.ActiveExplorer().CommandBars.ActiveMenuBar;<br>_helpMenuIndex = _menuBar.Controls[MENU_BEFORE].Index;<br><br>_topMenu = (Office.CommandBarPopup)(_menuBar.Controls.Add(Office.MsoControlType.msoControlPopup, <br>Type.Missing, Type.Missing, _helpMenuIndex, <span class="kwrd">true</span>));<br>_topMenu.Caption = <span class="str">&quot;Add-in Tasks&quot;</span>;<br>_topMenu.Visible = <span class="kwrd">true</span>;</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b> </p>
<pre class="csharpcode">_menuBar = <span class="kwrd">Me</span>.ActiveExplorer().CommandBars.ActiveMenuBar<br>_helpMenuIndex = _menuBar.Controls(MENU_BEFORE).Index<br><br>_topMenu = <span class="kwrd">CType</span>(_menuBar.Controls.Add(Office.MsoControlType.msoControlPopup, Type.Missing, <br>Type.Missing, _helpMenuIndex, <span class="kwrd">True</span>), Office.CommandBarPopup)<br>_topMenu.Caption = <span class="str">&quot;Add-in Tasks&quot;</span> <br>_topMenu.Visible = True</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>After creating the menu, you add menu items by calling the <b>Controls.Add() </b>
method. Once again, the code looks a little cluttered, but is overall very understandable. The
<b>Caption </b>properties in both cases determine what is seen when the menu is opened:
</p>
<p><b>Visual C#</b> </p>
<pre class="csharpcode">_settingsMenu = (Office.CommandBarButton)(_topMenu.Controls.Add(Office.MsoControlType.msoControlButton, <br>Type.Missing, Type.Missing, Type.Missing, <span class="kwrd">true</span>));<br>_settingsMenu.Caption = <span class="str">&quot;Remote Alert Notification Settings...&quot;</span>;<br>_settingsMenu.Visible = <span class="kwrd">true</span>;<br>_settingsMenu.Enabled = <span class="kwrd">true</span>;</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b> </p>
<pre class="csharpcode">_settingsMenu = <span class="kwrd">CType</span>(_topMenu.Controls.Add(Office.MsoControlType.msoControlButton, Type.Missing, <br>Type.Missing, Type.Missing, <span class="kwrd">True</span>), Office.CommandBarButton)<br>_settingsMenu.Caption = <span class="str">&quot;Remote Alert Notification Settings...&quot;</span> <br>_settingsMenu.Visible = <span class="kwrd">True</span> <br>_settingsMenu.Enabled = True<span class="kwrd"></span>
</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style><style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>You will still need to create a settings form, and create an event handler to respond to user clicks on the item. At runtime, selecting the
<b>Add-in Tasks | Remote Alert Notification Settings </b>menu option brings up this custom dialog:
</p>
<p><img alt="" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/908472/rediroutlook_2.gif" border="0">
</p>
<h4>Alerts</h4>
<p>The final step is to determine how to actually send the remote alerts. I toyed with the idea of creating a remoting client to run on other PCs, or publish/subscribe clients, but the easiest approach is to work with what is already there. The
<b>Messenger </b>service is a built-in Windows service for sending simple administrative messages from servers. Note that this is not related to the
<b>MSN Messenger </b>product. </p>
<p>Unfortunately, in the past few years, the service has also become a target of spammers, so it is often disabled by Anti-Spyware products like
<b>Microsoft AntiSpyware</b>. In order to enable it, go to <b>Services </b>configuration, then enable and start the
<b>Messenger </b>service. Once it is enabled, you can use a built-in command, <b>
net.exe</b>, to send messages. Given a computer's name or IP address, you can send a message as follows:
</p>
<pre>net send mycomputername This is my message. <br></pre>
<p>From code, this isn't a good option, as it causes the command prompt to appear, and it requires you to find the path to the
<b>net </b>command. Instead, in this article, I've decided to platform-invoke the underlying Win32 method to send the alert. This is easy to do once you've located the appropriate method; in this case,
<b>NetMessageBufferSend</b> in the <b>Netapi32</b> library. Start by declaring the method signature:
</p>
<p><b>Visual C#</b> </p>
<pre class="csharpcode">[DllImport(<span class="str">&quot;Netapi32&quot;</span>, CharSet=CharSet.Unicode)]<br><span class="kwrd">private</span> <span class="kwrd">static</span> <span class="kwrd">extern</span> <span class="kwrd">int</span> NetMessageBufferSend(<span class="kwrd">string</span> servername ,<br>    <span class="kwrd">string</span> msgname ,<br>    <span class="kwrd">string</span> fromname ,<br>    <span class="kwrd">string</span> buf ,<br>    <span class="kwrd">int</span> buflen );</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b> </p>
<pre class="csharpcode">&lt;DllImport(<span class="str">&quot;Netapi32&quot;</span>, CharSet:=CharSet.<span class="kwrd">Unicode</span>)&gt; _<br><span class="kwrd">Private</span> <span class="kwrd">Shared</span> <span class="kwrd">Function</span> NetMessageBufferSend(<span class="kwrd">ByVal</span> servername <span class="kwrd">As</span> <span class="kwrd">String</span>, _<br>    <span class="kwrd">ByVal</span> msgname <span class="kwrd">As</span> <span class="kwrd">String</span>, _<br>    <span class="kwrd">ByVal</span> fromname <span class="kwrd">As</span> <span class="kwrd">String</span>, _<br>    <span class="kwrd">ByVal</span> buf <span class="kwrd">As</span> <span class="kwrd">String</span>, _<br>    <span class="kwrd">ByVal</span> buflen <span class="kwrd">As</span> <span class="kwrd">Integer</span>) <span class="kwrd">As</span> <span class="kwrd">Integer</span> <br><span class="kwrd">End</span> <span class="kwrd">Function</span> </pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Notice there is no body to the method. When you specify the <b>DllImport</b> attribute, this flags to the compiler that the actual method exists in a platform library, not in the managed class. Calling the method then, is as easy as calling any other method:
</p>
<p><b>Visual C#</b> </p>
<pre class="csharpcode">NetMessageBufferSend(<span class="kwrd">null</span>, address, <span class="kwrd">null</span>, message, message.Length * 2 &#43; 2);</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p><b>Visual Basic</b> </p>
<pre class="csharpcode">NetMessageBufferSend(<span class="kwrd">Nothing</span>, address, <span class="kwrd">Nothing</span>, message, message.Length * 2 &#43; 2)</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>Now that we have a way to actually send the alert (with no client install even!), we need to respond to the
<b>Reminder </b>event. In the event handler, we will first check to see if the <b>
RemoteRemindersEnabled </b>setting is true, then determine what type of item triggered the event. Mail, appointment, and task items are supported below in this project. Depending on the type, you can extract various fields to build up a simple string, then
 send the alert: </p>
<p><b>Visual C#</b> </p>
<pre class="csharpcode"><span class="kwrd">if</span>( Properties.Settings.Default.RemoteRemindersEnabled )<br>{<br>    <span class="kwrd">string</span> reminderMsg;<br><br>    <span class="kwrd">if</span>(item <span class="kwrd">is</span> Outlook.MailItem)<br>    {<br>        Outlook.MailItem reminderMail;<br>        reminderMail = (Outlook.MailItem)item;<br>        reminderMsg = String.Format(<span class="str">&quot;Remote Outlook Reminder\nMail &quot;</span>&#43;<br>            <span class="str">&quot;subject: {0}\nReminder time: {1:t}&quot;</span>, reminderMail.Subject,<br>            reminderMail.ReminderTime);<br>    }<br>    <span class="kwrd">else</span> <span class="kwrd">if</span>(item <span class="kwrd">is</span> Outlook.AppointmentItem)<br>    {<br>        Outlook.AppointmentItem reminderAppt;<br>        reminderAppt = (Outlook.AppointmentItem)item;<br>        reminderMsg = String.Format(<span class="str">&quot;Remote Outlook Reminder\n &quot;</span>&#43;<br>        <span class="str">&quot;Appointment subject: {0}\nLocation: {1}\nReminder time: {2:t}&quot;</span>,<br>        reminderAppt.Subject, reminderAppt.Location, reminderAppt.Start);<br>    }<br>    <span class="kwrd">else</span> <span class="kwrd">if</span>(item <span class="kwrd">is</span> Outlook.TaskItem)<br>    {<br>        Outlook.TaskItem reminderTask;<br>        reminderTask = (Outlook.TaskItem)item;<br>        reminderMsg = String.Format(<span class="str">&quot;Remote Outlook Reminder\nTask &quot;</span>&#43;<br>            <span class="str">&quot;subject: {0}\nReminder time: {1:t}&quot;</span>, reminderTask.Subject, <br>            reminderTask.ReminderTime);<br>    }<br>    <span class="kwrd">else</span><br>    {<br>        <span class="rem">// Unsupported item</span><br>        <span class="kwrd">return</span>;<br>    }<br><br>    NetSend.Send(Properties.Settings.Default.RemoteReminderAddress,<br>        reminderMsg);<br>}</pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<pre><b>Visual Basic</b></pre>
<pre class="csharpcode"><span class="kwrd"></span><span class="kwrd">If</span> My.Settings.RemoteRemindersEnabled <span class="kwrd">Then</span> <br>  <span class="kwrd">Dim</span> reminderMsg <span class="kwrd">As</span> <span class="kwrd">String</span> <br><br>  <span class="kwrd">If</span> <span class="kwrd">TypeOf</span> item <span class="kwrd">Is</span> Outlook.MailItem <span class="kwrd">Then</span> <br>    <span class="kwrd">Dim</span> reminderMail <span class="kwrd">As</span> Outlook.MailItem<br>    reminderMail = <span class="kwrd">CType</span>(item, Outlook.MailItem)<br>    reminderMsg = <span class="kwrd">String</span>.Format(<span class="str">&quot;Remote Outlook Reminder\nMail subject: {0}\nReminder time: {1:t}&quot;</span>, <br>                                                    reminderMail.Subject, reminderMail.ReminderTime)<br>  <span class="kwrd">ElseIf</span> <span class="kwrd">TypeOf</span> item <span class="kwrd">Is</span> Outlook.AppointmentItem <span class="kwrd">Then</span> <br>    <span class="kwrd">Dim</span> reminderAppt <span class="kwrd">As</span> Outlook.AppointmentItem<br>    reminderAppt = <span class="kwrd">CType</span>(item, Outlook.AppointmentItem)<br>    reminderMsg = <span class="kwrd">String</span>.Format(<span class="str">&quot;Remote Outlook Reminder\nAppointment subject: {0}\nLocation: {1}\nReminder time: {2:t}&quot;</span>, <br>                                                    reminderAppt.Subject, reminderAppt.Location, reminderAppt.Start)<br>  <span class="kwrd">ElseIf</span> <span class="kwrd">TypeOf</span> item <span class="kwrd">Is</span> Outlook.TaskItem <span class="kwrd">Then</span> <br>    <span class="kwrd">Dim</span> reminderTask <span class="kwrd">As</span> Outlook.TaskItem<br>    reminderTask = <span class="kwrd">CType</span>(item, Outlook.TaskItem)<br>    reminderMsg = <span class="kwrd">String</span>.Format(<span class="str">&quot;Remote Outlook Reminder\nTask subject: {0}\nReminder time: {1:t}&quot;</span>, <br>                                                     reminderTask.Subject, reminderTask.ReminderTime)<br>  <span class="kwrd">Else</span><br>    <span class="rem">' Unsupported item</span><br>    <span class="kwrd">Return</span><br>  <span class="kwrd">End</span> <span class="kwrd">If</span><br><br>  NetSend.Send(My.Settings.RemoteReminderAddress, reminderMsg)<br><span class="kwrd">End</span> If<br></pre>
<style type="text/css">
<!--
.csharpcode, .csharpcode 
	{font-size:small;
	color:black;
	font-family:consolas,"Courier New",courier,monospace;
	background-color:#ffffff}
.csharpcode 
	{margin:0em}
.csharpcode .rem
	{color:#008000}
.csharpcode .kwrd
	{color:#0000ff}
.csharpcode .str
	{color:#006080}
.csharpcode .op
	{color:#0000c0}
.csharpcode .preproc
	{color:#cc6633}
.csharpcode .asp
	{background-color:#ffff00}
.csharpcode .html
	{color:#800000}
.csharpcode .attr
	{color:#ff0000}
.csharpcode .alt
	{background-color:#f4f4f4;
	width:100%;
	margin:0em}
.csharpcode .lnum
	{color:#606060}
-->
</style>
<p>The <b>NetSend.Send</b> method actually performs a quick replacement on any carriage returns, as they are not directly supported, then sends the alert using the Win32 call. The message will pop up on the specified computer over any other application:
</p>
<p><img alt="" src="http://ecn.channel9.msdn.com/o9/c4fcontent/migration/908472/rediroutlook_3.gif" border="0">
</p>
<h4>Next Steps</h4>
<p>Future expansion might be to allow messages to be broadcasted to multiple machines. This is easy on a domain, but would require additional work on many home networks.
<code>Net send</code> has some limitations, including sparse formatting options and a bad perception due to spammers. A more robust client, or tying it into an existing instant messenger network could be useful.
</p>
<h4>Conclusion</h4>
<p>Building this was fun. It served a definite purpose and allowed me to use a number of techniques to get it working. Download
<b>Visual C# 2005 Express Edition</b> or <b>Visual Basic 2005 Express Edition</b>, the beta VSTO Outlook installer, then give this application a try. Get started at
<a href="http://msdn.microsoft.com/express">http://msdn.microsoft.com/express</a>.
</p>
<h4>Additional Resources</h4>
<ul>
<li><a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=74B56C72-7A1F-431F-A29C-58EB39E97A86&amp;displaylang=en">VSTO support for Outlook (Beta)</a>
</li><li><a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/netmgmt/netmgmt/netmessagebuffersend.asp">NetMessageBufferSend documentation</a></li></ul>
 <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Niners/c4f.Sean-Campbell/Posts/RSS&WT.dl=0&WT.entryid=Entry:RSSView:ef6d482ac537415386d39e7600dc0ce3">]]></description>
      <comments>http://channel9.msdn.com/coding4fun/articles/Redirecting-Outlook-Reminders</comments>
      <itunes:summary>



&amp;nbsp;
Today&#39;s article will guide you through creating an add-in to Outlook 2003 to send alerts to another computer when a reminder is raised.



Sean Campbell


Difficulty: Easy
Time Required: 
1-3 hours
Cost: Free
Software: Visual Studio Express Editions
Hardware: 
Download: 

C# Download
VB Download






In my last article in this series, I worked with the new Visual Studio 2005 Tools for Microsoft Office (VSTO 2005) newly released support for Microsoft Outlook (currently beta). At that point, it was enough to just get it installed, set up the snippets,
 and take a look at the samples. I created a starter project to demonstrate creating a new mail item and task. Of course it was just a stepping stone to the great things you can do with the beta, but I wanted to do something useful this time.
 
I don&#39;t know about you, but in my house I have my laptop that floats from room to room, a main desktop in the office, a media center computer, my wife&#39;s computer, and other assorted boxes awaiting upgrades or repair. I have Outlook installed on my laptop
 to keep it portable. Obviously, with all of the aforementioned systems, I&#39;m not always sitting in front of my laptop. This means that meeting and task reminders will often go off without me noticing them. Not a good situation!
 
As they say, necessity is the mother of invention. &amp;quot;Wouldn&#39;t it be nice if I could be alerted on a different computer since Outlook is bound to only one?&amp;quot; I thought. Then, it came to me. The new VSTO 2005 for Outlook support was the answer! Why not register
 for event notifications when a reminder goes off, and raise an alert somewhere else? And from that,
Outlook Alerts was born.  
Today&#39;s article will guide you through creating an add-in to Outlook 2003 to send alerts to another computer when a reminder is raised. In order to follow this article and run the code, you will need any of the Visual Studio Express editions. The code samples
 in this article are shown in Visual Basic 200</itunes:summary>
      <link>http://channel9.msdn.com/coding4fun/articles/Redirecting-Outlook-Reminders</link>
      <pubDate>Tue, 31 Oct 2006 09:11:00 GMT</pubDate>
      <guid isPermaLink="false">http://channel9.msdn.com/coding4fun/articles/Redirecting-Outlook-Reminders</guid>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/908472_100.jpg" height="75" width="100"></media:thumbnail>
      <media:thumbnail url="http://ecn.channel9.msdn.com/o9/c4f/images/908472_220.jpg" height="165" width="220"></media:thumbnail>      
      <dc:creator>Sean Campbell</dc:creator>
      <itunes:author>Sean Campbell</itunes:author>
      <slash:comments>8</slash:comments>
      <wfw:commentRss>http://channel9.msdn.com/coding4fun/articles/Redirecting-Outlook-Reminders/RSS</wfw:commentRss>
    </item>    
</channel>
</rss>