<?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; programming</title>
	<atom:link href="http://devshaped.com/tag/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>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>
