<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
	xmlns:media="http://search.yahoo.com/mrss/"
>

<channel>
	<title>dev{shaped} &#187; Practical Programming</title>
	<atom:link href="http://devshaped.com/category/practical-programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://devshaped.com</link>
	<description></description>
	<lastBuildDate>Mon, 13 Jul 2009 14:47:13 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<!-- podcast_generator="podPress/8.8" -->
		<copyright>&#xA9; </copyright>
		<managingEditor>derek@webradius.com ()</managingEditor>
		<webMaster>derek@webradius.com()</webMaster>
		<category></category>
		<itunes:keywords></itunes:keywords>
		<itunes:subtitle></itunes:subtitle>
		<itunes:summary></itunes:summary>
		<itunes:author></itunes:author>
		<itunes:category text="Society &amp; Culture"/>
		<itunes:owner>
			<itunes:name></itunes:name>
			<itunes:email>derek@webradius.com</itunes:email>
		</itunes:owner>
		<itunes:block>No</itunes:block>
		<itunes:explicit>no</itunes:explicit>
		<itunes:image href="http://devshaped.com/wp-content/plugins/podpress/images/powered_by_podpress_large.jpg" />
		<image>
			<url>http://devshaped.com/wp-content/plugins/podpress/images/powered_by_podpress.jpg</url>
			<title>dev{shaped}</title>
			<link>http://devshaped.com</link>
			<width>144</width>
			<height>144</height>
		</image>
		<item>
		<title>Practical Programming: Hidden Talents</title>
		<link>http://devshaped.com/2009/05/practical-programming-hidden-talents/</link>
		<comments>http://devshaped.com/2009/05/practical-programming-hidden-talents/#comments</comments>
		<pubDate>Wed, 13 May 2009 00:59:00 +0000</pubDate>
		<dc:creator>Derek</dc:creator>
				<category><![CDATA[Practical Programming]]></category>
		<category><![CDATA[memory]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[sound]]></category>

		<guid isPermaLink="false">http://devshaped.com/?p=186</guid>
		<description><![CDATA[by Peter Jones
 This edition of Practical Programming covers a set of three useful classes / namespaces from the .NET Framework that you probably aren&#8217;t familiar with (yet).
Let&#8217;s make some noise: System.Media
Producing sound from a computer is something you may have learned in Programmer Playschool and promptly forgot (like me), but it is a useful [...]]]></description>
			<content:encoded><![CDATA[<p>by <a href="http://jonesie.net.nz/" target="_blank">Peter Jones</a></p>
<p><img style="border-right-width: 0px; margin: 0px 0px 22px 22px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" border="0" align="right" src="http://devshaped.com/wp-content/uploads/2009/02/peter-jones.jpg" /> This edition of Practical Programming covers a set of three useful classes / namespaces from the .NET Framework that you probably aren&#8217;t familiar with (yet).</p>
<h2>Let&#8217;s make some noise: System.Media</h2>
<p>Producing sound from a computer is something you may have learned in Programmer Playschool and promptly forgot (like me), but it is a useful little feature to add to all types of software, not just desktop games. Playing a system sound or other sound files is very useful in monitoring environments where the users are not seated in front of a computer 24&#215;7 (for example, in server rooms or manufacturing environments).</p>
<p>  <span id="more-186"></span>
<p>System.Media is a namespace that contains three useful classes for playing system sounds and .wav files. System sounds are defined in the Sounds applet of the Windows Control Panel.</p>
<p>What MSDN says: </p>
<p><i>The System.Media namespace contains classes for playing sound files and accessing sounds provided by the system. </i></p>
<p><i></i></p>
<p><i>The following classes are included in this namespace: </i></p>
<p><i></i></p>
<ul>
<li><i>A SoundPlayer class for loading and playing sounds in various file formats. </i></li>
<li><i>A SystemSound class for representing and playing a system sound. </i></li>
<li><i>A SystemSounds class that retrieves sounds associated with a set of Windows operating system sound-event types.</i> </li>
</ul>
<p>Playing a System sound couldn’t be easier:</p>
<div style="font-family: courier new; font-size: 9pt">SystemSounds.Asterisk.Play();</div>
<p>This will play the .wav file associated with the asterisk system sound. SystemSounds is a simple wrapper for the five most common sounds – asterisk, beep, question, exclamation and hand.</p>
<p>If you have your own attention-grabbing, eardrum-busting sound file then you can play this just as easily:</p>
<div style="font-family: courier new; font-size: 9pt"><span style="color: blue">string</span> filename = <span style="color: maroon">&quot;houston-we-have-a-problem.wav&quot;</span>;     <br />SoundPlayer sp = <span style="color: blue">new</span> SoundPlayer(filename);</div>
<p>Loading of large .wav file can take a while so, thoughtfully, Microsoft added support for loading a sound file asynchronously.</p>
<div style="font-family: courier new; font-size: 9pt"><span style="color: blue">static</span> SoundPlayer _player;     </p>
<p><span style="color: blue">static</span>&#160;<span style="color: blue">void</span> Main(<span style="color: blue">string</span>[] args)     <br />{     <br />&#160; <span style="color: blue">string</span> filename = <span style="color: maroon">&quot;houston-we-have-a-problem.wav&quot;</span>;     <br />&#160; _player = <span style="color: blue">new</span> SoundPlayer();     <br />&#160; _player.LoadCompleted +=&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">new</span> AsyncCompletedEventHandler(sp_LoadCompleted);     <br />&#160; _player.SoundLocation = filename;     <br />&#160; _player.LoadAsync();     <br />&#160; Console.ReadLine();     <br />}     </p>
<p><span style="color: blue">static</span>&#160;<span style="color: blue">void</span> sp_LoadCompleted(<span style="color: blue">object</span> sender, AsyncCompletedEventArgs e)     <br />{     <br />&#160; <span style="color: blue">if</span> (e.Error == <span style="color: blue">null</span>)     <br />&#160; {     <br />&#160;&#160;&#160; _player.Play();     <br />&#160; }     <br />&#160; <span style="color: blue">else</span>     <br />&#160; {     <br />&#160;&#160;&#160; Console.WriteLine(<span style="color: maroon">&quot;Could not load sound: &quot;</span> + e.Error.Message);     <br />&#160; }     <br />}     </div>
<p>This simple C# console application will play the sound file after it is loaded. Not only will the loading of the sound occur asynchronously, but the player will also play the .wav file in a new thread.</p>
<p>Additionally, the player can load a wave file from various sources such as a URL, application resources, or a stream.</p>
<h2>Brain the size of a planet? MemoryFailPoint</h2>
<p>In these multi-gigabyte days it&#8217;s not often that an application runs out of memory – virtual or otherwise – but there are few things more frustrating to a user than an &#8216;Insufficient Memory&#8217; exception. Applications that don&#8217;t handle these exceptions can potentially corrupt system data (and possibly damage your career!).</p>
<p>Thankfully, there is a simple solution: MemoryFailPoint.</p>
<p>What MSDN says: </p>
<p><i>Check for sufficient memory resources prior to execution.</i></p>
<p><i></i></p>
<p>MemoryFailPoint throws an InsufficientMemoryException prior to your operation beginning, rather than an OutOfMemoryException at some unpredictable point during the operation. Here&#8217;s the actual program that is used to launch the Space Shuttle Microsoft (j/k).</p>
<div style="font-family: courier new; font-size: 9pt"><span style="color: blue">const</span>&#160;<span style="color: blue">int</span> MB_MEMORY_REQUIRED = <span style="color: maroon">2048</span>; <span style="color: green">// 2 gig</span>     </p>
<p><span style="color: blue">try</span>     <br />{     <br />&#160; securePayload();     <br />&#160; alertMedia();     <br />&#160; loadCrew();     <br />&#160; <span style="color: blue">int</span> countDown = <span style="color: maroon">10</span>;&#160; <br />&#160; beginCountdown();     <br />&#160; <span style="color: blue">while</span> (countDown &gt; <span style="color: maroon">0</span>)     <br />&#160; {     <br />&#160;&#160;&#160; Console.WriteLine(countDown);     <br />&#160;&#160;&#160; <span style="color: blue">if</span> (countDown == <span style="color: maroon">3</span>)     <br />&#160;&#160;&#160;&#160;&#160; ignition();     <br />&#160;&#160;&#160; Thread.Sleep(<span style="color: maroon">1000</span>);     <br />&#160;&#160;&#160; countDown&#8211;;     <br />&#160; }     </p>
<p>&#160; Console.ForegroundColor = ConsoleColor.Yellow;     <br />&#160; Console.WriteLine(<span style="color: maroon">&quot;B L A S T O F F ! ! !&quot;</span>);     <br />}     <br /><span style="color: blue">catch</span> (OutOfMemoryException mex)     <br />{     <br />&#160; Console.WriteLine(<span style="color: maroon">&quot;Not enough free memory to lauch shuttle.&quot;</span>);     <br />&#160; Console.WriteLine(<span style="color: maroon">&quot;Please try again later.&quot;</span>);     <br />}     </div>
<p>Hopefully, the real NASA application is a little more complicated than this, but you could imagine a situation where running out of available memory just after ignition could be somewhat problematic. It&#8217;s better to know before you begin that your countdown is likely to fail. Adding a MemoryFailPoint around the critical code will help with this:</p>
<div style="font-family: courier new; font-size: 9pt"><span style="color: blue">try</span>     <br />{     <br />&#160; <span style="color: blue">using</span> (MemoryFailPoint mfp = <span style="color: blue">new</span> MemoryFailPoint(MB_MEMORY_REQUIRED))     <br />&#160; {     <br />&#160;&#160;&#160; &#8230;     <br />&#160; }     <br />}     <br /><span style="color: blue">catch</span> (InsufficientMemoryException mex)     <br />{     <br />&#160; Console.WriteLine(<span style="color: maroon">&quot;Not enough free memory to lauch shuttle.&quot;</span>);     <br />&#160; Console.WriteLine(<span style="color: maroon">&quot;Please try again later.&quot;</span>);     <br />}     </p>
</div>
<p>When using MemoryFailPoint for more realistic purposes, you can make intelligent decisions about the execution path. For example, fast sorting algorithms can use more memory than slower but less resource hungry versions.</p>
<h2>Secret Squirrel &#8211; System.Security.SecureString</h2>
<p>What MSDN says: </p>
<p><em>Represents text that should be kept confidential. The text is encrypted for privacy when being used, and deleted from computer memory when no longer needed.</em></p>
<p>This sounds like something useful to do, and indeed it is! To use a SecureString you need to append characters to it like so:</p>
<div style="font-family: courier new; font-size: 9pt"><span style="color: blue">string</span> password = <span style="color: maroon">&quot;Password&quot;</span>;     </p>
<p><span style="color: blue">using</span> (SecureString sPassword = <span style="color: blue">new</span> SecureString())     <br />{     <br />&#160; <span style="color: blue">foreach</span> (<span style="color: blue">char</span> ch <span style="color: blue">in</span> password) sPassword.AppendChar(ch);     <br />&#160; <span style="color: green">// do something with the secure string</span>     <br />}     </div>
<p>Clearly, this would be a tad pointless! The unsecure password is right there in clear text for all to see (and discover). To understand this, you need to understand show strings in the .NET Framework work.</p>
<p><u>Strings are immutable</u>. That is, once you create a string in memory, it can&#8217;t change – it can only be replaced. For example:</p>
<div style="font-family: courier new; font-size: 9pt"><span style="color: blue">string</span> somestring = <span style="color: maroon">&quot;fred&quot;</span>;     <br /><span style="color: green">// do something</span>     <br />somestring = <span style="color: maroon">&quot;bob&quot;</span>;     </p>
</div>
<p>Looking at this you might think that there is some chunk of memory somewhere that starts off as &quot;fred&quot; and later becomes &quot;bob&quot;. This is not the case. In actuality, both &quot;fred&quot; and &quot;bob&quot; will be in memory somewhere within the process space of the application. Every time you change a string, a new copy of the string is made and the old one is left for later cleanup by the garbage collector. A sniffer type application on a compromised machine could read through your unprotected memory quite easily.</p>
<p>So, when should you use SecureString? There are a few places in the framework that require a SecureString but the best time to use this is anywhere in your application that you prompt for something you don&#8217;t want to risk exposing to unauthorized users or processes.</p>
<p>SecureString should be used in conjunction with other secure mechanisms such as an encrypted configuration file or database record, SSL/TLS for web applications to network transport, etc.</p>
<p><u>References</u>:</p>
<p>B# .NET Blog &#8211; <a href="http://bartdesmet.net/blogs/bart/archive/2006/03/31/3851.aspx">http://bartdesmet.net/blogs/bart/archive/2006/03/31/3851.aspx</a></p>
<p>.NET Security Blog &#8211; <a href="http://blogs.msdn.com/shawnfa/archive/2004/05/27/143254.aspx">http://blogs.msdn.com/shawnfa/archive/2004/05/27/143254.aspx</a></p>
<p>&#8212;&#8211;</p>
<p><em>Peter Jones is a 25 year veteran (vintage?) programmer and Microsoft MVP (ASP.NET) from New Zealand. He currently works for </em><a href="http://www.intergen.co.nz"><em>Intergen</em></a><em> &#8211; a leading Microsoft Gold Partner. Peter has worked on and created systems for many industries such as Telecommunications, Manufacturing, Government, Education and more. He cut his programming teeth on dBase 3, Clipper 5 and C before moving to Windows development tools such as Visual Basic, Delphi and .NET. Currently he is working with content management systems (SharePoint and EPiServer) in Sydney, Australia. You can contact Peter and read his occasionally updated blog at </em><a href="http://jonesie.net.nz"><em>http://jonesie.net.nz</em></a><em>. </em></p>
]]></content:encoded>
			<wfw:commentRss>http://devshaped.com/2009/05/practical-programming-hidden-talents/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Creating Useful Installers with Custom Actions</title>
		<link>http://devshaped.com/2009/04/creating-useful-installers-with-custom-actions/</link>
		<comments>http://devshaped.com/2009/04/creating-useful-installers-with-custom-actions/#comments</comments>
		<pubDate>Wed, 01 Apr 2009 09:00:00 +0000</pubDate>
		<dc:creator>Derek</dc:creator>
				<category><![CDATA[Practical Programming]]></category>
		<category><![CDATA[custom actions]]></category>
		<category><![CDATA[installers]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://devshaped.com/2009/04/creating-useful-installers-with-custom-actions/</guid>
		<description><![CDATA[by Christian Jacob
 So you are almost done with implementing a ground breaking, state of the art, super duper plugin-enabled calculator application with syntax highlighting and now you are wondering how to get it deployed? In case you are already trying to put some arguments together to convince your boss for buying a suite to [...]]]></description>
			<content:encoded><![CDATA[<p>by <a href="http://www.trimagination.info/" target="_blank">Christian Jacob</a></p>
<p><img style="border-bottom: 0px; border-left: 0px; margin: 0px 0px 22px 22px; display: inline; border-top: 0px; border-right: 0px" title="christian-jacob" border="0" alt="christian-jacob" align="right" src="http://devshaped.com/wp-content/uploads/2009/03/christianjacob.jpg" width="85" height="57" /> So you are almost done with implementing a ground breaking, state of the art, super duper plugin-enabled calculator application with syntax highlighting and now you are wondering how to get it deployed? In case you are already trying to put some arguments together to convince your boss for buying a suite to building Microsoft Installer packages worth several thousand dollars: <b>Stop! Don’t do that.</b> Well, at least not if your application is not as complex as let’s say your development environment.</p>
<p>Using Microsoft Visual Studio you should be able to create an MSI in literally no time by using the predefined Setup Project template and if you need to accomplish additional tasks that Windows Installer does not support out of the box, read on to find out how to extend your installer with own custom actions.</p>
<p> <span id="more-121"></span><br />
<h2>The Vision</h2>
<p>A couple of years ago market researcher Evans Data noticed a massive drop of C++ developers and also forecasted a continuous decrease. Bjarne Stroustrup on the other hand said that the number of C++ developers is higher than ever (he’s the inventor of C++ by the way). Whoever you trust, you are most probably reading this because you want to know how to use C# or VB.NET for writing custom actions in Visual Studio instead of using good old C++. So let’s dive into that topic by creating a not so fictional case scenario: The first task you would want to accomplish is creating an eventlog source for your application (because you read that the installation of an application is the suggested moment for doing just that)</p>
<p>Note: We will do a lot more than that, so I have included a small sample solution for you to easily reproduce what I am talking about.  You can download it from <a href="http://devshaped.com/files/MyCalcSln.zip">http://devshaped.com/files/MyCalcSln.zip</a>.</p>
<h2>The Solution</h2>
<p>As I said earlier, you could use C++ to implement a native custom action. However, the easiest solution for getting this done using C# or VB.NET is deriving a class from the <i>Installer Class</i> and overriding the <i>Install</i> method. Then you would add your custom action to the <i>Custom Action Table</i> of the installer. </p>
<p>So let’s start!</p>
<h2>Create the Custom Action</h2>
<p>Add an <i>Installer </i>by right clicking your project and select Add &gt; New Item &gt; Installer Class. Name it CreateEventSource.cs for now.</p>
<p><a href="http://devshaped.com/wp-content/uploads/2009/03/clip-image002.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image002" border="0" alt="clip_image002" src="http://devshaped.com/wp-content/uploads/2009/03/clip-image002-thumb.jpg" width="500" height="308" /></a></p>
<p><em>Figure 1- Adding an Installer Class</em></p>
<p>Next right click the CreateEventSource.cs file in the solution explorer and select <i>View Code</i>. Replace it with the following (you may want to adjust the namespace and the actual event source name):</p>
<div style="font-family: courier new; font-size: 9pt"><span style="color: blue">namespace</span> MyCalcWin.Custom_Actions     <br />{&#160; <br />&#160; <span style="color: blue">using</span> System;&#160; <br />&#160; <span style="color: blue">using</span> System.ComponentModel;&#160; <br />&#160; <span style="color: blue">using</span> System.Configuration.Install;&#160; <br />&#160; <span style="color: blue">using</span> System.Diagnostics;&#160; </p>
<p>&#160; [RunInstaller(<span style="color: maroon">true</span>)]&#160; <br />&#160; <span style="color: blue">public</span>&#160;<span style="color: blue">partial</span>&#160;<span style="color: blue">class</span> CreateEventSource : Installer&#160; <br />&#160; {&#160; <br />&#160;&#160;&#160; <span style="color: blue">const</span>&#160;<span style="color: blue">string</span> EventSourceName = <span style="color: maroon">&quot;MyCalc&quot;</span>;&#160; </p>
<p>&#160;&#160;&#160; <span style="color: blue">public</span> CreateEventSource()&#160; <br />&#160;&#160;&#160; {&#160; <br />&#160;&#160;&#160;&#160;&#160; InitializeComponent();&#160; <br />&#160;&#160;&#160; }&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />&#160;&#160;&#160; <span style="color: blue">public</span>&#160;<span style="color: blue">override</span>&#160;<span style="color: blue">void</span> Install(System.Collections.IDictionary stateSaver)&#160; <br />&#160;&#160;&#160; {&#160; <br />&#160;&#160;&#160;&#160;&#160; <span style="color: blue">try</span>&#160; <br />&#160;&#160;&#160;&#160;&#160; {&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">base</span>.Install(stateSaver);&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; EventLog.CreateEventSource(EventSourceName, <span style="color: maroon">&quot;Application&quot;</span>);&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; EventLog.WriteEntry(EventSourceName, <span style="color: maroon">&quot;Eventsource created&quot;</span>);&#160; <br />&#160;&#160;&#160;&#160;&#160; }&#160; <br />&#160;&#160;&#160;&#160;&#160; <span style="color: blue">catch</span> (Exception ex)&#160; <br />&#160;&#160;&#160;&#160;&#160; {&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.Windows.Forms.MessageBox.Show(&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">string</span>.Format(<span style="color: maroon">&quot;Error performing installer tasks: {0}&quot;</span>, ex.Message));&#160; <br />&#160;&#160;&#160;&#160;&#160; }&#160; <br />&#160;&#160;&#160; }&#160; </p>
<p>&#160;&#160;&#160; <span style="color: blue">public</span>&#160;<span style="color: blue">override</span>&#160;<span style="color: blue">void</span> Uninstall(System.Collections.IDictionary savedState)&#160; <br />&#160;&#160;&#160; {&#160; <br />&#160;&#160;&#160;&#160;&#160; <span style="color: blue">try</span>&#160; <br />&#160;&#160;&#160;&#160;&#160; {&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">base</span>.Uninstall(savedState);&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; EventLog.DeleteEventSource(EventSourceName);&#160; <br />&#160;&#160;&#160;&#160;&#160; }&#160; <br />&#160;&#160;&#160;&#160;&#160; <span style="color: blue">catch</span> (Exception ex)&#160; <br />&#160;&#160;&#160;&#160;&#160; {&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.Windows.Forms.MessageBox.Show(&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">string</span>.Format(<span style="color: maroon">&quot;Error permorming uninstaller task: {0}&quot;</span>, ex.Message));&#160; <br />&#160;&#160;&#160;&#160;&#160; }&#160; <br />&#160;&#160;&#160; }&#160; <br />&#160; }     <br />}     </div>
<p>As you can see, deriving from the <i>Installer</i> base class is not enough. You need to add the attribute <i>RunInstaller</i> to the class and initialize it with <i>true</i> as shown above. This basically marks the <i>CreateEventSource</i> class as an <i>Installer</i> class and makes it visible to reflection.</p>
<h2>Create the setup project</h2>
<p>Simply add a new <i>Setup Project</i> to your solution by right clicking your solution in the solution explorer and then Add &gt; New Project &gt; Other Project Types &gt; Setup Project as shown in the following figure:</p>
<p><a href="http://devshaped.com/wp-content/uploads/2009/03/clip-image004.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image004" border="0" alt="clip_image004" src="http://devshaped.com/wp-content/uploads/2009/03/clip-image004-thumb.jpg" width="500" height="325" /></a></p>
<p><em>Figure 2 &#8211; Adding a Setup Project</em></p>
<p>To let the <i>Setup Project</i> know what to install, right click the project and select Add &gt; Project Output… Make sure your application project is selected as <i>Project</i> and choose <i>Primary Output</i>. Click <i>OK</i>. </p>
<p><a href="http://devshaped.com/wp-content/uploads/2009/03/clip-image006.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image006" border="0" alt="clip_image006" src="http://devshaped.com/wp-content/uploads/2009/03/clip-image006-thumb.jpg" width="280" height="313" /></a></p>
<p><em>Figure 3 &#8211; Adding Project Output to Setup Project</em></p>
<p>With these simple steps you just created a setup that is able to install your application. Now you would make sure your custom actions are called and configure some simple settings. Right click the <i>Setup Project</i> in the solution explorer and select View &gt; Custom Actions.</p>
<p>Now right click the <i>Custom Actions</i> node and select <i>Add Custom Action</i>. Look in <i>File System on Target Machine</i> and double click <i>Application Folder</i>. Select the <i>Primary Output</i> from your application project and click <i>OK</i>.</p>
<p><a href="http://devshaped.com/wp-content/uploads/2009/03/clip-image008.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image008" border="0" alt="clip_image008" src="http://devshaped.com/wp-content/uploads/2009/03/clip-image008-thumb.jpg" width="221" height="135" /></a></p>
<p><em>Figure 4 &#8211; Custom Action View</em></p>
<p>Easy. This will create the eventlog source for you by making use of the <i>Installer Class</i> you created earlier. If you would build your setup now and install it, the application will be defaulted to [ProgramFilesFolder][Manufacturer]\[ProductName]. Of course it is up to you to change the default target path. In my case, C:\Program Files\TOP TECHNOLOGIES CONSULTING GmbH\MyCalc would be a little like breaking a fly on the wheel. So I right click the <i>Setup Project</i> in the solution explorer and select View &gt; File System and choose <i>Application Folder</i>. In the properties pane, I can configure the <i>DefaultLocation</i> to something like [ProgramFilesFolder][ProductName]. That’s better.</p>
<h2>Install your application</h2>
<p>Now let’s finally make a real job of it. Right click the <i>Setup Project</i> in the solution explorer and select <i>Build</i>. After being built successfully, right click the project again and select <i>Install</i>.</p>
<p>You should be familiar with the dialogs that follow. However, after your setup successfully installed your top notch calculator, have a look at the event viewer by clicking <i>Start</i> and entering <i>eventvwr</i>. </p>
<p>You will find the following entry in the application log:</p>
<p><a href="http://devshaped.com/wp-content/uploads/2009/03/clip-image010.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image010" border="0" alt="clip_image010" src="http://devshaped.com/wp-content/uploads/2009/03/clip-image010-thumb.jpg" width="495" height="344" /></a></p>
<p><em>Figure 5 &#8211; Eventlog Entry</em></p>
<h2>Observations</h2>
<p>When using a fully featured environment for creating and using <i>Custom Actions</i> such as <i>InstallShield</i> from Acresso or <i>Windows Installer Xml</i> from Microsoft, you have absolute control over when and how your custom action is actually called. You can start it during the interview phase of your setup (aka UI sequence), during the immediate phase of the execution sequence when the actual installation script is generated or use it as a deferred custom action that is run in within the system context while the system changes are really applied. </p>
<p><i>Custom Actions</i> implemented as <i>Installer Classes</i> are <b>only run deferred in the system context</b>. That means that your application is already successfully installed at that time. You have full access to all your files and also the configuration. You could implement a <i>Custom Action</i> for instance that alters configuration settings of your application based upon properties set by the user during the UI sequence (I will show you how later).</p>
<p>If you want to dive into the details of the Microsoft Windows Installer installation process, go ahead and read Alex Shevchuck’s TechNet entry <a href="http://blogs.technet.com/alexshev/archive/2008/02/21/how-windows-installer-engine-installs-the-installation-package.aspx">here</a>. This is a great resource for a decent understanding about what’s going on under the hood.</p>
<h2>Potentialities (or: What the heck is CustomActionData?)</h2>
<p>When looking at the choices in the <i>View</i> context menu of your <i>Setup Project</i>, you already noticed the following entries:</p>
<ul>
<li>File System </li>
<li>Registry </li>
<li>File Type </li>
<li>User Interface </li>
<li>Custom Actions </li>
<li>Launch Conditions </li>
</ul>
<p>What most certainly caught your attention is the <i>User Interface</i> entry. Yes! You can really add custom UI dialogs to a <i>Visual Studio Setup Project</i>. Although it is possible creating real custom dialogs, you can instantly start using own dialogs by choosing from the provided templates. Since we already agreed that we are talking about relatively simple applications here, in most cases that will get you started immediately (if you really really need more than that, look <a href="http://www.codeproject.com/KB/install/vsSetupCustomDialogs.aspx">here</a>).</p>
<h2>Changing Application Settings During Installation </h2>
<p>Let’s have some fun with custom dialogs to do something really useful here you most probably won’t instantly find by poking keywords into a search engine. Looking into the functional specification of your calculator you notice that one of your bosses (the one who usually has the most intriguing ideas of all) demanded that the calculator should welcome the user with his/her name. You heard him mumbling something about “Unique Selling Point” while he left the conference room…</p>
<p>So here is what you do:</p>
<h3>Create a splash screen</h3>
<p>Right click your calculator application and select Add &gt; Windows Form. Name the form Welcome.cs and set its properties to the following values: </p>
<p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="123">
<p><b>Property</b></p>
</td>
<td valign="top" width="102">
<p><b>Value</b></p>
</td>
</tr>
<tr>
<td valign="top" width="123">
<p>FormBorderStyle</p>
</td>
<td valign="top" width="102">
<p>None</p>
</td>
</tr>
<tr>
<td valign="top" width="123">
<p>ShowInTaskbar</p>
</td>
<td valign="top" width="102">
<p>False</p>
</td>
</tr>
<tr>
<td valign="top" width="123">
<p>TopMost</p>
</td>
<td valign="top" width="102">
<p>True</p>
</td>
</tr>
<tr>
<td valign="top" width="123">
<p>StartPosition</p>
</td>
<td valign="top" width="102">
<p>CenterScreen</p>
</td>
</tr>
</tbody>
</table>
<p>Drag and drop three label controls into the form like this:</p>
<p><a href="http://devshaped.com/wp-content/uploads/2009/03/clip-image012.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image012" border="0" alt="clip_image012" src="http://devshaped.com/wp-content/uploads/2009/03/clip-image012-thumb.jpg" width="170" height="79" /></a></p>
<p><em>Figure 6 &#8211; Borderless splash screen</em></p>
<h3>Create and bind an application setting to a label</h3>
<p>Now configure the UserNameLabel label. In the property pane expand the ApplicationSettings node and click the ellipsis button (…) to the right of the Property Binding setting. Select the Text property, expand the drop down list and select New… Enter UserName as Name and Application as Scope (we&#8217;ll assume that the user who installs the calculator won&#8217;t let anyone else start it).</p>
<p>At this moment, Visual Studio automatically creates an app.config file for you that should basically look like this:</p>
<pre style="font-size: 9pt"><span style="color: blue">&lt;?</span><span style="color: maroon">xml</span> <span style="color: red">version</span>=&quot;<span style="color: blue">1.0</span>&quot; <span style="color: red">encoding</span>=&quot;<span style="color: blue">utf-8</span>&quot; <span style="color: blue">?&gt;</span>
<span style="color: blue">&lt;</span><span style="color: maroon">configuration</span><span style="color: blue">&gt;</span>
  <span style="color: blue">&lt;</span><span style="color: maroon">configSections</span><span style="color: blue">&gt;</span>
      <span style="color: blue">&lt;</span><span style="color: maroon">sectionGroup</span> <span style="color: red">name</span>=&quot;<span style="color: blue">applicationSettings</span>&quot; <span style="color: red">type</span>=&quot;<span style="color: blue">System.Configuration.ApplicationSettingsGroup,
          System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</span>&quot; <span style="color: blue">&gt;</span>
          <span style="color: blue">&lt;</span><span style="color: maroon">section</span> <span style="color: red">name</span>=&quot;<span style="color: blue">MyCalcWin.Properties.Settings</span>&quot;
              <span style="color: red">type</span>=&quot;<span style="color: blue">System.Configuration.ClientSettingsSection, System, Version=2.0.0.0,
              Culture=neutral, PublicKeyToken=b77a5c561934e089</span>&quot; <span style="color: red">requirePermission</span>=&quot;<span style="color: blue">false</span>&quot; /<span style="color: blue">&gt;</span>
      <span style="color: blue">&lt;</span>/<span style="color: maroon">sectionGroup</span><span style="color: blue">&gt;</span>
  <span style="color: blue">&lt;</span>/<span style="color: maroon">configSections</span><span style="color: blue">&gt;</span>
  <span style="color: blue">&lt;</span><span style="color: maroon">applicationSettings</span><span style="color: blue">&gt;</span>
      <span style="color: blue">&lt;</span><span style="color: maroon">MyCalcWin.Properties.Settings</span><span style="color: blue">&gt;</span>
          <span style="color: blue">&lt;</span><span style="color: maroon">setting</span> <span style="color: red">name</span>=&quot;<span style="color: blue">UserName</span>&quot; <span style="color: red">serializeAs</span>=&quot;<span style="color: blue">String</span>&quot;<span style="color: blue">&gt;</span>
              <span style="color: blue">&lt;</span><span style="color: maroon">value</span> /<span style="color: blue">&gt;</span>
          <span style="color: blue">&lt;</span>/<span style="color: maroon">setting</span><span style="color: blue">&gt;</span>
      <span style="color: blue">&lt;</span>/<span style="color: maroon">MyCalcWin.Properties.Settings</span><span style="color: blue">&gt;</span>
  <span style="color: blue">&lt;</span>/<span style="color: maroon">applicationSettings</span><span style="color: blue">&gt;</span>
<span style="color: blue">&lt;</span>/<span style="color: maroon">configuration</span><span style="color: blue">&gt;</span></pre>
<p>If you have a close look at the Welcome.Designer.cs file you will find the following line that does the binding for you:</p>
<div style="font-family: courier new; font-size: 9pt"><span style="color: blue">this</span>.UserNameLabel.Text = global::MyCalcWin.Properties.Settings.Default.UserName;</div>
<h3>Let the splash screen appear at startup</h3>
<p>To make the splash screen appear, adjust the Load method of your main form like this:</p>
<div style="font-family: courier new; font-size: 9pt"><span style="color: blue">private</span>&#160;<span style="color: blue">void</span> Form1_Load(<span style="color: blue">object</span> sender, EventArgs e) </p>
<p>{ </p>
<p>&#160; <span style="color: blue">this</span>.Hide(); </p>
<p>&#160; var splashScreen = <span style="color: blue">new</span> Welcome(); </p>
<p>&#160; splashScreen.Show(); </p>
<p>&#160; splashScreen.Update(); </p>
<p>&#160; System.Threading.Thread.Sleep(<span style="color: maroon">5000</span>); </p>
<p>&#160; splashScreen.Close(); </p>
<p>&#160; <span style="color: blue">this</span>.Visible = <span style="color: maroon">true</span>; </p>
<p>} </p>
<p></div>
<p>Now let’s finally wire things up with the setup project.</p>
<h3>Create a custom dialog</h3>
<p>Right click the Setup Project in the solution explorer and select View &gt; User Interface. Right click the Start node in the Install tree and select Add dialog. Choose Textboxes (A) and click OK.</p>
<p><a href="http://devshaped.com/wp-content/uploads/2009/03/clip-image014.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image014" border="0" alt="clip_image014" src="http://devshaped.com/wp-content/uploads/2009/03/clip-image014-thumb.jpg" width="380" height="279" /></a></p>
<p><em>Figure 7 &#8211; Adding a Custom Dialog</em></p>
<p>Drag and drop the new dialog in front of the Confirm Installation node. Select it and change its properties to the following values: </p>
<p><table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="104">
<p><b>Property</b></p>
</td>
<td valign="top" width="515">
<p><b>Value</b></p>
</td>
</tr>
<tr>
<td valign="top" width="104">
<p>BannerText</p>
</td>
<td valign="top" width="515">
<p>Enter your name</p>
</td>
</tr>
<tr>
<td valign="top" width="104">
<p>BodyText</p>
</td>
<td valign="top" width="515">
<p>MyCalc is the only calculator that will welcome you personally on each startup! Just tell it who you are.</p>
</td>
</tr>
<tr>
<td valign="top" width="104">
<p>Edit1Label</p>
</td>
<td valign="top" width="515">
<p>Your name:</p>
</td>
</tr>
<tr>
<td valign="top" width="104">
<p>Edit1Property</p>
</td>
<td valign="top" width="515">
<p>USERNAME</p>
</td>
</tr>
<tr>
<td valign="top" width="104">
<p>Edit2Visible</p>
</td>
<td valign="top" width="515">
<p>False</p>
</td>
</tr>
<tr>
<td valign="top" width="104">
<p>Edit3Visible</p>
</td>
<td valign="top" width="515">
<p>False</p>
</td>
</tr>
<tr>
<td valign="top" width="104">
<p>Edit4Visible</p>
</td>
<td valign="top" width="515">
<p>False</p>
</td>
</tr>
</tbody>
</table>
<p>Now right click again the Setup Project in the solution explorer and select View &gt; Custom Actions. Select Primary Output from MyCalcWin (Active) right under the Install node and change its CustomActionData property value to /userName=&quot;[USERNAME]&quot;.</p>
<h3>Create a new Custom Action</h3>
<p>Now comes the tricky part. We are talking here of at least a .NET 2.0 application. As we already saw, we are working with real type safe and <i>supposedly</i> easy to use settings utilizing the data bound Settings.settings file. Fortunately, .NET already generated a type safe wrapper for us. Unfortunately you cannot access the settings as easily as from within the application due to the fact that the installer simply does not have a mapper for it (and we won’t supply it with one).</p>
<p>What you can do though is this:</p>
<p>Create another custom action as you already did before, call it RegisterUser and replace the generated code with the following:</p>
<div style="font-family: courier new; font-size: 9pt"><span style="color: blue">namespace</span> MyCalcWin.Custom_Actions </p>
<p>{ </p>
<p>&#160; <span style="color: blue">using</span> System.Collections; </p>
<p>&#160; <span style="color: blue">using</span> System.ComponentModel; </p>
<p>&#160; <span style="color: blue">using</span> System.Configuration; </p>
<p>&#160; <span style="color: blue">using</span> System.Configuration.Install; </p>
<p>&#160; <span style="color: blue">using</span> System.Xml; </p>
<p>&#160; [RunInstaller(<span style="color: maroon">true</span>)] </p>
<p>&#160; <span style="color: blue">public</span>&#160;<span style="color: blue">partial</span>&#160;<span style="color: blue">class</span> RegisterUser : Installer </p>
<p>&#160; { </p>
<p>&#160;&#160;&#160; <span style="color: blue">public</span> RegisterUser() </p>
<p>&#160;&#160;&#160; { </p>
<p>&#160;&#160;&#160;&#160;&#160; InitializeComponent(); </p>
<p>&#160;&#160;&#160; } </p>
<p>&#160;&#160;&#160; <span style="color: blue">public</span>&#160;<span style="color: blue">override</span>&#160;<span style="color: blue">void</span> Install(IDictionary stateSaver) </p>
<p>&#160;&#160;&#160; { </p>
<p>&#160;&#160;&#160;&#160;&#160; <span style="color: blue">base</span>.Install(stateSaver); </p>
<p>&#160;&#160;&#160;&#160;&#160; <span style="color: green">// Get username from context</span> </p>
<p>&#160;&#160;&#160;&#160;&#160; var userName = <span style="color: blue">this</span>.Context.Parameters[<span style="color: maroon">&quot;userName&quot;</span>]; </p>
<p>&#160;&#160;&#160;&#160;&#160; <span style="color: green">// Context contains assemblypath by default</span> </p>
<p>&#160;&#160;&#160;&#160;&#160; var assemblyPath = <span style="color: blue">this</span>.Context.Parameters[<span style="color: maroon">&quot;assemblypath&quot;</span>]; </p>
<p>&#160;&#160;&#160;&#160;&#160; <span style="color: green">// Get UserName setting in app.config</span> </p>
<p>&#160;&#160;&#160;&#160;&#160; var config = ConfigurationManager.OpenExeConfiguration(assemblyPath); </p>
<p>&#160;&#160;&#160;&#160;&#160; var sectionGroup = config.GetSectionGroup(<span style="color: maroon">&quot;applicationSettings&quot;</span>); </p>
<p>&#160;&#160;&#160;&#160;&#160; var section = sectionGroup.Sections[<span style="color: maroon">&quot;MyCalcWin.Properties.Settings&quot;</span>]<span style="color: blue">&#160;</span></div>
<div style="font-family: courier new; font-size: 9pt"><span style="color: blue">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; as</span> ClientSettingsSection; </p>
<p>&#160;&#160;&#160;&#160;&#160; var settingElement = section.Settings.Get(<span style="color: maroon">&quot;UserName&quot;</span>); </p>
<p>&#160;&#160;&#160;&#160;&#160; <span style="color: green">// Create new value node</span> </p>
<p>&#160;&#160;&#160;&#160;&#160; var doc = <span style="color: blue">new</span> XmlDocument(); </p>
<p>&#160;&#160;&#160;&#160;&#160; var newValue = doc.CreateElement(<span style="color: maroon">&quot;value&quot;</span>); </p>
<p>&#160;&#160;&#160;&#160;&#160; newValue.InnerText = userName; </p>
<p>&#160;&#160;&#160;&#160;&#160; <span style="color: green">// Set new UserName value</span> </p>
<p>&#160;&#160;&#160;&#160;&#160; settingElement.Value.ValueXml = newValue; </p>
<p>&#160;&#160;&#160;&#160;&#160; <span style="color: green">// Save changes</span> </p>
<p>&#160;&#160;&#160;&#160;&#160; section.SectionInformation.ForceSave = <span style="color: maroon">true</span>; </p>
<p>&#160;&#160;&#160;&#160;&#160; config.Save(ConfigurationSaveMode.Modified); </p>
<p>&#160;&#160;&#160; } </p>
<p>&#160; } </p>
<p>} </div>
<p>As you can see, we can access the Custom Action Data we prepared earlier through the InstallContext Parameters collection. Also the InstallContext already contains a couple of default parameters such as the <i>assemblypath</i> (which we need to access the applications’ configuration file).</p>
<p>What we are doing here is loading the .exe.config file of our application, digging through to the UserName setting, creating a new Xml node containing the username value and finally putting the value into the configuration before we are saving the changes. It is really as easy as that. Wasn’t that obvious?</p>
<p>Now compile and install your application. </p>
<p>The setup will ask you for your username:</p>
<p><a href="http://devshaped.com/wp-content/uploads/2009/03/clip-image016.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image016" border="0" alt="clip_image016" src="http://devshaped.com/wp-content/uploads/2009/03/clip-image016-thumb.jpg" width="402" height="330" /></a></p>
<p><em>Figure 8 &#8211; User registration dialog</em></p>
<p>When starting the calculator, the splash screen welcomes you:</p>
<p><a href="http://devshaped.com/wp-content/uploads/2009/03/clip-image018.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image018" border="0" alt="clip_image018" src="http://devshaped.com/wp-content/uploads/2009/03/clip-image018-thumb.jpg" width="220" height="102" /></a></p>
<p><em>Figure 9 &#8211; Actual splash screen</em> </p>
<h2>Alternatives</h2>
<p>Over and above the samples you saw so far there are several alternatives to using the Installer Class provided by Visual Studio. One is using native C++ (the languageWindows Installer is actually developed in, which is why it is the most powerful way of implementing custom actions). Explaining how that works is out of the scope of this article, but you can read about it for example on Steven Bone’s Blog who published three absolutely awesome articles about it <a href="http://bonemanblog.blogspot.com/2005/10/custom-action-tutorial-part-i-custom.html">here</a>.</p>
<p>A native custom action that accesses the MSI log for instance basically looks like this:</p>
<pre style="font-size: 9pt">

<span style="color: blue">extern</span> <span style="color: maroon">&quot;C&quot;</span> UINT __stdcall Install(MSIHANDLE hInstall)
{
  PMSIHANDLE hRecord = MsiCreateRecord(<span style="color: maroon">0</span>);
  MsiRecordSetString(hRecord, <span style="color: maroon">0</span>, TEXT(<span style="color: maroon">&quot;Native C++ is better than Installer Class!&quot;</span>));
  MsiProcessMessage(hInstall, INSTALLMESSAGE(INSTALLMESSAGE_INFO), hRecord);
  <span style="color: blue">return</span> ERROR_SUCCESS;
}
</pre>
<p>Using DTF (Deployment Tools Foundation), which is part of the Windows Installer Xml Toolset, enables you to implement Custom Actions with managed code. However, you need to make sure .NET Framework is already installed on the computer you are running the setup on and also have a couple of prerequisites to fulfill.</p>
<p><table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="242">
<p><b>Action</b></p>
</td>
<td valign="top" width="105">
<p align="center"><b>Installer Class</b></p>
</td>
<td valign="top" width="112">
<p align="center"><b>Native C++ DLL</b></p>
</td>
<td valign="top" width="73">
<p align="center"><b>WiX DTF</b></p>
</td>
</tr>
<tr>
<td valign="top" width="242">
<p><b>Run in UI sequence</b></p>
</td>
<td valign="top" width="105">&#160;</td>
<td valign="top" width="112">
<p align="center">X</p>
</td>
<td valign="top" width="73">
<p align="center">X</p>
</td>
</tr>
<tr>
<td valign="top" width="242">
<p><b>Run immediate in execute sequence</b></p>
</td>
<td valign="top" width="105">&#160;</td>
<td valign="top" width="112">
<p align="center">X</p>
</td>
<td valign="top" width="73">
<p align="center">X</p>
</td>
</tr>
<tr>
<td valign="top" width="242">
<p><b>Run deferred in execute sequence</b></p>
</td>
<td valign="top" width="105">
<p align="center">X</p>
</td>
<td valign="top" width="112">
<p align="center">X</p>
</td>
<td valign="top" width="73">
<p align="center">X</p>
</td>
</tr>
<tr>
<td valign="top" width="242">
<p><b>Read MSI properties</b></p>
</td>
<td valign="top" width="105">
<p align="center">X<a href="#_ftn1_1368" name="_ftnref1_1368">[1]</a></p>
</td>
<td valign="top" width="112">
<p align="center">X</p>
</td>
<td valign="top" width="73">
<p align="center">X</p>
</td>
</tr>
<tr>
<td valign="top" width="242">
<p><b>Write MSI properties</b></p>
</td>
<td valign="top" width="105">&#160;</td>
<td valign="top" width="112">
<p align="center">X</p>
</td>
<td valign="top" width="73">
<p align="center">X</p>
</td>
</tr>
<tr>
<td valign="top" width="242">
<p><b>Debuggable</b></p>
</td>
<td valign="top" width="105">
<p align="center">X</p>
</td>
<td valign="top" width="112">
<p align="center">X</p>
</td>
<td valign="top" width="73">
<p align="center">X <a href="#_ftn2_1368" name="_ftnref2_1368">[2]</a></p>
</td>
</tr>
<tr>
<td valign="top" width="242">
<p><b>Access MSI Logfile</b></p>
</td>
<td valign="top" width="105">&#160;</td>
<td valign="top" width="112">
<p align="center">X</p>
</td>
<td valign="top" width="73">
<p align="center">X</p>
</td>
</tr>
<tr>
<td valign="top" width="242">
<p><b>Access Installstate log</b></p>
</td>
<td valign="top" width="105">
<p align="center">X</p>
</td>
<td valign="top" width="112">&#160;</td>
<td valign="top" width="73">&#160;</td>
</tr>
<tr>
<td valign="top" width="242">
<p><b>.NET Framework must be installed</b></p>
</td>
<td valign="top" width="105">
<p align="center">X</p>
</td>
<td valign="top" width="112">&#160;</td>
<td valign="top" width="73">
<p align="center">X</p>
</td>
</tr>
<tr>
<td valign="top" width="242">
<p><b>Windows Installer Xml must be installed</b></p>
</td>
<td valign="top" width="105">&#160;</td>
<td valign="top" width="112">&#160;</td>
<td valign="top" width="73">
<p align="center">X</p>
</td>
</tr>
</tbody>
</table>
<h2>Conclusion</h2>
<p>In many cases, installation needs are straightforward enough that it is not worth the effort to implement anything more complex than the Custom Actions that run deferred in system context. Although you gain more control over the installation process when you choose to implement <i>Windows Installer Xml</i> based <i>Custom Actions</i> or native CA’s, <em>Installer </em>class based <i>Custom Actions</i> can be a great way to extend your Visual Studio based <i>Setup Project</i> without the need to invest in additional installer solutions.</p>
<hr align="left" size="1" width="33%" />
<p><a href="#_ftnref1_1368" name="_ftn1_1368">[1]</a> Through stateSaver dictionary collection</p>
<p><a href="#_ftnref2_1368" name="_ftn2_1368">[2]</a> Simple unit testing possibility via wrapping the MSI session</p>
<p>&#8212;&#8211;</p>
<p>Christian Jacob is an IT Consultant with TOP TECHNOLOGIES CONSULTING, a Microsoft Gold Partner with focus on infrastructures, security and business solutions. He primarily uses C# and VB.NET in nowadays development and&#160; has his roots in C++ based game development. He spends a lot of time in researching and creating innovative solutions around team development, Windows Installer, and TOP TECHNOLOGIES’ main software products. He currently resides nearby Hamburg in North Germany.</p>
]]></content:encoded>
			<wfw:commentRss>http://devshaped.com/2009/04/creating-useful-installers-with-custom-actions/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Banking with XML</title>
		<link>http://devshaped.com/2009/03/banking-with-xml/</link>
		<comments>http://devshaped.com/2009/03/banking-with-xml/#comments</comments>
		<pubDate>Sun, 01 Mar 2009 10:00:00 +0000</pubDate>
		<dc:creator>Derek</dc:creator>
				<category><![CDATA[Practical Programming]]></category>

		<guid isPermaLink="false">http://devshaped.com/?p=45</guid>
		<description><![CDATA[By Peter Jones
 Remember XML? Remember those fun times you had creating XML data files, XSL&#8217;s and DTD&#8217;s using Notepad? It seemed like such a great thing to do. There were grandiose plans to save the world with markup.
Today, XML is just another file format thanks to great tools and (reasonably well followed) standards. The [...]]]></description>
			<content:encoded><![CDATA[<p>By <a href="http://jonesie.net.nz" target="_blank">Peter Jones</a></p>
<p><img style="border-right-width: 0px; margin: 0px 0px 22px 22px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="peter_jones" border="0" alt="peter_jones" align="right" src="http://devshaped.com/wp-content/uploads/2009/02/peter-jones.jpg" width="85" height="57" /> Remember XML? Remember those fun times you had creating XML data files, <a href="http://en.wikipedia.org/wiki/Extensible_Stylesheet_Language">XSL</a>&#8217;s and <a href="http://en.wikipedia.org/wiki/Document_Type_Definition">DTD</a>&#8217;s using Notepad? It seemed like such a great thing to do. There were grandiose plans to save the world with markup.</p>
<p>Today, XML is just another file format thanks to great tools and (reasonably well followed) standards. The tools in Visual Studio do such a great job of encapsulating XML that we often forget that it even exists under the covers. </p>
<p>And then along comes a scenario where you need to dig deep and reach for those reference manuals (or search engine). Recently I had just such a challenge.</p>
<p><span id="more-45"></span></p>
<h2>The Mission</h2>
<p>Create a site for Students and Law Professionals to register for seminars offered by a law college. Seminar attendees would pay for seminars using a credit card. Payments would be processed online by the college&#8217;s bank. </p>
<h2>The Solution</h2>
<p>The web site was created using ASP.NET MVC, Visual Studio 2008 and SQL Server 2005. The college&#8217;s bank provided various documents to describe their payment gateway interface which supports payment by the usual credit cards, plus credit transactions and other services. For this site we only required the payment service.</p>
<h2>Principals</h2>
<p>The .NET Framework is <a href="http://blogs.msdn.com/brada/archive/2008/03/17/number-of-types-in-the-net-framework.aspx">huge</a>. It contains over 11,000 types (classes, structs, etc). You can bet your bottom dollar that there are several ways to do just about any task you choose. My overriding principal when creating any coded solution is to use the clearest and easiest to maintain code. Performance and elegance normally come second to this &#8211; mostly because of the types of applications I create but also because simple code is usually better code.</p>
<h2>Getting Setup</h2>
<p>For this exercise I have created a sample web service and client web site to test it. You can <a href="/wp-content/uploads/2009/02/jonesiespaymentgateway.zip">download the complete sample code from here</a>. This sample includes a complete standalone project for processing payments with a test payment gateway. With a bit of work you should be able to easily adapt this for a real payment gateway of your choice. </p>
<p>In the remainder of this article I will be focusing on the <b>PaymentGatewayFormatter</b> class from the sample. A full explanation of the sample code is beyond the scope of this article but please feel free to drop me a line if you have any questions or suggestions.</p>
<h2>The Problem</h2>
<p>In these enlightened times, we tend to expect &#8217;standard&#8217; web services to be made available for just about everything. Connecting to such a web service is trivial if you can use Visual Studio or the .NET SDK WSDL tool to generate the interface proxy for you. However, in this case, the bank provided only the following:</p>
<ul>
<li>A <a href="http://en.wikipedia.org/wiki/REST">REST</a> style web service sending and receiving plain old XML (<a href="http://en.wikipedia.org/wiki/Plain_Old_XML">POX</a>) with no <a href="http://en.wikipedia.org/wiki/Web_Services_Description_Language">WSDL</a>. </li>
<li>A PDF document describing the service architecture, rules for usage, sample XML request/response messages, and DTD schemas. </li>
<li>A PDF document describing the HTTP/XML and Java interfaces. </li>
</ul>
<p>And that was it &#8211; nothing for .NET, no XSD, no WSDL and no SOAP. A call to the bank requesting a .NET interface resulted in a one word answer, which you can probably guess!</p>
<h2>The Implementation</h2>
<p>After some research and experimentation with Windows Communication Foundation (<a href="http://en.wikipedia.org/wiki/Windows_Communication_Foundation">WCF</a>) and Web Service Contract First (<a href="http://www.thinktecture.com/resourcearchive/tools-and-software/wscf">WSCF</a>) and with limited time to create the interface, I opted for a hand coded implementation using low level framework support and <a href="http://msdn.microsoft.com/library/system.net.httpwebrequest.aspx">HTTPWebRequest</a>.</p>
<h2>The Specification</h2>
<p>The bank provided sample request and response messages as below:</p>
<p><strong>Sample Request:</strong></p>
<pre><span style="color: blue">&lt;?</span><span style="color: maroon">xml</span> <span style="color: red">version</span>=&quot;<span style="color: blue">1.0</span>&quot; <span style="color: red">encoding</span>=&quot;<span style="color: blue">UTF-8</span>&quot;<span style="color: blue">?&gt;</span>
<span style="color: blue">&lt;</span><span style="color: maroon">TransactMessage</span><span style="color: blue">&gt;</span>
  <span style="color: blue">&lt;</span><span style="color: maroon">MessageInfo</span><span style="color: blue">&gt;</span>
    <span style="color: blue">&lt;</span><span style="color: maroon">messageID</span><span style="color: blue">&gt;</span>8af793f9af34bea0cf40f5fb5c630c<span style="color: blue">&lt;</span>/<span style="color: maroon">messageID</span><span style="color: blue">&gt;</span>
  <span style="color: blue">&lt;</span>/<span style="color: maroon">MessageInfo</span><span style="color: blue">&gt;</span>
  <span style="color: blue">&lt;</span><span style="color: maroon">MerchantInfo</span><span style="color: blue">&gt;</span>
    <span style="color: blue">&lt;</span><span style="color: maroon">merchantID</span><span style="color: blue">&gt;</span>123456<span style="color: blue">&lt;</span>/<span style="color: maroon">merchantID</span><span style="color: blue">&gt;</span>
    <span style="color: blue">&lt;</span><span style="color: maroon">password</span><span style="color: blue">&gt;</span>password<span style="color: blue">&lt;</span>/<span style="color: maroon">password</span><span style="color: blue">&gt;</span>
  <span style="color: blue">&lt;</span>/<span style="color: maroon">MerchantInfo</span><span style="color: blue">&gt;</span>
  <span style="color: blue">&lt;</span><span style="color: maroon">RequestType</span><span style="color: blue">&gt;</span>Payment<span style="color: blue">&lt;</span>/<span style="color: maroon">RequestType</span><span style="color: blue">&gt;</span>
  <span style="color: blue">&lt;</span><span style="color: maroon">Payment</span><span style="color: blue">&gt;</span>
    <span style="color: blue">&lt;</span><span style="color: maroon">TxnList</span> <span style="color: red">count</span>=&quot;<span style="color: blue">1</span>&quot;<span style="color: blue">&gt;</span>
      <span style="color: blue">&lt;</span><span style="color: maroon">Txn</span> <span style="color: red">ID</span>=&quot;<span style="color: blue">1</span>&quot;<span style="color: blue">&gt;</span>
        <span style="color: blue">&lt;</span><span style="color: maroon">txnType</span><span style="color: blue">&gt;</span>0<span style="color: blue">&lt;</span>/<span style="color: maroon">txnType</span><span style="color: blue">&gt;</span>
        <span style="color: blue">&lt;</span><span style="color: maroon">amount</span><span style="color: blue">&gt;</span>1000<span style="color: blue">&lt;</span>/<span style="color: maroon">amount</span><span style="color: blue">&gt;</span>
        <span style="color: blue">&lt;</span><span style="color: maroon">purchaseOrderNo</span><span style="color: blue">&gt;</span>test<span style="color: blue">&lt;</span>/<span style="color: maroon">purchaseOrderNo</span><span style="color: blue">&gt;</span>
        <span style="color: blue">&lt;</span><span style="color: maroon">CreditCardInfo</span><span style="color: blue">&gt;</span>
          <span style="color: blue">&lt;</span><span style="color: maroon">cardNumber</span><span style="color: blue">&gt;</span>4444333322221111<span style="color: blue">&lt;</span>/<span style="color: maroon">cardNumber</span><span style="color: blue">&gt;</span>
          <span style="color: blue">&lt;</span><span style="color: maroon">expiryDate</span><span style="color: blue">&gt;</span>08/12<span style="color: blue">&lt;</span>/<span style="color: maroon">expiryDate</span><span style="color: blue">&gt;</span>
        <span style="color: blue">&lt;</span>/<span style="color: maroon">CreditCardInfo</span><span style="color: blue">&gt;</span>
      <span style="color: blue">&lt;</span>/<span style="color: maroon">Txn</span><span style="color: blue">&gt;</span>
    <span style="color: blue">&lt;</span>/<span style="color: maroon">TxnList</span><span style="color: blue">&gt;</span>
  <span style="color: blue">&lt;</span>/<span style="color: maroon">Payment</span><span style="color: blue">&gt;</span>
<span style="color: blue">&lt;</span>/<span style="color: maroon">TransactMessage</span><span style="color: blue">&gt;</span></pre>
<p><strong>Sample Response:</strong></p>
<pre><span style="color: blue">&lt;?</span><span style="color: maroon">xml</span> <span style="color: red">version</span>=&quot;<span style="color: blue">1.0</span>&quot; <span style="color: red">encoding</span>=&quot;<span style="color: blue">UTF-8</span>&quot;<span style="color: blue">?&gt;</span>
<span style="color: blue">&lt;</span><span style="color: maroon">TransactMessage</span><span style="color: blue">&gt;</span>
  <span style="color: blue">&lt;</span><span style="color: maroon">MessageInfo</span><span style="color: blue">&gt;</span>
    <span style="color: blue">&lt;</span><span style="color: maroon">messageID</span><span style="color: blue">&gt;</span>b9cffb095b4f460fb0d60be85975b600<span style="color: blue">&lt;</span>/<span style="color: maroon">messageID</span><span style="color: blue">&gt;</span>
  <span style="color: blue">&lt;</span>/<span style="color: maroon">MessageInfo</span><span style="color: blue">&gt;</span>
  <span style="color: blue">&lt;</span><span style="color: maroon">RequestType</span><span style="color: blue">&gt;</span>Payment<span style="color: blue">&lt;</span>/<span style="color: maroon">RequestType</span><span style="color: blue">&gt;</span>
  <span style="color: blue">&lt;</span><span style="color: maroon">Status</span><span style="color: blue">&gt;</span>
    <span style="color: blue">&lt;</span><span style="color: maroon">statusCode</span><span style="color: blue">&gt;</span>000<span style="color: blue">&lt;</span>/<span style="color: maroon">statusCode</span><span style="color: blue">&gt;</span>
    <span style="color: blue">&lt;</span><span style="color: maroon">statusDescription</span><span style="color: blue">&gt;</span>Normal<span style="color: blue">&lt;</span>/<span style="color: maroon">statusDescription</span><span style="color: blue">&gt;</span>
  <span style="color: blue">&lt;</span>/<span style="color: maroon">Status</span><span style="color: blue">&gt;</span>
  <span style="color: blue">&lt;</span><span style="color: maroon">MerchantInfo</span><span style="color: blue">&gt;</span>
    <span style="color: blue">&lt;</span><span style="color: maroon">merchantID</span><span style="color: blue">&gt;</span>123456<span style="color: blue">&lt;</span>/<span style="color: maroon">merchantID</span><span style="color: blue">&gt;</span>
  <span style="color: blue">&lt;</span>/<span style="color: maroon">MerchantInfo</span><span style="color: blue">&gt;</span>
  <span style="color: blue">&lt;</span><span style="color: maroon">Payment</span><span style="color: blue">&gt;</span>
    <span style="color: blue">&lt;</span><span style="color: maroon">TxnList</span> <span style="color: red">count</span>=&quot;<span style="color: blue">1</span>&quot;<span style="color: blue">&gt;</span>
      <span style="color: blue">&lt;</span><span style="color: maroon">Txn</span> <span style="color: red">ID</span>=&quot;<span style="color: blue">1</span>&quot;<span style="color: blue">&gt;</span>
        <span style="color: blue">&lt;</span><span style="color: maroon">txnType</span><span style="color: blue">&gt;</span>0<span style="color: blue">&lt;</span>/<span style="color: maroon">txnType</span><span style="color: blue">&gt;</span>
        <span style="color: blue">&lt;</span><span style="color: maroon">amount</span><span style="color: blue">&gt;</span>1000<span style="color: blue">&lt;</span>/<span style="color: maroon">amount</span><span style="color: blue">&gt;</span>
        <span style="color: blue">&lt;</span><span style="color: maroon">purchaseOrderNo</span><span style="color: blue">&gt;</span>test<span style="color: blue">&lt;</span>/<span style="color: maroon">purchaseOrderNo</span><span style="color: blue">&gt;</span>
        <span style="color: blue">&lt;</span><span style="color: maroon">approved</span><span style="color: blue">&gt;</span>Yes<span style="color: blue">&lt;</span>/<span style="color: maroon">approved</span><span style="color: blue">&gt;</span>
        <span style="color: blue">&lt;</span><span style="color: maroon">responseCode</span><span style="color: blue">&gt;</span>00<span style="color: blue">&lt;</span>/<span style="color: maroon">responseCode</span><span style="color: blue">&gt;</span>
        <span style="color: blue">&lt;</span><span style="color: maroon">responseText</span><span style="color: blue">&gt;</span>Approved<span style="color: blue">&lt;</span>/<span style="color: maroon">responseText</span><span style="color: blue">&gt;</span>
        <span style="color: blue">&lt;</span><span style="color: maroon">txnID</span><span style="color: blue">&gt;</span>009844<span style="color: blue">&lt;</span>/<span style="color: maroon">txnID</span><span style="color: blue">&gt;</span>
        <span style="color: blue">&lt;</span><span style="color: maroon">CreditCardInfo</span><span style="color: blue">&gt;</span>
          <span style="color: blue">&lt;</span><span style="color: maroon">pan</span><span style="color: blue">&gt;</span>444433...111<span style="color: blue">&lt;</span>/<span style="color: maroon">pan</span><span style="color: blue">&gt;</span>
          <span style="color: blue">&lt;</span><span style="color: maroon">expiryDate</span><span style="color: blue">&gt;</span>08/12<span style="color: blue">&lt;</span>/<span style="color: maroon">expiryDate</span><span style="color: blue">&gt;</span>
          <span style="color: blue">&lt;</span><span style="color: maroon">cardType</span><span style="color: blue">&gt;</span>6<span style="color: blue">&lt;</span>/<span style="color: maroon">cardType</span><span style="color: blue">&gt;</span>
          <span style="color: blue">&lt;</span><span style="color: maroon">cardDescription</span><span style="color: blue">&gt;</span>Visa<span style="color: blue">&lt;</span>/<span style="color: maroon">cardDescription</span><span style="color: blue">&gt;</span>
        <span style="color: blue">&lt;</span>/<span style="color: maroon">CreditCardInfo</span><span style="color: blue">&gt;</span>
      <span style="color: blue">&lt;</span>/<span style="color: maroon">Txn</span><span style="color: blue">&gt;</span>
    <span style="color: blue">&lt;</span>/<span style="color: maroon">TxnList</span><span style="color: blue">&gt;</span>
  <span style="color: blue">&lt;</span>/<span style="color: maroon">Payment</span><span style="color: blue">&gt;</span>
<span style="color: blue">&lt;</span>/<span style="color: maroon">TransactMessage</span><span style="color: blue">&gt;</span></pre>
<p>My first inclination was to create XSD files using these samples. Visual Studio made this easy to achieve. With the sample XML files open in Visual Studio I selected the Create Schema option from the XML menu. This produced an accurate XSD file. However, this was not much use by itself. I needed to create a C# class to include in my web site that would enable serialization of XML to and from the payment gateway.</p>
<p>The command line WSDL tool provided in the .NET Framework SDK does a great job of generating code for just this purpose. But in this case it was not so useful. Note that the request and response messages both have a root node of &lt;TransactionMessage&gt;. When I generated the C# classes from the generated XSD files, I had duplicate classes in the files for TransactionMessage, MessageInfo, Status etc. Fixing this would have required hand coding of the schema to include request and response messages, or merging of the generated classes. This felt like a lot of error-prone work.</p>
<h2>XmlTextWriter</h2>
<p>All I really wanted was a simple way to send a bunch of XML to a web site and read the response. The XML was not particularly complex or large so I opted to create the request using <a href="http://msdn.microsoft.com/library/system.xml.xmltextwriter.aspx">XmlTextWriter</a>.</p>
<p>XmlTextWriter could not be any easier. I&#8217;ll explain how to use it in the steps below.</p>
<p>1)&#160;&#160; Create a method to compose the required XML. I use a custom object, PaymentRequest to encapsulate the details of the request.</p>
<div style="font-family: courier new"><span style="color: blue">public</span>&#160;<span style="color: blue">string</span> GetPaymentRequestXML(PaymentRequest request) </p>
<p>{&#160; </p>
<p>}&#160; </p>
</div>
<p><span>(All of the following code belongs inside this method).</span></p>
<p>2)&#160;&#160; Create a stream for the XmlTextWriter to write to.</p>
<div style="font-family: courier new">MemoryStream ms = <span style="color: blue">new</span> MemoryStream(); </div>
<p>3)&#160;&#160; Create an instance of an XmlTextWriter. Note the use of UTF8 encoding to match the sample XML file. </p>
<div style="font-family: courier new">XmlTextWriter writer = <span style="color: blue">new</span> XmlTextWriter(ms, System.Text.Encoding.UTF8); </div>
<p>4)&#160;&#160; Use the XmlTextWriter to write elements and attributes to the stream. XmlTextWriter provides methods that produce validated elements only. For your example, we begin with the root node, <span style="line-height: 110%; font-family: &quot;Courier New&quot;; color: #a31515">TransactMessage</span><span>:</span> </p>
<div style="font-family: courier new">writer.WriteStartElement(<span style="color: maroon">&quot;TransactMessage&quot;</span>); </div>
<p>Every element that is started must be ended:</p>
<p style="line-height: normal; margin: 0in 0in 0pt"><span style="font-family: &quot;Courier New&quot;">writer.WriteEndElement(); <span style="color: green">// TransactMessage</span></span> </p>
<p>I find it less error prone to always create the start and end element method calls in pairs, and build the structure from the outside in &#8211; much like matching curly-braces in C#. Adding a comment to the WriteEndElement method call will also help you remember what you are ending. For example:</p>
<div style="font-family: courier new">writer.WriteStartElement(<span style="color: maroon">&quot;MessageInfo&quot;</span>);&#160; <br />writer.WriteElementString(<span style="color: maroon">&quot;messageID&quot;</span>, </div>
<div style="font-family: courier new">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; request.MessageID.ToString(<span style="color: maroon">&quot;N&quot;</span>));&#160; <br />writer.WriteEndElement(); <span style="color: green">// MessageInfo </span></div>
<p>This will produce the following XML in the output stream:</p>
<pre><span style="color: blue">&lt;</span><span style="color: maroon">MessageInfo</span><span style="color: blue">&gt;</span>
<span style="color: blue">&lt;</span><span style="color: maroon">messageID</span><span style="color: blue">&gt;</span>8af793f9af34bea0cf40f5fb5c630c<span style="color: blue">&lt;</span>/<span style="color: maroon">messageID</span><span style="color: blue">&gt;</span>
<span style="color: blue">&lt;</span>/<span style="color: maroon">MessageInfo</span><span style="color: blue">&gt;</span> </pre>
<p>Use WriteElementString to create a complete element with a simple string as its inner xml value. To create an attribute on the current element simply follow the WriteStartElement call with WriteAttributeString.</p>
<div style="font-family: courier new">writer.WriteStartElement(<span style="color: maroon">&quot;TxnList&quot;</span>);&#160; <br />writer.WriteAttributeString(<span style="color: maroon">&quot;count&quot;</span>, <span style="color: maroon">&quot;1&quot;</span>);&#160; </div>
<p>5)&#160;&#160; Flush the writer.</p>
<div style="font-family: courier new">writer.Flush(); </div>
<p>6)&#160;&#160; Convert the stream to a string and return it.</p>
<div style="font-family: courier new"><span style="color: blue">string</span> xml = <span style="color: blue">null</span>;&#160; <br /><span style="color: blue">using</span> (StreamReader sr = <span style="color: blue">new</span> StreamReader(ms))&#160; <br />{ </p>
<p>&#160; ms.Seek(<span style="color: maroon">0</span>, SeekOrigin.Begin);&#160; <br />&#160; xml = sr.ReadToEnd();&#160; <br />}&#160; <br /><span style="color: blue">return</span> xml;&#160; </p>
</div>
<p>And that&#8217;s about it. XmlTextWriter has many more useful methods to deal with namespaces and other standard XML features, but for this simple example these are not required.</p>
<h2>XmlReader</h2>
<p>Writing an XML file is very simple. Reading one, unfortunately, is not quite as straight forward. The main issue is that you cannot assume the order of elements will totally match your expectations. In our Bank of Jones sample it may be quite feasible to receive a response with the MessageInfo, Status and MerchantInfo elements in any order. </p>
<p>XmlReader allows you to read elements in an expected order, in much the same way as you would write them with XmlTextWriter. This may work for a while but when dealing with external systems there is no guarantee that it will work forever. In fact, when dealing with banks, it&#8217;s a very good idea to assume it will change at random and you will only know about this when your client code fails!</p>
<p>Fortunately, there is a way to deal with this. XmlReader allows you to processes the XML serially. An example is the best way to describe this. Here are the steps.</p>
<p>1)&#160;&#160; Create an empty method to process the response stream.</p>
<div style="font-family: courier new"><span style="color: blue">public</span> PaymentResponse ReadPaymentResponse(Stream input)&#160; <br />{ </p>
<p>}</div>
<p>2)&#160;&#160; Create an XmlReader instance, and somewhere to store the de-serialized response data. In my case this is a PaymentResponse object.</p>
<div style="font-family: courier new">PaymentResponse rsp = <span style="color: blue">new</span> PaymentResponse();&#160; <br />XmlReader reader = XmlReader.Create(input);&#160; <br />rsp.Status = PaymentResponse.StatusEnum.Incomplete; </div>
<p>3)&#160;&#160; Read through the input stream using reader.Read() which will read through the input XML one &#8216;item&#8217; at a time. The item could be a start element, an attribute, an end element, comment, white space and more. Each time you call .Read() it advanced the internal pointer of the reader to the next item and sets a number of properties that you can use to determine exactly what the reader is pointing at. This is a very efficient way of parsing large XML files/streams because it is a forward only, read only mechanism.</p>
<p>Below is the main code I use to process the input stream. </p>
<div style="font-family: courier new"><span style="color: blue">while</span> (reader.Read()) </p>
<p>{ </p>
<p>&#160; <span style="color: blue">if</span> (reader.NodeType == XmlNodeType.Element) </p>
<p>&#160; { </p>
<p>&#160;&#160;&#160; <span style="color: blue">if</span> (reader.Name == <span style="color: maroon">&quot;TransactMessage&quot;</span>) </p>
<p>&#160;&#160;&#160; { </p>
<p>&#160;&#160;&#160;&#160;&#160; <span style="color: blue">while</span> (reader.Read()) </p>
<p>&#160;&#160;&#160;&#160;&#160; { </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">if</span> (reader.NodeType == XmlNodeType.Element &amp;&amp; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; reader.Name == <span style="color: maroon">&quot;MessageInfo&quot;</span>) </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; { </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; readMessageInfo(rsp, reader); </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; } </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">else</span>&#160;<span style="color: blue">if</span> (reader.NodeType == XmlNodeType.Element &amp;&amp; </div>
<div style="font-family: courier new">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; reader.Name == <span style="color: maroon">&quot;RequestType&quot;</span>) </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; { </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; reader.Read(); </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; rsp.RequestType = reader.Value; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; } </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">else</span>&#160;<span style="color: blue">if</span> (reader.Name == <span style="color: maroon">&quot;MerchantInfo&quot;</span>) </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; { </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; readMerchantInfo(rsp, reader); </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; } </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">else</span>&#160;<span style="color: blue">if</span> (reader.Name == <span style="color: maroon">&quot;Status&quot;</span>) </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; { </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; readStatus(rsp, reader); </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; } </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">else</span>&#160;<span style="color: blue">if</span> (reader.Name == <span style="color: maroon">&quot;Payment&quot;</span>) </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; { </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; readPayment(rsp, reader); </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; } </p>
<p>&#160;&#160;&#160;&#160;&#160; } </p>
<p>&#160;&#160;&#160; } </p>
<p>&#160; } </p>
<p>} </div>
<p>This code uses a number of sub-processing methods that also advance the cursor through the input stream (I have excluded these from here for brevity but you can examine them in the sample source code provided). Breaking the processing method into smaller chunks like this makes the methods much clearer.</p>
<p>Below is the helper method to update the PaymentResponse with the CreditCardInfo node. The other processing methods follow the same pattern of looping until the node ends.</p>
<div style="font-family: courier new"><span style="color: blue">private</span>&#160;<span style="color: blue">static</span>&#160;<span style="color: blue">void</span> readCardInfo(PaymentResponse rsp, XmlReader reader) </p>
<p>{ </p>
<p>&#160; <span style="color: blue">while</span> (reader.Read()) </p>
<p>&#160; { </p>
<p>&#160;&#160;&#160; <span style="color: blue">if</span> (reader.NodeType == XmlNodeType.Element) </p>
<p>&#160;&#160;&#160; { </p>
<p>&#160;&#160;&#160;&#160;&#160; <span style="color: blue">if</span> (reader.Name == <span style="color: maroon">&quot;pan&quot;</span>) </p>
<p>&#160;&#160;&#160;&#160;&#160; { </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; reader.Read(); </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; rsp.CardNumber = reader.Value; </p>
<p>&#160;&#160;&#160;&#160;&#160; } </p>
<p>&#160;&#160;&#160;&#160;&#160; <span style="color: blue">else</span>&#160;<span style="color: blue">if</span> (reader.Name == <span style="color: maroon">&quot;expiryDate&quot;</span>) </p>
<p>&#160;&#160;&#160;&#160;&#160; { </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; reader.Read(); </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; rsp.Expiry = reader.Value; </p>
<p>&#160;&#160;&#160;&#160;&#160; } </p>
<p>&#160;&#160;&#160;&#160;&#160; <span style="color: blue">else</span>&#160;<span style="color: blue">if</span> (reader.Name == <span style="color: maroon">&quot;cardType&quot;</span>) </p>
<p>&#160;&#160;&#160;&#160;&#160; { </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; reader.Read(); </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; rsp.CardType = reader.Value; </p>
<p>&#160;&#160;&#160;&#160;&#160; } </p>
<p>&#160;&#160;&#160;&#160;&#160; <span style="color: blue">else</span>&#160;<span style="color: blue">if</span> (reader.Name == <span style="color: maroon">&quot;cardDescription&quot;</span>) </p>
<p>&#160;&#160;&#160;&#160;&#160; { </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; reader.Read(); </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; rsp.CardDescription = reader.Value; </p>
<p>&#160;&#160;&#160;&#160;&#160; } </p>
<p>&#160;&#160;&#160; } </p>
<p>&#160;&#160;&#160; <span style="color: blue">else</span>&#160;<span style="color: blue">if</span> (reader.NodeType == XmlNodeType.EndElement &amp;&amp; </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; reader.Name == <span style="color: maroon">&quot;CreditCardInfo&quot;</span>) </p>
<p>&#160;&#160;&#160; { </p>
<p>&#160;&#160;&#160;&#160;&#160; <span style="color: blue">break</span>; </p>
<p>&#160;&#160;&#160; } </p>
<p>&#160; } </p>
<p>} </p>
<p></div>
<h2>Alternatives</h2>
<p>The .NET Framework provides several ways of reading and writing XML files. The &#8216;legacy&#8217; method is to use XmlDocument. This still works well but tends to be rather inefficient, especially with large XML files. The construction of the XML with XmlDocument is simple but not as intuitive as with XmlTextWriter. Reading of data from XmlDocument generally requires navigating through the structure using XPath queries. </p>
<p>If the 3.5 version of the .NET Framework, the new XDocument provided with LINQ is an excellent option. Using XDocument I could construct the payment transaction thus:</p>
<div style="font-family: courier new">XDocument doc = <span style="color: blue">new</span> XDocument( </p>
<p>&#160; <span style="color: blue">new</span> XDeclaration(<span style="color: maroon">&quot;1.0&quot;</span>, Encoding.UTF8.HeaderName, <span style="color: blue">string</span>.Empty), </p>
<p>&#160;&#160;&#160; <span style="color: blue">new</span> XElement(<span style="color: maroon">&quot;TransactMessage&quot;</span>, </p>
<p>&#160;&#160;&#160;&#160;&#160; <span style="color: blue">new</span> XElement(<span style="color: maroon">&quot;MessageInfo&quot;</span>, </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">new</span> XElement(<span style="color: maroon">&quot;messageID&quot;</span>, request.MessageID.ToString(<span style="color: maroon">&quot;N&quot;</span>)) </p>
<p>&#160;&#160;&#160;&#160;&#160; ), </p>
<p>&#160;&#160;&#160;&#160;&#160; <span style="color: blue">new</span> XElement(<span style="color: maroon">&quot;MerchantInfo&quot;</span>, </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">new</span> XElement(<span style="color: maroon">&quot;merchantID&quot;</span>, MerchantID), </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">new</span> XElement(<span style="color: maroon">&quot;password&quot;</span>, Password) </p>
<p>&#160;&#160;&#160;&#160;&#160; ), </p>
<p>&#160;&#160;&#160;&#160;&#160; <span style="color: blue">new</span> XElement(<span style="color: maroon">&quot;RequestType&quot;</span>, PAYMENT_REQUEST_TYPE), </p>
<p>&#160;&#160;&#160;&#160;&#160; <span style="color: blue">new</span> XElement(<span style="color: maroon">&quot;Payment&quot;</span>, </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">new</span> XElement(<span style="color: maroon">&quot;TxnList&quot;</span>, </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">new</span> XAttribute(<span style="color: maroon">&quot;count&quot;</span>, <span style="color: maroon">&quot;1&quot;</span>), </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">new</span> XElement(<span style="color: maroon">&quot;Txn&quot;</span>, </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">new</span> XAttribute(<span style="color: maroon">&quot;ID&quot;</span>, <span style="color: maroon">&quot;1&quot;</span>), </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">new</span> XElement(<span style="color: maroon">&quot;txnType&quot;</span>, <span style="color: maroon">&quot;0&quot;</span>), </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">new</span> XElement(<span style="color: maroon">&quot;amount&quot;</span>, </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; (request.Amount * <span style="color: maroon">100</span>).ToString(<span style="color: maroon">&quot;##########&quot;</span>)), </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">new</span> XElement(<span style="color: maroon">&quot;purchaseOrderNo&quot;</span>, request.OrderNumber), </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">new</span> XElement(<span style="color: maroon">&quot;CreditCardInfo&quot;</span>, </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">new</span> XElement(<span style="color: maroon">&quot;cardNumber&quot;</span>, request.CardNumber), </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">new</span> XElement(<span style="color: maroon">&quot;expiryDate&quot;</span>, request.Expiry), </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: blue">new</span> XElement(<span style="color: maroon">&quot;cvv&quot;</span>, request.CVV) </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ) </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ) </p>
<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; ) </p>
<p>&#160;&#160;&#160;&#160;&#160; ) </p>
<p>&#160;&#160;&#160; ) </p>
<p>&#160; ); </p>
<p></div>
<p>This syntax is certainly easy to construct and read but as you can imagine, a large deeply nested XML file can look messy and finding a mismatched parenthesis or missing comma is not fun.</p>
<p>Reading XML with LINQ bypasses the need to create cryptic XPath queries but it is still a query driven process. For example, to read the MessageInfo node would require the following code:</p>
<div style="font-family: courier new">var messageInfo = (from mi <span style="color: blue">in</span> ele.Descendants(<span style="color: maroon">&quot;MessageInfo&quot;</span>)&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; select <span style="color: blue">new</span>&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; messageID = mi.Element(<span style="color: maroon">&quot;messageID&quot;</span>).Value&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }).SingleOrDefault();&#160; </p>
</div>
<p>This code is clear enough and in some ways safer than my example, but it is not available for .NET 2.0. For my situation, XmlTextWriter and XmlReader provided a clear, simple, and efficient mechanism for dealing with XML data. </p>
<p>&#8212;</p>
<p><em>Peter Jones is a 25 year veteran (vintage?) programmer and Microsoft MVP (ASP.NET) from New Zealand. He currently works for </em><a href="http://www.intergen.co.nz"><em>Intergen</em></a><em> &#8211; a leading Microsoft Gold Partner. Peter has worked on and created systems for many industries such as Telecommunications, Manufacturing, Government, Education and more. He cut his programming teeth on dBase 3, Clipper 5 and C before moving to Windows development tools such as Visual Basic, Delphi and .NET. Currently he is working with content management systems (SharePoint and EPiServer) in Sydney, Australia. You can contact Peter and read his occasionally updated blog at </em><a href="http://jonesie.net.nz"><em>http://jonesie.net.nz</em></a><em>. </em></p>
]]></content:encoded>
			<wfw:commentRss>http://devshaped.com/2009/03/banking-with-xml/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Practical Programming: Sending Email</title>
		<link>http://devshaped.com/2009/01/practical-programming-sending-email/</link>
		<comments>http://devshaped.com/2009/01/practical-programming-sending-email/#comments</comments>
		<pubDate>Sat, 17 Jan 2009 01:33:00 +0000</pubDate>
		<dc:creator>Derek</dc:creator>
				<category><![CDATA[Practical Programming]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[smtp]]></category>
		<category><![CDATA[ssl]]></category>

		<guid isPermaLink="false">http://devshaped.com/2009/01/practical-programming-sending-email/</guid>
		<description><![CDATA[By Derek Hatchard
 Sending email from a .NET application is incredibly simple:
using System.Net.Mail;     &#8230;     SmtpClient _smtp = new SmtpClient(&#34;smtp.test.com&#34;);     _smtp.Send(&#34;from@test.com&#34;,&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#34;derek@devshaped.com&#34;,&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#34;Subject&#34;,&#160; &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#34;Body&#34;); 
With just these few lines of code, you are sending an email from from@test.com to derek@devshaped.com. Pretty [...]]]></description>
			<content:encoded><![CDATA[<p>By <a href="http://derekh.com/" target="_blank">Derek Hatchard</a></p>
<p><img style="border-right-width: 0px; margin: 0px 0px 22px 22px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Derek_Hatchard" border="0" alt="Derek_Hatchard" align="right" src="http://devshaped.com/wp-content/uploads/2009/01/derek-hatchard.jpg" width="85" height="57" /> Sending email from a .NET application is incredibly simple:</p>
<div style="font-family: courier new"><span style="color: blue">using</span> System.Net.Mail;     <br />&#8230;     <br />SmtpClient _smtp = <span style="color: blue">new</span> SmtpClient(<span style="color: maroon">&quot;smtp.test.com&quot;</span>);     <br />_smtp.Send(<span style="color: maroon">&quot;from@test.com&quot;</span>,&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: maroon">&quot;derek@devshaped.com&quot;</span>,&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: maroon">&quot;Subject&quot;</span>,&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: maroon">&quot;Body&quot;</span>); </div>
<p>With just these few lines of code, you are sending an email from from@test.com to derek@devshaped.com. Pretty easy stuff.</p>
<p>But what if you need something a little more complicated? The example above assumes the standard SMTP port for email with no authentication and an unencrypted connection. Fortunately these “complications” are quite easy to deal with in .NET.</p>
<p> <span id="more-31"></span><br />
<h2>Different Port</h2>
<p>If you need to send email on a different port, simply add the following line:</p>
<div style="font-family: courier new">_smtp.Port = <span style="color: maroon">587</span>;</div>
<h2>SMTP Authentication</h2>
<p>If you are not sending through a local SMTP server, your app will likely need to authenticate itself. If you need to pass credentials to the SMTP server, use the Credentials property on the SmtpClient class:</p>
<div style="font-family: courier new"><span style="color: blue">using</span> System.Net;     <br />&#8230;     <br />_smtp.Credentials = <span style="color: blue">new</span> NetworkCredential(<span style="color: maroon">&quot;username&quot;</span>, <span style="color: maroon">&quot;pwd&quot;</span>);</div>
<h2>Encrypted Connection</h2>
<p>Since you are passing credentials to the server, you really should be using a secure connection (many mail providers <em>require</em> you to use a secure connection). In code, it’s just one line:</p>
<div style="font-family: courier new">_smtp.EnableSsl = <span style="color: maroon">true</span>;     </div>
<h2>Sending Email On Behalf of Someone</h2>
<p>A final practical consideration when sending email is the distinction between From and Sender. In a simple scenario, you only need a From address. But if you are writing code to send email, chances are good that there is something not-quite-so-simple happening. </p>
<p>Perhaps you have received an email with a header like this in Outlook:</p>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="fromsender" border="0" alt="fromsender" src="http://devshaped.com/wp-content/uploads/2009/01/fromsender.jpg" width="382" height="88" /> </p>
<p>This is an example of one email account sending an email on behalf of someone else. This is often used by automated systems and it is trivial to add to your application. To add a Sender you cannot pass values directly to an SmtpClient object; you must create a new instance of the MailMessage class, set the properties, and then pass the MailMessage object to the SmtpClient object:</p>
<div style="font-family: courier new">MailMessage _msg = <span style="color: blue">new</span> MailMessage(<span style="color: maroon">&quot;from@test.com&quot;</span>,&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: maroon">&quot;derek@devshaped.com&quot;</span>,&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: maroon">&quot;Subject&quot;</span>,&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: maroon">&quot;Body&quot;</span>);&#160; <br />_msg.Sender = <span style="color: blue">new</span> MailAddress(<span style="color: maroon">&quot;sender@test.com&quot;</span>);</div>
<div style="font-family: courier new">_smtp.Send(_msg); </div>
<p>Keep in mind that your message is going through an SMTP server that might not let you set arbitrary From and Sender values.</p>
<h2>Bringing it All Together</h2>
<p>Here is what the final code looks like that incorporates an alternate port, credentials, encrypted transport, and a sender:</p>
<div style="font-family: courier new"><span style="color: blue">using</span> System.Net;     <br /><span style="color: blue">using</span> System.Net.Mail;     <br />&#8230;     <br />SmtpClient _smtp = <span style="color: blue">new</span> SmtpClient(<span style="color: maroon">&quot;smtp.test.com&quot;</span>);     <br />_smtp.Port = <span style="color: maroon">587</span>;     <br />_smtp.Credentials = <span style="color: blue">new</span> NetworkCredential(<span style="color: maroon">&quot;username&quot;</span>, <span style="color: maroon">&quot;pwd&quot;</span>);     <br />_smtp.EnableSsl = <span style="color: maroon">true</span>;     </p>
<p>MailMessage _msg = <span style="color: blue">new</span> MailMessage(<span style="color: maroon">&quot;from@test.com&quot;</span>,     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: maroon">&quot;derek@devshaped.com&quot;</span>,     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: maroon">&quot;Subject&quot;</span>,     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span style="color: maroon">&quot;Body&quot;</span>);     <br />_msg.Sender = <span style="color: blue">new</span> MailAddress(<span style="color: maroon">&quot;sender@test.com&quot;</span>);     <br />_smtp.Send(_msg); </div>
</p>
<p>&#8212;-</p>
<p>Derek Hatchard is the content editor for <a href="http://microsoft.com/youshapeit/msdn">http://microsoft.com/youshapeit/msdn</a> and <a href="http://devshaped.com">http://devshaped.com</a>. He is also the founder of <a href="http://crowdspace.net/" target="_blank">Crowd Space</a>. You can find him online at <a href="http://derekh.com">http://derekh.com</a>, <a href="http://ardentdev.com">http://ardentdev.com</a>, and <a href="http://twitter.com/derekhat">http://twitter.com/derekhat</a>. </p>
]]></content:encoded>
			<wfw:commentRss>http://devshaped.com/2009/01/practical-programming-sending-email/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
