<?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}</title>
	<atom:link href="http://devshaped.com/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>All I Wanted Was My Data</title>
		<link>http://devshaped.com/2009/05/all-i-wanted-was-my-data/</link>
		<comments>http://devshaped.com/2009/05/all-i-wanted-was-my-data/#comments</comments>
		<pubDate>Wed, 13 May 2009 01:00:00 +0000</pubDate>
		<dc:creator>Derek</dc:creator>
				<category><![CDATA[Features]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[orm]]></category>

		<guid isPermaLink="false">http://devshaped.com/?p=181</guid>
		<description><![CDATA[by Barry Gervin
 Most .NET developers are going to need to access relational data at some point. For somebody approaching .NET for the first time, the data access story in the .NET world can be a little overwhelming to say the least. Existing .NET developers looking to update their data access techniques can face a [...]]]></description>
			<content:encoded><![CDATA[<p>by <a href="http://blogs.objectsharp.com/CS/blogs/barry/" target="_blank">Barry Gervin</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="barrygervin" border="0" alt="barrygervin" align="right" src="http://devshaped.com/wp-content/uploads/2009/05/barrygervin.jpg" width="85" height="57" /> Most .NET developers are going to need to access relational data at some point. For somebody approaching .NET for the first time, the data access story in the .NET world can be a little overwhelming to say the least. Existing .NET developers looking to update their data access techniques can face a similar overwhelming experience. This article will help you understand the currently shipping mainstream technologies and how you can choose the one that is right for your particular needs.</p>
<p><span id="more-181"></span></p>
<p>There is a wide array of choices from Microsoft as well as from within the .NET ecosystem. There are many considerations to keep in mind when evaluating these technologies such as type safety, developer productivity, maintainability, concurrency, database agnosticism, performance, and scalability. One element that is almost universally accepted as a best (and only) practice these days is optimistic concurrency. Just about every data access technology that you&#8217;ll be interested in is going to use this concurrency model. That is where the similarities end.</p>
<div style="border-bottom: black 1px solid; text-align: left; border-left: black 1px solid; padding-bottom: 10px; background-color: #eeeeee; padding-left: 10px; padding-right: 10px; margin-left: 40px; border-top: black 1px solid; margin-right: 40px; border-right: black 1px solid; padding-top: 10px">Optimistic Concurrency is about being &quot;optimistic&quot; that we will not run into concurrent write access to records in the database. You could think of this as &quot;you probably aren&#8217;t going to update this record I&#8217;m about to give you, and even if you do, no one else is likely to update it at the same time&quot;. In practical terms, this means that I&#8217;m going to give you the record and forget I even gave it to you. When you want to update it, instead of just giving me the new values, you may want to let me know what version of the record you were editing so I can make sure somebody else hasn&#8217;t already changed it since I first gave it to you. Even more practically, this means, in addition to using the primary key in the where clause, also give me the original values of every column (or the ones you really care about). For SQL Server, you can be clever and use a single timestamp column that gets updated every time a record is touched. </div>
<h2><b>Traditional ADO.NET</b></h2>
<p>ADO.NET is a .NET brand name for all things data access from Microsoft. Typically using ADO.NET means using SqlCommand objects. Using a SqlCommand, we can pass a native T-SQL statement directly to the database. This could be a SELECT, INSERT, UPDATE, DELETE, a stored proc, or even a DDL (Data Definition Language) statement. Because ADO.NET doesn&#8217;t know too much about the database syntax, this statement is simply stored in a SqlCommand as a string and passed off directly to the database. You must use one of the Execute* methods on the SqlCommand to invoke the command. Using ExecuteNonQuery will fire the statement and assume it returns no result sets. This is useful in the Insert, Update, and Delete scenarios. To bring a result set back, we use the ExecuteReader method which will return a DataReader. A DataReader looks a little bit like a cursor which will allow us in .NET code to loop through the result set one row at a time and look at the columns. The DataReader is somewhat stupid in that it doesn&#8217;t know much about the shape or data types of the results coming back so you must use untyped access to get the columns as such in the code below:</p>
<div style="font-family: courier new; font-size: 9pt"><span style="color: blue">string</span> mySelectQuery = <span style="color: maroon">&quot;SELECT OrderID, CustomerID FROM Orders&quot;</span>;     <br />SqlConnection myConnection = <span style="color: blue">new</span> SqlConnection(myConnString);     <br />SqlCommand myCommand = <span style="color: blue">new</span> SqlCommand(mySelectQuery,myConnection);     <br />myConnection.Open();     <br />SqlDataReader myReader;     <br />myReader = myCommand.ExecuteReader();     </p>
<p><span style="color: green">// Always call Read before accessing data.</span>     <br /><span style="color: blue">while</span> (myReader.Read())     <br />{     <br />&#160; Console.WriteLine(myReader.GetInt32(<span style="color: maroon">0</span>) + <span style="color: maroon">&quot;, &quot;</span> +&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; myReader.GetString(<span style="color: maroon">1</span>));     <br />}     </p>
<p><span style="color: green">// always call Close when done reading.</span>     <br />myReader.Close();     </p>
<p><span style="color: green">// Close the connection when done with it.</span>     <br />myConnection.Close();     </div>
<p>It is also important to note that the connection to the database remains open during this looping. You may want to reduce the amount of work you do in the loop to minimize the amount of time the database connection is held open. This will make your application more scalable since database connections are a finite resource.</p>
<p>If you are only returning a single value (like a count or exactly one column from one row) you can use the ExecuteScalar method which is a bit easier to use than a DataReader.</p>
<p>SqlCommands and DataReaders in general let you be very precise about the SQL that is sent to the server and control exactly when the connection is opened and closed. You have to provide a bit more muscle in getting the data out of the SQL and coerced into .NET data types, but for performance sensitive areas of your applications, this could pay off. The other thing to be aware of is that there are a different set of objects (Commands, Connections, DataReaders) for each relational database provider. So if you need to move from SQL Server to ODBC to Oracle, you&#8217;ll need different objects. Fortunately each of these objects are based on an interface and you can program through the interface by using a DbProviderFactory class to create the concrete types based on configuration data. You will have to be sure to use ANSI compatible SQL in your attempt to be database agnostic, which may run counter to providing high speed data access which often requires developers to use native &amp; unique syntax to a particular relational database engine. Obviously your mileage might vary here.</p>
<h3>DataSets, DataTables, Data &amp; Table Adapters</h3>
<p>With DataReaders you need to be careful about how long you keep your connection open while iterating. Sometimes it is better to pull back your entire result set into memory, release your connection to the database, and then process the result set afterwards. This is where DataSets can be helpful. If you have a batch processing scenario that requires the entire result set in memory or you need to provide end user editing in a grid control, then DataSets are a good place to hold that data. </p>
<p>One of the primary benefits of a DataSet is that it not only caches the data in an efficient memory structure, but it can provide change tracking (what records were added? Deleted? Changed? What were the original values of each column, etc). DataSets work collaboratively with a SqlDataAdapter object, which is simply a composite of 4 SqlCommands (InsertCommand, SelectCommand, UpdateCommand, and DeleteCommand) mapping to the appropriate CRUD behavior (create, read, update, and delete).</p>
<p>DataSets can contain multiple result sets, each mapped into its own DataTable. Tables can be related to each other with Relations which mimic foreign keys. DataSets take care of master-detail linkages and keep everything &quot;hooked up&quot; when inserting records into parent and child tables with identity columns. Each table will require its own SqlDataAdapter. If you are doing a mix of insert, updates, and deletes and your database has referential constraints, you&#8217;ll need to orchestrate the changes, making sure parent records are inserted before children and that deletions happen in the reverse order. </p>
<p>DataSets/DataTables come in two flavors: typed and untyped. Untyped DataSets simply infer the table and column definitions after executing the SqlDataAdapter.Fill method. Accessing the columns must be done similarly to DataReaders using column names in quotes or by positional reference. Typed Datasets on the other hand use wizards and a design surface to generate a strongly typed object. The typed dataset is defined by an XSD document. The XSD is then turned into a strongly typed/named class that essentially sits on top of an untyped dataset. A table mappings collection on the SqlDataAdapter class allows you to use different names for your strongly typed object than that of your database table and column names.</p>
<p>Many people in the .NET 1.0-2.0 era used typed datasets as business entities and wrapped some additional business logic around them. Although you could map column names, you were typically tied tightly to your table design in the database. DataSets can also be converted to and from XML, including a diffgram format that retains pending change information. In many circles, DataSets have and continue to be serialized between distributed layers of an application. This makes for a pretty productive development environment, but has drawn architectural criticisms compared to properly modeled services with messages and contracts.</p>
<p>In .NET 1.0, DataAdapters and DataSets were different objects that really didn&#8217;t know about each other until you executed the DataAdapter Fill or Update method and passed the DataSet/DataTable to the respective method. It was possible for the table mappings in the SqlDataAdapter to get out of sync with the strongly typed dataset. To improve this situation, Microsoft introduced TableAdapters in .NET 2.0, which are really just DataAdapters that are strongly typed and embedded into the definition of the typed dataset. </p>
<h2><b>Object Relational Mapping</b></h2>
<p>With .NET 3.0/3.5, MS has finally released not one but two ORM toolkits. I say finally because MS previously promised an ORM toolkit to developers in the form of a project called ObjectSpaces. ObjectSpaces was never released and its demise is clouded in a series of potentially bad integrations with WinFS, Project Green, or the MS Business Framework, all of which were eventually cancelled.</p>
<p>The spark that reignited MS ambitions to produce an ORM was the Language Integrated Query (LINQ) project. LINQ&#8217;s goal as part of C# 3.0 and Visual Basic 9.0 was to provide a set based metaphor for dealing with heterogeneous data types including object collections, XML, and last but not least, relational data. For the relational component of LINQ, the language team came up with a project called LINQ to SQL and shipped it as part of .NET Framework 3.5.</p>
<p>During the same time period, the Data Programmability Group in the SQL Server team had been working on a new layer to sit over top of SQL Server&#8217;s logical data model. This new &quot;Entity Data Model&quot; (EDM) would allow developers to interact with their relational database using a more abstract conceptual model based on the ideas of Dr. Peter Chen. For this team, the promise of Language Integrated Query was what really brought the notion of the EDM to life, and so began the &quot;Entity Framework&quot; project. The Entity Framework did not ship until several months after LINQ to SQL as part of the .NET 3.5 Service Pack 1 release.</p>
<p>On the outside, LINQ to SQL and the Entity Framework ORMs appear very similar. Both tools use a graphical design tool and wizard to map a relational database into an object model. They can both use LINQ queries to project relational data into objects using composable queries. Both provide change tracking so that changes made to the objects can be persisted back to the database with a single method call. </p>
<p>Given these similarities, Microsoft has spent some considerable energy in explaining when to use each of these technologies. While these two ORMs have strong similarities in programming models, their internal architectures are quite different. These key differences are:</p>
<ul>
<li style="margin-bottom: 10px">LINQ to SQL has been locked directly to SQL Server, whereas the Entity Framework includes a provider model that allows it to work with any relational engine. As mid 2009 the list of available providers in the ecosystem included SQL Server, Oracle, Sybase, DB2, Informix, MySQL, PostgresSQL, SQLite, OpenLink Virtuoso, and Firebird. </li>
<li style="margin-bottom: 10px">LINQ to SQL does not provide a mechanism for streaming records one at a time. Using Entity SQL, the Entity Framework can provide Data Reader style access to results using the same mapping layer used for object queries. </li>
<li style="margin-bottom: 10px">LINQ to SQL provides an out of the box experience for lazy loading. Lazy loading allows the engine to automatically (by default) go out and retrieve new data as it is needed based on code that access different elements of the object graph. In the Entity Framework, you have to be explicit when you make trips to the database. Both ORMs allow you to load deep object graphs eagerly as well. </li>
<li style="margin-bottom: 10px">Perhaps the largest difference between Entity Framework and LINQ to SQL is the conceptual modeling layer that EF provides. EF provides a much richer mapping layer than LINQ to SQL, allowing you to join tables together, provide elaborate class hierarchies with abstract and concrete types, and retain many-to-many relationships in your model. Future plans will see the conceptual model being used in other MS products such as SQL Server Reporting Services and SQL Server Analysis Services. </li>
<li style="margin-bottom: 10px">Finally, expect to see significant investment in the Entity Framework ORM from Microsoft. Both ORMs are now managed by the same product team at MS and they have stated that while LINQ to SQL will continue to be supported and maintained, future innovation will be focused on the Entity Framework. </li>
</ul>
<h2><b>Other ORM Technologies</b></h2>
<p>You can&#8217;t talk about ORMs in the .NET world without mentioning NHibernate. NHibernate or &quot;NH&quot; is a mature yet free open source framework which is a port of the popular Java ORM Hibernate. Perhaps one of the biggest distinctions of NH is its support for a Domain Driven Design workflow which purports a code-first or test-first approach to building applications. Typical NH developers build their classes first and then use an XML file to map those to a database. Unlike NH, both LINQ to SQL and Entity Framework advocate a model-first approach, and one could argue a database driven approach. Both LINQ to SQL and Entity Framework designers assume you have an existing database that needs mapping to some objects that will be derived out of your model. </p>
<p>Although there are other commercial and open source ORM tools available, NHibernate, LINQ to SQL, and Entity Framework are by far the most popular technologies in use today.</p>
<h2>Enter Data Services</h2>
<p>When it comes to building distributed applications, your mileage will vary with the array of data access technologies. Dealing with serialization and concurrency issues in those environments is beyond the scope of this article. However, it is important to mention what appears to be yet another data access technology available from Microsoft called ADO.NET Data Services, formerly code-named &quot;Astoria&quot;. Astoria was made available with .NET 3.5 SP1.</p>
<p>Astoria is an HTTP service layer built on top of WCF that provides a REST-style API to your data, giving each of your elements of data a unique URI (for example, http://host/northwind.svc/Products(1) ). Out of the box, this service can be enabled for an Entity Framework model or any other IUpdateable/IQueryable data source in just a few lines of code. Data is queryable and updateable via pure HTTP verbs (PUT, POST, DELETE, and GET) using query strings and HTTP payload. Data can be serialized in either AtomPub or JSON format. The net effect is that your data model is widely interoperable with a dizzying array of potential clients and technologies. </p>
<p>Although you are free to build up complex query strings and HTTP payloads for just about any type of operation, the Astoria team has created client libraries to assist in these endeavors. Firstly, an ASP.NET Ajax library is available on CodePlex to allow JavaScript developers to easily work with Astoria Services. Secondly, as part of the core installation, there is a .NET Client Library which provides a natural query model using LINQ and projecting data into client side .NET objects for use by your .NET or Silverlight projects.</p>
<p>A new project, currently named &quot;RIA Services&quot; (code-named &quot;Alexandria&quot;), builds on top of ADO.NET Data Services by also providing rich validation and UI cues on top of your data model in a client/server model. This technology probably won&#8217;t be released until around the .NET 4.0 timeframe, but it is definitely something you should keep your eye on.</p>
<h2>Application Frameworks</h2>
<p>As you can see, the trend in Data Access is to abstract into higher and higher levels within your applications. As data access libraries are generating entity classes, the question around locating data validation logic can become a slippery slope. If a data access generated entity can validate correct data types, maybe it should also validate that postal codes and phone numbers are of the correct format. Should they also cross-validate postal codes with states/provinces? Should these error messages be managed inside of my entities? The waters can be muddied quite quickly.</p>
<p>It is therefore worthy to briefly mention a few of the more popular application frameworks that embrace a holistic view of data access in the scope of an application. </p>
<p>CSLA.NET (Component-based Scalable Logical Architecture) is a framework developed principally by author Rocky Lhotka in conjunction with his popular series of Business Objects books. When first released, CSLA was focused on Visual Basic 6, but over the years it has remained very current on the latest Microsoft technologies and is now principally maintained in C# and ported to VB. In CSLA, data is fully encapsulated by rich business objects that manage all behavior including persistence. CSLA facilitates the re-use of business objects in many possible client technologies including ASP.NET, WPF, WinForms, and Silverlight including distributed architectures using Web Services.</p>
<p>DevForce from IdeaBlade is a commercially available framework for building rich, distributed applications in Silverlight, WPF, WinForms, and ASP.NET. DevForce builds on top of the Entity Framework for its persistence layer and includes a Business Objects server for distributed architectures. DevForce is a popular application framework and has been around since 2001. </p>
<h2>But All I Wanted Was My Data</h2>
<p>If you can believe it, this article has been a <b><u>short</u></b> list of the current and popular data access technologies. I think I could safely say that the one piece of universally accepted guidance is that if the data access technology you are considering is not in the above list, then it is likely out dated or obscure and perhaps you should think twice about using it.</p>
<p>If you are comfortable with open source projects and you are a strong believer in Domain-Driven-Development, NHibernate is an obvious choice. There is a strong community to back you up on this decision.</p>
<p>If you prefer to stick with Microsoft Technologies, and you have a legacy database to start from, or prefer a model-driven or data-driven approach, then the Entity Framework is likely where you should end up. </p>
<p>If you prefer to work with a more structured and complete application framework, both CSLA and DevForce are worthy choices at this level and you will have community and paid-support available to back you up on each of these respectively.</p>
<p>The last key piece of advice to offer is that you don&#8217;t have to pick just one of these. There are pros and cons and you may have to use multiple technologies, even within the same application. If you feel the need for performance, there are no rules against dropping out of your ORM and opting for more direct access. Keep an open mind and use the best tool for the job. </p>
<p>&#8212;&#8211;</p>
<p><em>Barry Gervin is a founding Partner of ObjectSharp in Toronto, Canada. As a Principal Consultant, Barry provides technical leadership to his valued clients, staff, and the development community. Over his 19 year career in the IT industry, he has led many development teams to successfully deliver large software projects within tight schedules and budgets that consistently perform for their customers. Barry currently serves as a </em><a href="http://www.microsoft.com/rd"><em>MS Regional Director</em></a><em> in Southern Ontario and has received the </em><a href="https://mvp.support.microsoft.com/profile/Barry.Gervin"><em>Microsoft MVP Award</em></a><em> for Solutions Architecture for the past 5 years.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://devshaped.com/2009/05/all-i-wanted-was-my-data/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Mano Kulasingam on digiTweet</title>
		<link>http://devshaped.com/2009/05/mano-kulasingam-on-digitweet/</link>
		<comments>http://devshaped.com/2009/05/mano-kulasingam-on-digitweet/#comments</comments>
		<pubDate>Wed, 13 May 2009 00:59:00 +0000</pubDate>
		<dc:creator>Derek</dc:creator>
				<category><![CDATA[codeplex]]></category>
		<category><![CDATA[Audio]]></category>
		<category><![CDATA[digitweet]]></category>

		<guid isPermaLink="false">http://devshaped.com/?p=189</guid>
		<description><![CDATA[ Our CodePlex Project of the Month for May 2009 is digiTweet. 
digiTweet is an open source desktop Twitter client for Windows. DigiTweet provides Twitter functionality within a rich user interface built with Windows Presentation Foundation (WPF). 
Listen to our interview with Mano Kulasingam (@digi_tweet) using the embedded audio player or download the MP3. 
&#8212;&#8211;
CodePlex [...]]]></description>
			<content:encoded><![CDATA[<p><img style="border-bottom: 0px; border-left: 0px; margin: 0px 0px 22px 22px; display: inline; border-top: 0px; border-right: 0px" title="digitweet" border="0" alt="digitweet" align="right" src="http://devshaped.com/wp-content/uploads/2009/05/digitweet.jpg" width="85" height="57" /> Our CodePlex Project of the Month for May 2009 is <a href="http://digitweet.codeplex.com/" target="_blank">digiTweet</a>. </p>
<p>digiTweet is an open source desktop Twitter client for Windows. DigiTweet provides Twitter functionality within a rich user interface built with Windows Presentation Foundation (WPF). </p>
<p>Listen to our interview with Mano Kulasingam (<a href="http://twitter.com/digi_tweet" target="_blank">@digi_tweet</a>) using the embedded audio player or download the MP3. </p>
<p>&#8212;&#8211;</p>
<p><em>CodePlex is Microsoft&#8217;s open source project hosting web site. Start a new project, join an existing one, or download software created by the community. <a href="http://www.codeplex.com/CodePlex" target="_blank">Learn More</a></em></p>
]]></content:encoded>
			<wfw:commentRss>http://devshaped.com/2009/05/mano-kulasingam-on-digitweet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<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>Efficiency Upgrade</title>
		<link>http://devshaped.com/2009/05/efficiency-upgrade/</link>
		<comments>http://devshaped.com/2009/05/efficiency-upgrade/#comments</comments>
		<pubDate>Wed, 13 May 2009 00:59:00 +0000</pubDate>
		<dc:creator>Derek</dc:creator>
				<category><![CDATA[MAXoutput]]></category>
		<category><![CDATA[efficiency]]></category>
		<category><![CDATA[productivity]]></category>
		<category><![CDATA[resources]]></category>

		<guid isPermaLink="false">http://devshaped.com/?p=179</guid>
		<description><![CDATA[by Derek Hatchard
 Developers solve problems. Good developers solve problems efficiently. The reward for that efficiency is [insert your preferred reward here]. Let&#8217;s assume you&#8217;re simply motivated by the satisfaction of a job well done (or maybe a promotion, a raise, longer lunch breaks, or just some extra time with your family). Whatever the motivation, [...]]]></description>
			<content:encoded><![CDATA[<p>by <a href="http://derekh.com/" target="_blank">Derek Hatchard</a></p>
<p><img style="border-bottom: 0px; border-left: 0px; margin: 0px 0px 22px 22px; display: inline; border-top: 0px; border-right: 0px" border="0" align="right" src="http://devshaped.com/wp-content/uploads/2009/01/derek-hatchard.jpg" /> Developers solve problems. Good developers solve problems efficiently. The reward for that efficiency is [insert your preferred reward here]. Let&#8217;s assume you&#8217;re simply motivated by the satisfaction of a job well done (or maybe a promotion, a raise, longer lunch breaks, or just some extra time with your family). Whatever the motivation, the secret to solving problems efficiently is not inventing everything from scratch. Certainly the secret is not spinning your mental wheels hoping for inspiration. And most definitely the secret is not using Intellisense to arbitrarily try classes, methods, and properties until something works.</p>
<p>The secret to solving development problems efficiently is having the right information and the means to find the information you don&#8217;t have.</p>
<p><span id="more-179"></span></p>
<p>If you have been developing software for more than a week, you know that a working knowledge of language syntax and program construction (that is, &quot;programming&quot;) is only a small part of the necessary skill set for solving problems with software. As a developer, you need to understand the technologies, processes, and methods available to you. You also need to have a set of reliable resources you can turn to when you encounter problems.</p>
<p>Below you will find some resource recommendations to help you find the information you need to help solve development problems more efficiently so you can get on with living the rest of your life.</p>
<h1>Finding Answers to Specific Problems</h1>
<h2>Search Engines</h2>
<p>I have heard colleagues muse about the changing role of &quot;software developer,&quot; postulating that development has become a job mostly concerned with research and discovery. While that is no doubt an overstatement, the ability to find information quickly is an important skill. The place many of us turn to first is our search engine of choice whether it&#8217;s Live Search, Google, or a meta search site like Dogpile.</p>
<p>The appeal of most search engines is the beautiful simplicity of a single search box, but the needs of a developer are not simple when you factor in multiple versions of frameworks, programming languages with similar constructs, and behavior differences between competing products (I&#8217;m looking at you, Structured Query Language and Cascading Style Sheets). With just a short time investment, you can learn some advanced search operators and tricks to help narrow search results to exactly the information you need. For example, search for &quot;live advanced search keywords&quot; or &quot;google advanced operators&quot; and you&#8217;ll find a bunch of operators to help you become a search ninja.</p>
<p>In addition to your search engine of choice, Wikipedia can be an invaluable problem solving tool. I have found Wikipedia to be especially useful when searching for general topics such as common computer science algorithms and concepts. Although I often end up at Wikipedia through search engine results, Wikipedia has its own search box right on the home page (<a title="http://wikipedia.org/" href="http://wikipedia.org/">http://wikipedia.org/</a>).</p>
<p>Of course not all problems will have solutions waiting to be discovered via a search engine. Some problems have already been solved in another part of your organization and you simply have no idea about the pre-existing solution. There are many tools designed to help companies deal with code asset management and search behind the firewall. One interesting product is Krugle, a specialty search engine built for indexing and searching code.</p>
<h2>Stack Overflow</h2>
<p>Searching is great when you know exactly what to search for and somebody else has previously solved a similar problem. When you are dealing with a more difficult issue, you may want to pose your specific problem to other developers for advice. There are plenty of discussion boards and forums for developers on the Internet to ask and answer questions.</p>
<p>One intriguing and useful site is Stack Overflow, a &quot;collaboratively edited question and answer site for programmers.&quot; This innovative developer Q&amp;A site allows users to post responses to questions and vote answers up or down based on usefulness, accuracy, etc. In addition to posting questions, you can search Stack Overflow or browse posted questions by tag. When you are posting a question on Stack Overflow, the application automatically searches existing questions and shows you matches that might already contain the answer you seek.</p>
<p>For obscure topics and scenarios such as bizarre error codes, Stack Overflow can be a job saver.</p>
<h2>Twitter</h2>
<p>Microblogging seems to be all the rage these days and some developers find services like Twitter to be an extremely effective way to share tips and send out requests for help. Twitter and similar services can be a two-edged sword, though, as they can be as much a distraction as a tool for information exchange.</p>
<p>If you are not familiar with Twitter, it lets you follow posts or &quot;tweets&quot; from other Twitter users. Tweets can be no more than 140 characters. You choose who you want to follow.</p>
<p>There are plenty of ways to use Twitter that will surely reduce your efficiency, but with a bit of intentionality in your approach, you can build a reasonable size network of trusted colleagues with whom you can swap questions, answers, tips, and tricks. (When your friends hear you are &quot;on Twitter,&quot; they may demand to know your Twitter username. You might need to maintain separate Twitter accounts for work and personal use.)</p>
<h2>Officemates, Coworkers, and IM Contacts</h2>
<p>If you are anything like me, you find it tempting to just ask an officemate or IM contact for an answer. Of course this means solving my problem at the expense of my colleague who is distracted from doing his/her own work. With your recently acquired ninja search engine skills, take a look at some of the research on the impact of interruptions on productivity and ponder how a work culture that accepts interruptions as common practice could ultimately make you a less effective developer. Just something to think about before you start picking the brains of your cubicle mates.</p>
<h2>Other Options</h2>
<p>What sources do you rely on for finding answers to specific problems? Leave a comment below.</p>
<h1>Keeping Up with New Technologies</h1>
<p>With the rapid and continuous rate of change in the software development space, keeping up with the latest and greatest technologies could be a full-time job – in fact it is in many organizations! It really has become impossible to keep up with everything, but you should not let the fear of information overload prevent you from staying informed about significant changes directly related to your area of expertise. Being informed about new technologies helps you make informed choices about the tools, platforms, and libraries you will use to get from problem to solution.</p>
<h2>Blogs</h2>
<p>One easy way to stay informed about topics that might affect you is to subscribe to at least a few blogs in your area. Scott Guthrie&#8217;s blog is a good choice if you only want to get the big headline news like a new release of the .NET Framework (<a title="http://weblogs.asp.net/scottgu/" href="http://weblogs.asp.net/scottgu/">http://weblogs.asp.net/scottgu/</a>). If you&#8217;re a Silverlight developer, Tim Heuer&#8217;s blog would be a good choice (<a title="http://timheuer.com/blog/" href="http://timheuer.com/blog/">http://timheuer.com/blog/</a>). If you&#8217;re an ASP.NET developer, perhaps try the Visual Web Developer Team Blog (<a title="http://blogs.msdn.com/webdevtools/" href="http://blogs.msdn.com/webdevtools/">http://blogs.msdn.com/webdevtools/</a>). </p>
<p>If checking blogs via a blog reader is not your thing, you might want to use a service that will deliver new blog posts to you via email.&#160; FeedBlitz (<a title="http://www.feedblitz.com/" href="http://www.feedblitz.com/">http://www.feedblitz.com/</a>) is a service I use for several blogs that I want to track even when I&#8217;m too busy to spend time reading my larger blog subscription list. Or you might want to add a few feeds to a customized browser home page through a service like Pageflakes or Netvibes.</p>
<h2>Podcasts</h2>
<p>Another way to stay current on technology is by listening to audio podcasts like .NET Rocks (<a title="http://dotnetrocks.com/" href="http://dotnetrocks.com/">http://dotnetrocks.com/</a>) and Hanselminutes (<a title="http://hanselminutes.com/" href="http://hanselminutes.com/">http://hanselminutes.com/</a>). Internet audio shows like these are generally packed with great technical content that helps keep you up to date. Podcasts can be an easy way to transform a tedious commute into a serious professional development opportunity. Personally I use the Zune desktop software (<a title="http://zune.net/" href="http://zune.net/">http://zune.net/</a>) to automatically download new podcast episodes and sync them to my Zune device. If you don&#8217;t have a Zune, you can still grab the MP3 files from the Zune download folder and copy them to any portable media player.</p>
<h2>User Groups</h2>
<p>User groups are another great way to stay current on new technologies. User groups are community-run technical groups that hold events (both in-person and virtual) for members to learn about technologies related to the focus area(s) of the groups. User group events often happen outside of normal work hours, which can admittedly make it difficult for some people to attend. In addition to learning opportunities, user group events can be a great place to discuss technical issues you are tackling and increase the size of your network of colleagues that you can turn to for help.</p>
<p>Go to <a title="http://www.ineta.org/" href="http://www.ineta.org/">http://www.ineta.org/</a> to find details (including meeting times and places) for .NET-focused user groups in your neck of the woods.</p>
<h1>Challenging Your Thinking</h1>
<p>When building software, your existing methods for thinking about problems are used to design a solution based on the tools and information you have available. Too many times I have seen developers stuck in a mental rut and developing solutions inefficiently because of outdated or misguided thinking about the problem at hand. Case in point: I used to spend far too much time building and deploying simple tools and utilities as compiled executables until I learned to embrace scripting as a fully legitimate form of programming (after having turned my back on my past as a UNIX scripting hack). In part my thinking was influenced by the experiences of other developers who were sharing their experiences online.</p>
<p>If you do not have people challenging your think, I believe you will stagnate as a developer. That means talking to or reading the musings of other developers. Ideally you will find yourself disagreeing with or questioning their thoughts on a regular basis. You aren&#8217;t being challenged if you only read what likeminded people write.</p>
<p>Below are some sources that I find useful in challenging my thinking and assumptions. They might not work for you, which is fine, but I encourage you to find your own trusted sources that will regularly challenge your thinking.</p>
<p><strong>CodingHorror.com</strong> is written by the brilliant and prolific Jeff Atwood. It has been a constant trove of insight and reasoned perspective, ranging from discussions of technical details to choosing a programming chair. (Jeff is one of the founders of the abovementioned Stack Overflow.)</p>
<p><strong>JoelOnSoftware.com</strong> is written by the equally brilliant Joel Spolsky. He is the source of such gems as &quot;The Joel Test: 12 Steps to Better Code&quot; and &quot;Things You Should Never Do.&quot; In addition to development topics, Joel writes about management and business issues. (Joel is the other founder of Stack Overflow.&#160; Hmmm&#8230; perhaps I have a bias.)</p>
<p><strong>Ted Neward</strong> writes a technical blog (<a title="http://blogs.tedneward.com/" href="http://blogs.tedneward.com/">http://blogs.tedneward.com/</a>) that I regularly enjoy. Although I don&#8217;t read every post, I always find his pontifications worth digesting.</p>
<p><strong>Daniel Crenna </strong>(<a href="http://dimebrain.com/blog">http://dimebrain.com/blog</a>) is another technical blogger whose musings I enjoy reading. Daniel is a great community champion and the founder of several open source projects. His blogging pace has slowed down in 2009 as he&#8217;s been working on some useful projects, but I keep hoping he&#8217;ll starting writing again soon. He&#8217;s a web / RIA guy, an area I&#8217;m interested in, so he stays in the ol&#8217; blog list.</p>
<h1>Join the Conversation</h1>
<p>What do you do to be more efficient as a developer? What are your favorite resources for challenging your thinking? How do you keep up on technology changes in your area of expertise? How do you find solutions to specific problems? Leave a comment to share <strong>YOUR</strong> tips with us.</p>
</p>
<p>&#8212;&#8211;</p>
<p><em>Derek Hatchard is the content editor for </em><a href="http://microsoft.com/youshapeit/msdn"><em>http://microsoft.com/youshapeit/msdn</em></a><em> and </em><a href="http://devshaped.com"><em>http://devshaped.com</em></a><em>. He is also the founder of </em><a href="http://crowdspace.net/"><em>Crowd Space</em></a><em>. You can find him online at </em><a href="http://derekh.com"><em>http://derekh.com</em></a><em>, </em><a href="http://ardentdev.com"><em>http://ardentdev.com</em></a><em>, and </em><a href="http://twitter.com/derekhat"><em>http://twitter.com/derekhat</em></a><em>.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://devshaped.com/2009/05/efficiency-upgrade/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Mike Fourie on MSBuild Extension Pack</title>
		<link>http://devshaped.com/2009/04/mike-fourie-on-msbuild-extension-pack/</link>
		<comments>http://devshaped.com/2009/04/mike-fourie-on-msbuild-extension-pack/#comments</comments>
		<pubDate>Wed, 01 Apr 2009 09:00:00 +0000</pubDate>
		<dc:creator>Derek</dc:creator>
				<category><![CDATA[Audio]]></category>
		<category><![CDATA[codeplex]]></category>
		<category><![CDATA[msbuild]]></category>
		<category><![CDATA[open source]]></category>

		<guid isPermaLink="false">http://devshaped.com/2009/04/mike-fourie-on-msbuild-extension-pack/</guid>
		<description><![CDATA[Our CodePlex Project of the Month for April 2009 is the MSBuild Extension Pack.
The MSBuild Extension Pack provides a collection of over 240 tasks for MSBuild, including things like Environment Variables, Event Logs, Performance Counters, Registry, Services, Code Signing, Zip Files, Email, IIS6, IIS7, Twitter, and WMI.
Listen to our interview with project coordinator Mike Fourie [...]]]></description>
			<content:encoded><![CDATA[<p>Our CodePlex Project of the Month for April 2009 is the <a href="http://msbuildextensionpack.codeplex.com/" target="_blank">MSBuild Extension Pack</a>.</p>
<p>The MSBuild Extension Pack provides a collection of over 240 tasks for MSBuild, including things like Environment Variables, Event Logs, Performance Counters, Registry, Services, Code Signing, Zip Files, Email, IIS6, IIS7, Twitter, and WMI.</p>
<p>Listen to our interview with project coordinator Mike Fourie using the embedded audio player or download the MP3. </p>
<p>&#8212;&#8211; </p>
<p><em>CodePlex is Microsoft’s open source project hosting web site. Start a new project, join an existing one, or download software created by the community. </em><a href="http://www.codeplex.com/CodePlex" target="_blank"><em>Learn More</em></a></p>
]]></content:encoded>
			<wfw:commentRss>http://devshaped.com/2009/04/mike-fourie-on-msbuild-extension-pack/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
			<enclosure url="http://devshaped.com/audio/msbuildextpack.mp3" length="4670016" type="audio/mpeg"/>
<itunes:duration>9:43</itunes:duration>
		<itunes:subtitle>Our CodePlex Project of the Month for April 2009 is the MSBuild Extension Pack.  The MSBuild Extension Pack provides a collection of over 240 ...</itunes:subtitle>
		<itunes:summary>Our CodePlex Project of the Month for April 2009 is the MSBuild Extension Pack.  The MSBuild Extension Pack provides a collection of over 240 tasks for MSBuild, including things like Environment Variables, Event Logs, Performance Counters, Registry, Services, Code Signing, Zip Files, Email, IIS6, IIS7, Twitter, and WMI.  Listen to our interview with project coordinator Mike Fourie using the embedded audio player or download the MP3.   -----   CodePlex is Microsoftrsquo;s open source project hosting web site. Start a new project, join an existing one, or download software created by the community. Learn More 
</itunes:summary>
		<itunes:keywords>Audio,,codeplex</itunes:keywords>
		<itunes:author>derek@webradius.com</itunes:author>
		<itunes:explicit>no</itunes:explicit>
		<itunes:block>No</itunes:block>
	</item>
		<item>
		<title>Getting Started with Continuous Integration</title>
		<link>http://devshaped.com/2009/04/getting-started-with-continuous-integration/</link>
		<comments>http://devshaped.com/2009/04/getting-started-with-continuous-integration/#comments</comments>
		<pubDate>Wed, 01 Apr 2009 09:00:00 +0000</pubDate>
		<dc:creator>Derek</dc:creator>
				<category><![CDATA[MAXoutput]]></category>
		<category><![CDATA[ci]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[continuous integration]]></category>

		<guid isPermaLink="false">http://devshaped.com/2009/04/getting-started-with-continuous-integration/</guid>
		<description><![CDATA[by Sondre Bjellås
 Continuous Integration is a development practice that can help improve your company&#8217;s ability to deliver quality software. It can reduce the time to market and the deployment cycle from functional complete products to having the solutions deployed on desktop or servers.
Continuous Integration, or CI, can start with a lone developer desktop and [...]]]></description>
			<content:encoded><![CDATA[<p>by <a href="http://sondreb.com/blog/" target="_blank">Sondre Bjellås</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="sondre-bjellas" border="0" alt="sondre-bjellas" align="right" src="http://devshaped.com/wp-content/uploads/2009/03/sondrebjellas.jpg" width="85" height="57" /> Continuous Integration is a development practice that can help improve your company&#8217;s ability to deliver quality software. It can reduce the time to market and the deployment cycle from functional complete products to having the solutions deployed on desktop or servers.</p>
<p>Continuous Integration, or CI, can start with a lone developer desktop and mature closer towards production. The ultimate goal is to have a CI environment that can take you from checked-in code to production ready installation packages.</p>
<p><strong>The instructions in this article will help you get started with CI even if you&#8217;re a single developer or a small team.</strong></p>
<p>This is a process that takes time, but don&#8217;t be afraid of the road ahead, I will walk you through the first baby-steps towards a well-tuned machine. CI-practice is one of many important elements for the software development industry to mature to levels of other types of manufacturing.</p>
<p><span id="more-159"></span></p>
<h2><b>Introduction to Continuous Integration</b></h2>
<p>Martin Fowler has written a very good introduction to CI which you can read this on his website: <a href="http://martinfowler.com/articles/continuousIntegration.html">http://martinfowler.com/articles/continuousIntegration.html</a> [1]</p>
<p><i>Continuous Integration is a software development practice where members of a team integrate their work frequently, usually each person integrates at least daily &#8211; leading to multiple integrations per day. Each integration is verified by an automated build (including test) to detect integration errors as quickly as possible. Many teams find that this approach leads to significantly reduced integration problems and allows a team to develop cohesive software more rapidly. This article is a quick overview of Continuous Integration summarizing the technique and its current usage.</i></p>
<p>The clean and simple essence of CI is to avoid the situation <i>“It works on my machine”</i>. This has caused a lot of pain between developer and users, but also between developers. Most of us have experienced that our projects stops compiling properly after a <i>Get Latest</i> operation on the source control system. Another important aspect of CI is to have a cycles of automatic compilation and testing of your projects. We will get deeper into automatic testing later in this article.</p>
<h2><b>Source Control Systems</b></h2>
<p>If you are not familiar with source control systems (SCM), I suggest reading a good introduction by Eric Sink. While the first CI example I will give in this article doesn’t use SCM, it is an essential piece of the puzzle if you&#8217;re doing computer software development. Even as a single developer, it&#8217;s advisable to use a SCM. SCM will give you better control and management of your projects, with history and the ability to restore deleted code.</p>
<p>Introduction to SCM: <a href="http://www.ericsink.com/scm/scm_intro.html">http://www.ericsink.com/scm/scm_intro.html</a> [2]</p>
<p>There are many providers of SCM software; for the purpose of this article we will use Microsoft Visual SourceSafe. When your team grows and you have the finances to purchase licenses, I suggest upgrading to Microsoft Visual Studio Team System, which is a complete Application Life-Cycle Management (ALM) suite.</p>
<h2><b>Setting up your environment</b></h2>
<p>There are various CI solutions available for .NET developers, one of the most popular is Cruise Control .NET (<a href="http://ccnet.thoughtworks.com/">http://ccnet.thoughtworks.com/</a> [3]).</p>
<p>[Please note that all examples are from a 64-bit system where the Program Files paths includes <i>(x86)</i> for 32-bit applications. If you have a 32-bit environment, please make sure you remove any reference to <i>(x86)</i>.]</p>
<p>Cruice Control .NET (CC.NET) comes in various forms, for beginners the setup alternative is the simplest to get you started (CruiseControl.NET-1.4.2-Setup.exe).</p>
<p><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-image0021.jpg" width="300" height="232" /></p>
<p><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-image0041.jpg" width="300" height="232" /></p>
<p>After the installation has completed, a new folder will appear in the Windows start menu. From here we can access the main configuration file and launch the console application.</p>
<p><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-image0061.jpg" width="270" height="119" /></p>
<p><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-image0081.jpg" width="500" height="206" /></p>
<p>Before we continue with updates to our configuration file, we need to learn a little bit about build tools…</p>
<h2><b>Build Tools</b></h2>
<p>To compile the source code, you will need a tool that does the build for you. One alternative is NAnt, which is a free tool (<a href="http://nant.sourceforge.net/">http://nant.sourceforge.net/</a> [4]).</p>
<p>With Visual Studio 2005 Microsoft introduced MSBuild, which is a standalone build engine for .NET. This has made it more accessible for third parties and made it simpler to automate and script.</p>
<p>The simplest way to get started with a build process is to utilize MSBuild, which is already installed if you have .NET Framework 2.0. We will configure CC.NET to start the MSBuild process which takes care of the compilation of our Visual Studio Solution.</p>
<h2><b>New Project or Existing Solutions</b></h2>
<p>It is much less effort to include guidance, frameworks, and tools in the beginning of a new project. This applies to CI as well. The further you get in the development process, the harder it gets to make everything work properly in a CI-environment.</p>
<h2><b>Sample Projects</b></h2>
<p>For the purpose of this article, we’ll create a new Visual Studio solution called <i>IntegrationSample</i>. Within this solution we will create 3 projects: <i>IntegrationSample</i> (Windows Forms), <i>Integration.Common</i> (Class Library) and <i>Integration.Test</i> (Class library).</p>
<p>Add a <i>Person.cs</i> class to the Common project with the following code:</p>
<div style="font-family: courier new; font-size: 9pt"><span style="color: blue">namespace</span> Integration.Common     <br />{     <br />&#160; <span style="color: blue">public</span>&#160;<span style="color: blue">class</span> Person     <br />&#160; {     <br />&#160;&#160;&#160; <span style="color: blue">public</span>&#160;<span style="color: blue">string</span> Firstname { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }     <br />&#160;&#160;&#160; <span style="color: blue">public</span>&#160;<span style="color: blue">string</span> Lastname { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }     <br />&#160;&#160;&#160; <span style="color: blue">public</span> DateTime Birthdate { <span style="color: blue">get</span>; <span style="color: blue">set</span>; }     </p>
<p>&#160;&#160;&#160; <span style="color: blue">public</span>&#160;<span style="color: blue">bool</span> IsOlderThan60()     <br />&#160;&#160;&#160; {     <br />&#160;&#160;&#160;&#160;&#160; <span style="color: blue">return</span> (Birthdate &lt; DateTime.Now.AddYears(-<span style="color: maroon">60</span>));     <br />&#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">string</span> ToString()     <br />&#160;&#160;&#160; {     <br />&#160;&#160;&#160;&#160;&#160; <span style="color: blue">return</span>&#160;<span style="color: blue">string</span>.Format(<span style="color: maroon">&quot;{0} {1}&quot;</span>, Firstname, Lastname);     <br />&#160;&#160;&#160; }     <br />&#160; }     <br />}     </div>
<p>This class represents part of our business domain model and has certain business logic applied to it that is important to our business, namely the method that tells us if a person is more than 60 years old. The next step is to apply a test for our domain object.</p>
<h2><b>Automated Testing with Unit Tests</b></h2>
<p>Being able to automate the testing process of your projects is an important feature of a CI-environment. Having source code that works as tests for your application logic will help you when you’re later going back to modify, extend and fix existing code. With good tests you can ensure that your code changes won&#8217;t break the whole application. There are different frameworks available for unit testing, the most widely used with .NET is NUnit (<a href="http://www.nunit.org">www.nunit.org</a> [5]). To learn more about test-driven development, visit Wikipedia: <a href="http://en.wikipedia.org/wiki/Test-driven_development">http://en.wikipedia.org/wiki/Test-driven_development</a> [6]</p>
<p><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-image0101.jpg" width="300" height="233" /></p>
<p><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-image0121.jpg" width="300" height="234" /></p>
<p>When the installation of NUnit is complete, you can explore the included samples to learn more about writing unit tests. You can use the NUnit GUI to run your unit tests outside of the CI-environment.</p>
<p><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-image0141.jpg" width="244" height="176" /></p>
<p>To start writing unit tests, you need to add a reference to the following assembly in your <i>Integration.Test</i> project: &quot;C:\Program Files (x86)\NUnit 2.4.8\bin\nunit.framework.dll&quot;. Additionally you should create a reference between the Test and the Common project, so we can access our business domain model in the tests project.</p>
<p>When you’re done adding the reference, let’s create a class named <i>PersonTest.cs</i> which will contain all the unit tests for our specific domain object.</p>
<div style="font-family: courier new; font-size: 9pt"><span style="color: blue">using</span> System;     <br /><span style="color: blue">using</span> NUnit.Framework;     <br /><span style="color: blue">using</span> Integration.Common;     </p>
<p><span style="color: blue">namespace</span> Integration.Test     <br />{     <br />&#160; [TestFixture]     <br />&#160; <span style="color: blue">public</span>&#160;<span style="color: blue">class</span> PersonTest     <br />&#160; {     <br />&#160;&#160;&#160; [Test]     <br />&#160;&#160;&#160; <span style="color: blue">public</span>&#160;<span style="color: blue">void</span> IsOlderThan60Test()     <br />&#160;&#160;&#160; {     <br />&#160;&#160;&#160;&#160;&#160; Person person = <span style="color: blue">new</span> Person();     <br />&#160;&#160;&#160;&#160;&#160; person.Firstname = <span style="color: maroon">&quot;Sondre&quot;</span>;     <br />&#160;&#160;&#160;&#160;&#160; person.Lastname = <span style="color: maroon">&quot;Bjellås&quot;</span>;     <br />&#160;&#160;&#160;&#160;&#160; person.Birthdate = <span style="color: blue">new</span> DateTime(<span style="color: maroon">1905</span>, <span style="color: maroon">4</span>, <span style="color: maroon">4</span>);     <br />&#160;&#160;&#160;&#160;&#160; Assert.IsTrue(person.IsOlderThan60());     </p>
<p>&#160;&#160;&#160;&#160;&#160; person.Birthdate = DateTime.Now;     <br />&#160;&#160;&#160;&#160;&#160; Assert.IsFalse(person.IsOlderThan60());     </p>
<p>&#160;&#160;&#160;&#160;&#160; person.Birthdate = DateTime.MaxValue;     <br />&#160;&#160;&#160;&#160;&#160; Assert.IsFalse(person.IsOlderThan60());     <br />&#160;&#160;&#160; }     </p>
<p>&#160;&#160;&#160; [Test]     <br />&#160;&#160;&#160; <span style="color: blue">public</span>&#160;<span style="color: blue">void</span> ToStringTest()     <br />&#160;&#160;&#160; {     <br />&#160;&#160;&#160;&#160;&#160; Person person = <span style="color: blue">new</span> Person();     <br />&#160;&#160;&#160;&#160;&#160; person.Firstname = <span style="color: maroon">&quot;Sondre&quot;</span>;     <br />&#160;&#160;&#160;&#160;&#160; person.Lastname = <span style="color: maroon">&quot;Bjellås&quot;</span>;     <br />&#160;&#160;&#160;&#160;&#160; Assert.AreEqual(person.ToString(), <span style="color: maroon">&quot;Sondre Bjellås&quot;</span>);     <br />&#160;&#160;&#160; }     <br />&#160; }     <br />}     </div>
<p>Tests are done through assertions. There are many types of assert methods included in the NUnit framework and you should use them to validate your business logic. Writing good unit tests is hard and it&#8217;s a practice in which you will continually improve as you get more experienced with it.</p>
<p>You can now begin to run and validate the unit tests on your local machine, open the NUnit GUI application and open the Integration.Test.dll file.</p>
<p><a href="http://devshaped.com/wp-content/uploads/2009/03/clip-image0161.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-thumb1.jpg" width="500" height="290" /></a></p>
<p>As you can see in my screenshot, both of the tests for the Person object validates. When we later go back to change the business logic, we can use the unit tests as a means to validate that our changes doesn’t break anything.</p>
<h2><b>Bringing it all together</b></h2>
<p>Let’s go back to the CC.NET configuration file and start modifying it so we get our CI-environment up and running. It&#8217;s advisable to have a dedicate computer that act as a build-computer, but it&#8217;s not a requirement.</p>
<p>The first thing we’re going to do is modify the default configuration file to run NUnit and our tests, here is the script so far:</p>
<pre style="font-size: 9pt"><span style="color: blue">&lt;</span><span style="color: maroon">cruisecontrol</span> <span style="color: red">xmlns:cb</span>=&quot;<span style="color: blue">urn:ccnet.config.builder</span>&quot;<span style="color: blue">&gt;</span>
 <span style="color: blue">&lt;</span><span style="color: maroon">project</span> <span style="color: red">name</span>=&quot;<span style="color: blue">IntegrationSample</span>&quot;<span style="color: blue">&gt;</span>
  <span style="color: blue">&lt;</span><span style="color: maroon">tasks</span><span style="color: blue">&gt;</span>
   <span style="color: blue">&lt;</span><span style="color: maroon">nunit</span><span style="color: blue">&gt;</span>
    <span style="color: blue">&lt;</span><span style="color: maroon">path</span><span style="color: blue">&gt;</span>C:\Program Files (x86)\NUnit 2.4.8\bin\nunit-console.exe<span style="color: blue">&lt;</span>/<span style="color: maroon">path</span><span style="color: blue">&gt;</span>
    <span style="color: blue">&lt;</span><span style="color: maroon">assemblies</span><span style="color: blue">&gt;</span>
     <span style="color: blue">&lt;</span><span style="color: maroon">assembly</span><span style="color: blue">&gt;</span>C:\Source\Samples\IntegrationSample\Integration.Test\bin\Debug\Integration.Test.dll<span style="color: blue">&lt;</span>/<span style="color: maroon">assembly</span><span style="color: blue">&gt;</span>
    <span style="color: blue">&lt;</span>/<span style="color: maroon">assemblies</span><span style="color: blue">&gt;</span>
   <span style="color: blue">&lt;</span>/<span style="color: maroon">nunit</span><span style="color: blue">&gt;</span>
  <span style="color: blue">&lt;</span>/<span style="color: maroon">tasks</span><span style="color: blue">&gt;</span>
 <span style="color: blue">&lt;</span>/<span style="color: maroon">project</span><span style="color: blue">&gt;</span>
<span style="color: blue">&lt;</span>/<span style="color: maroon">cruisecontrol</span><span style="color: blue">&gt;</span></pre>
<p>Save the configuration and start the CruiceControl.NET application in the start menu. This will open a console application that will run your configuration. This is useful for beginners and when you’re setting up a new environment. When the configuration is complete, you should use the Windows Service for a more stable runtime.</p>
<p><a href="http://devshaped.com/wp-content/uploads/2009/03/clip-image0181.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-thumb1.jpg" width="500" height="252" /></a></p>
<p>When you ran the CC.NET installation, it should have created a virtual directory for you on the local Internet Information Services. If you happen to have any problems with this, make sure you create a virtual directory called webdashboard and map it to <i>C:\Program Files (x86)\CruiseControl.NET\webdashboard</i>.</p>
<p>Opening up the web dashboard should show us our IntegrationSample project and hopefully a green status, indicating that our unit tests has completed successfully. With the current configuration, we need to click the <i>Force</i> button to run tests.</p>
<p><a href="http://devshaped.com/wp-content/uploads/2009/03/clip-image020.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image020" border="0" alt="clip_image020" src="http://devshaped.com/wp-content/uploads/2009/03/clip-image020-thumb.jpg" width="500" height="246" /></a></p>
<p>This dashboard will be your viewport into the status and history of integration builds. You can drill down into the details of a build and you can have multiple CC.NET projects specified in the configuration file.</p>
<p>Our next step is to make CC.NET compile our source code using MSBuild.exe. </p>
<p>Within the &lt;tasks&gt; element in the configuration, add the following script above the NAnt task, which will tell CC.NET to execute MSBuild.exe with our Visual Studio solution file.</p>
<pre><span style="color: blue">&lt;</span><span style="color: maroon">msbuild</span><span style="color: blue">&gt;</span>
 <span style="color: blue">&lt;</span><span style="color: maroon">executable</span><span style="color: blue">&gt;</span>C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe<span style="color: blue">&lt;</span>/<span style="color: maroon">executable</span><span style="color: blue">&gt;</span>
 <span style="color: blue">&lt;</span><span style="color: maroon">workingDirectory</span><span style="color: blue">&gt;</span>C:\Source\Samples\IntegrationSample\<span style="color: blue">&lt;</span>/<span style="color: maroon">workingDirectory</span><span style="color: blue">&gt;</span>
 <span style="color: blue">&lt;</span><span style="color: maroon">projectFile</span><span style="color: blue">&gt;</span>IntegrationSample.sln<span style="color: blue">&lt;</span>/<span style="color: maroon">projectFile</span><span style="color: blue">&gt;</span>
 <span style="color: blue">&lt;</span><span style="color: maroon">buildArgs</span><span style="color: blue">&gt;</span>/noconsolelogger /p:Configuration=Debug /v:m<span style="color: blue">&lt;</span>/<span style="color: maroon">buildArgs</span><span style="color: blue">&gt;</span>
 <span style="color: blue">&lt;</span><span style="color: maroon">targets</span><span style="color: blue">&gt;</span>Build<span style="color: blue">&lt;</span>/<span style="color: maroon">targets</span><span style="color: blue">&gt;</span>
 <span style="color: blue">&lt;</span><span style="color: maroon">timeout</span><span style="color: blue">&gt;</span>720<span style="color: blue">&lt;</span>/<span style="color: maroon">timeout</span><span style="color: blue">&gt;</span>
 <span style="color: blue">&lt;</span><span style="color: maroon">logger</span><span style="color: blue">&gt;</span>C:\Program Files (x86)\CruiseControl.NET\server\ThoughtWorks.CruiseControl.MsBuild.dll<span style="color: blue">&lt;</span>/<span style="color: maroon">logger</span><span style="color: blue">&gt;</span>
<span style="color: blue">&lt;</span>/<span style="color: maroon">msbuild</span><span style="color: blue">&gt;</span></pre>
<p>To validate that CC.NET is working correctly, we can go ahead and make a quick modification to the source code. If you reverse the operator for the age method, we should see the IntegrationSample fail on the dashboard. Drilling down into the details, we should see that our unit test fails.</p>
<p><a href="http://devshaped.com/wp-content/uploads/2009/03/clip-image022.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image022" border="0" alt="clip_image022" src="http://devshaped.com/wp-content/uploads/2009/03/clip-image022-thumb.jpg" width="504" height="244" /></a></p>
<p>The last and final step is to add support for a source control system. As you have now seen, you can setup an CI-environment without source control, but it makes sense to use source control. A source control system adds history and backup support and the ability to make heavy and local changes and not disrupt the active codebase which is inside the source control database.</p>
<h2><b>Visual SourceSafe 2005</b></h2>
<p>If you don&#8217;t have a source control system yet, an easy way to get started is with Microsoft Visual SourceSafe 2005. With an MSDN Subscription, you can download it from the downloads page.</p>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image024" border="0" alt="clip_image024" src="http://devshaped.com/wp-content/uploads/2009/03/clip-image024.jpg" width="300" height="230" /></p>
<p>When you go beyond a small team of programmers I suggest upgrading the source control with a more modern provider, like Visual Studio Team System or SourceGear [7].</p>
<p>Going back to Visual Studio and our <i>IntegrationSample</i> project, we will go ahead and add it to our source control provider of choice.</p>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image026" border="0" alt="clip_image026" src="http://devshaped.com/wp-content/uploads/2009/03/clip-image026.jpg" width="304" height="98" /></p>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image028" border="0" alt="clip_image028" src="http://devshaped.com/wp-content/uploads/2009/03/clip-image028.jpg" width="300" height="238" /></p>
<p>When the solution and all the projects is added to the source control, we can open the Visual SourceSafe Explorer and see how our newly added project is added and we can begin to check-out and check-in code changes.</p>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image030" border="0" alt="clip_image030" src="http://devshaped.com/wp-content/uploads/2009/03/clip-image030.jpg" width="500" height="248" /></p>
<p>We’re now ready for the final changes to our ccnet.config file. Open up the configuration file from the start menu and add the following new elements to the top beneath the &lt;project&gt; element.</p>
<pre><span style="color: blue">&lt;</span><span style="color: maroon">triggers</span><span style="color: blue">&gt;</span>
 <span style="color: blue">&lt;</span><span style="color: maroon">intervalTrigger</span> <span style="color: red">seconds</span>=&quot;<span style="color: blue">60</span>&quot; /<span style="color: blue">&gt;</span>
<span style="color: blue">&lt;</span>/<span style="color: maroon">triggers</span><span style="color: blue">&gt;</span>

<span style="color: blue"> &lt;</span><span style="color: maroon">sourcecontrol</span> <span style="color: red">type</span>=&quot;<span style="color: blue">vss</span>&quot; <span style="color: red">autoGetSource</span>=&quot;<span style="color: blue">true</span>&quot; <span style="color: red">applyLabel</span>=&quot;<span style="color: blue">true</span>&quot;<span style="color: blue">&gt;</span>
 <span style="color: blue">&lt;</span><span style="color: maroon">executable</span><span style="color: blue">&gt;</span>C:\Program Files (x86)\Microsoft Visual SourceSafe\ss.exe<span style="color: blue">&lt;</span>/<span style="color: maroon">executable</span><span style="color: blue">&gt;</span>
 <span style="color: blue">&lt;</span><span style="color: maroon">project</span><span style="color: blue">&gt;</span>$/IntegrationSample<span style="color: blue">&lt;</span>/<span style="color: maroon">project</span><span style="color: blue">&gt;</span>
 <span style="color: blue">&lt;</span><span style="color: maroon">username</span><span style="color: blue">&gt;</span>build<span style="color: blue">&lt;</span>/<span style="color: maroon">username</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>Password123<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">ssdir</span><span style="color: blue">&gt;</span>C:\Source\VSS<span style="color: blue">&lt;</span>/<span style="color: maroon">ssdir</span><span style="color: blue">&gt;</span> <span style="color: blue">&lt;</span>!-- Path to your SourceSafe database --<span style="color: blue">&gt;</span>
 <span style="color: blue">&lt;</span><span style="color: maroon">workingDirectory</span><span style="color: blue">&gt;</span>C:\Source\Samples\IntegrationSample\Build\<span style="color: blue">&lt;</span>/<span style="color: maroon">workingDirectory</span><span style="color: blue">&gt;</span>
 <span style="color: blue">&lt;</span><span style="color: maroon">cleanCopy</span><span style="color: blue">&gt;</span>false<span style="color: blue">&lt;</span>/<span style="color: maroon">cleanCopy</span><span style="color: blue">&gt;</span>
<span style="color: blue">&lt;</span>/<span style="color: maroon">sourcecontrol</span><span style="color: blue">&gt;</span></pre>
<p>Make sure you use a different working directory than your normal project folder, if you are running CC.NET on the same machine that you&#8217;re developing on. You also need to modify the &lt;workingDirectory&gt; and &lt;assembly&gt; elements we created earlier. See the bottom of the article for a full version of our build script.</p>
<p>When you start CruiceControl.NET again, you should see something similar to this output. Please beware that it can take a short while for the process to start.</p>
<p><a href="http://devshaped.com/wp-content/uploads/2009/03/clip-image032.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image032" border="0" alt="clip_image032" src="http://devshaped.com/wp-content/uploads/2009/03/clip-image032-thumb.jpg" width="500" height="238" /></a></p>
<p>As you can see, the script finds that there has been modification in the project inside our source control, which triggers a get process of the source code and later compilation and test-run.</p>
<p>You can specify your own trigger interval in the configuration file, depending on the size of your development team and your software, you can tune it to make sure you build often, but not so much that your build server starts having trouble.</p>
<p>You should create a special user account that your build process can run as and access the source control, as you can see in the example above I created a user called <i>build</i>.</p>
<p>Now it&#8217;s time to test the whole cycle of editing source code, check-in, watch the build server figure out there has been a modification and trigger a compilation and test-run. Let&#8217;s check out the Person.cs file and modify the age check to make our unit tests fail.</p>
<p><a href="http://devshaped.com/wp-content/uploads/2009/03/clip-image034.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image034" border="0" alt="clip_image034" src="http://devshaped.com/wp-content/uploads/2009/03/clip-image034-thumb.jpg" width="244" height="176" /></a></p>
<div style="font-family: courier new"><span style="color: blue">public</span>&#160;<span style="color: blue">bool</span> IsOlderThan60() </p>
<p>{ </p>
<p>&#160; <span style="color: blue">return</span> (Birthdate &gt; DateTime.Now.AddYears(-<span style="color: maroon">60</span>)); </p>
<p>} </p>
<p></div>
<p>When you’re checking code back into the source control system, it’s good practice to add an informative comment. This is useful for historical purposes and for other team members to get an overview of changes in the history view.</p>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image036" border="0" alt="clip_image036" src="http://devshaped.com/wp-content/uploads/2009/03/clip-image036.jpg" width="500" height="269" /></p>
<p>After checking in our changes, we only need to wait a few seconds to see that CC.NET discovers our change and runs our script.</p>
<p><a href="http://devshaped.com/wp-content/uploads/2009/03/clip-image038.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image038" border="0" alt="clip_image038" src="http://devshaped.com/wp-content/uploads/2009/03/clip-image038-thumb.jpg" width="500" height="123" /></a></p>
<p>Congratulations, you now have a CI-environment up and running!</p>
<h2><b>Going Forward</b></h2>
<p>We have looked at the base tools in a CI-environment, going forward I suggest taking a look at frameworks and tools that works good together with CC.NET. FxCop [8] is a tool from Microsoft that analyzes your assemblies and reports anything that is not according to the industry standards for naming conventions, etc. NCover [9] is a tool which will generate code coverage reports (that means it will highlight which application logic in your application is being covered by unit tests). If you’re a component shop, API documentation is important. Using tools like SandCastle [10] you can automatically generate help files from your XML comments.</p>
<p>There is a whole world to explore and the extension ability to your CI-environment is endless and everything is there to help you improve the process of building good software with high quality.</p>
<p>You should now understand how to setup your own CI-environment using free tools. Best of luck in setting up your own environment! </p>
<h2><b>References:</b></h2>
<p>[1] <a href="http://martinfowler.com/articles/continuousIntegration.html">http://martinfowler.com/articles/continuousIntegration.html</a></p>
<p>[2]<a href="http://www.ericsink.com/scm/scm_intro.html">http://www.ericsink.com/scm/scm_intro.html</a></p>
<p>[3] <a href="http://ccnet.thoughtworks.com/">http://ccnet.thoughtworks.com/</a></p>
<p>[4] <a href="http://nant.sourceforge.net/">http://nant.sourceforge.net/</a></p>
<p>[5] <a href="http://www.nunit.org/">http://www.nunit.org/</a></p>
<p>[6] <a href="http://en.wikipedia.org/wiki/Test-driven_development">http://en.wikipedia.org/wiki/Test-driven_development</a></p>
<p>[7] <a href="http://www.sourcegear.com/">http://www.sourcegear.com/</a></p>
<p>[8] <a href="http://msdn.microsoft.com/en-us/library/bb429476(VS.80).aspx">http://msdn.microsoft.com/en-us/library/bb429476(VS.80).aspx</a></p>
<p>[9] <a href="http://www.ncover.com/">http://www.ncover.com/</a></p>
<p>[10] <a href="http://www.codeplex.com/Sandcastle">http://www.codeplex.com/Sandcastle</a></p>
<h2><b>Sample Soure Code</b> (includes the ccnet.config build script):</h2>
<p><a href="http://devshaped.com/wp-content/uploads/2009/03/IntegrationSample.zip" target="_blank">IntegrationSample.zip</a></p>
<h2><b>Build Script</b></h2>
<pre><span style="color: blue">&lt;</span><span style="color: maroon">cruisecontrol</span> <span style="color: red">xmlns:cb</span>=&quot;<span style="color: blue">urn:ccnet.config.builder</span>&quot;<span style="color: blue">&gt;</span>
 <span style="color: blue">&lt;</span><span style="color: maroon">project</span> <span style="color: red">name</span>=&quot;<span style="color: blue">IntegrationSample</span>&quot;<span style="color: blue">&gt;</span>

  <span style="color: blue">&lt;</span><span style="color: maroon">triggers</span><span style="color: blue">&gt;</span>
   <span style="color: blue">&lt;</span><span style="color: maroon">intervalTrigger</span> <span style="color: red">seconds</span>=&quot;<span style="color: blue">60</span>&quot; /<span style="color: blue">&gt;</span>
  <span style="color: blue">&lt;</span>/<span style="color: maroon">triggers</span><span style="color: blue">&gt;</span>

  <span style="color: blue">&lt;</span><span style="color: maroon">sourcecontrol</span> <span style="color: red">type</span>=&quot;<span style="color: blue">vss</span>&quot; <span style="color: red">autoGetSource</span>=&quot;<span style="color: blue">true</span>&quot; <span style="color: red">applyLabel</span>=&quot;<span style="color: blue">true</span>&quot;<span style="color: blue">&gt;</span>
   <span style="color: blue">&lt;</span><span style="color: maroon">executable</span><span style="color: blue">&gt;</span>C:\Program Files (x86)\Microsoft Visual SourceSafe\ss.exe<span style="color: blue">&lt;</span>/<span style="color: maroon">executable</span><span style="color: blue">&gt;</span>
   <span style="color: blue">&lt;</span><span style="color: maroon">project</span><span style="color: blue">&gt;</span>$/IntegrationSample<span style="color: blue">&lt;</span>/<span style="color: maroon">project</span><span style="color: blue">&gt;</span>
   <span style="color: blue">&lt;</span><span style="color: maroon">username</span><span style="color: blue">&gt;</span>build<span style="color: blue">&lt;</span>/<span style="color: maroon">username</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>Password123<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">ssdir</span><span style="color: blue">&gt;</span>C:\Source\VSS<span style="color: blue">&lt;</span>/<span style="color: maroon">ssdir</span><span style="color: blue">&gt;</span> <span style="color: blue">&lt;</span>!-- Path to your SourceSafe database --<span style="color: blue">&gt;</span>
   <span style="color: blue">&lt;</span><span style="color: maroon">workingDirectory</span><span style="color: blue">&gt;</span>C:\Source\Samples\IntegrationSample\Build\<span style="color: blue">&lt;</span>/<span style="color: maroon">workingDirectory</span><span style="color: blue">&gt;</span>
   <span style="color: blue">&lt;</span><span style="color: maroon">cleanCopy</span><span style="color: blue">&gt;</span>false<span style="color: blue">&lt;</span>/<span style="color: maroon">cleanCopy</span><span style="color: blue">&gt;</span>
  <span style="color: blue">&lt;</span>/<span style="color: maroon">sourcecontrol</span><span style="color: blue">&gt;</span>

  <span style="color: blue">&lt;</span><span style="color: maroon">tasks</span><span style="color: blue">&gt;</span>

   <span style="color: blue">&lt;</span><span style="color: maroon">msbuild</span><span style="color: blue">&gt;</span>
    <span style="color: blue">&lt;</span><span style="color: maroon">executable</span><span style="color: blue">&gt;</span>C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe<span style="color: blue">&lt;</span>/<span style="color: maroon">executable</span><span style="color: blue">&gt;</span>
    <span style="color: blue">&lt;</span><span style="color: maroon">workingDirectory</span><span style="color: blue">&gt;</span>C:\Source\Samples\IntegrationSample\Build\IntegrationSample\<span style="color: blue">&lt;</span>/<span style="color: maroon">workingDirectory</span><span style="color: blue">&gt;</span>
    <span style="color: blue">&lt;</span><span style="color: maroon">projectFile</span><span style="color: blue">&gt;</span>IntegrationSample.sln<span style="color: blue">&lt;</span>/<span style="color: maroon">projectFile</span><span style="color: blue">&gt;</span>
    <span style="color: blue">&lt;</span><span style="color: maroon">buildArgs</span><span style="color: blue">&gt;</span>/noconsolelogger /p:Configuration=Debug /v:m<span style="color: blue">&lt;</span>/<span style="color: maroon">buildArgs</span><span style="color: blue">&gt;</span>
    <span style="color: blue">&lt;</span><span style="color: maroon">targets</span><span style="color: blue">&gt;</span>Build<span style="color: blue">&lt;</span>/<span style="color: maroon">targets</span><span style="color: blue">&gt;</span>
    <span style="color: blue">&lt;</span><span style="color: maroon">timeout</span><span style="color: blue">&gt;</span>720<span style="color: blue">&lt;</span>/<span style="color: maroon">timeout</span><span style="color: blue">&gt;</span>
    <span style="color: blue">&lt;</span><span style="color: maroon">logger</span><span style="color: blue">&gt;</span>C:\Program Files (x86)\CruiseControl.NET\server\ThoughtWorks.CruiseControl.MsBuild.dll<span style="color: blue">&lt;</span>/<span style="color: maroon">logger</span><span style="color: blue">&gt;</span>
   <span style="color: blue">&lt;</span>/<span style="color: maroon">msbuild</span><span style="color: blue">&gt;</span>

   <span style="color: blue">&lt;</span><span style="color: maroon">nunit</span><span style="color: blue">&gt;</span>
    <span style="color: blue">&lt;</span><span style="color: maroon">path</span><span style="color: blue">&gt;</span>C:\Program Files (x86)\NUnit 2.4.8\bin\nunit-console.exe<span style="color: blue">&lt;</span>/<span style="color: maroon">path</span><span style="color: blue">&gt;</span>
    <span style="color: blue">&lt;</span><span style="color: maroon">assemblies</span><span style="color: blue">&gt;</span>
     <span style="color: blue">&lt;</span><span style="color: maroon">assembly</span><span style="color: blue">&gt;</span>C:\Source\Samples\IntegrationSample\Build\IntegrationSample\Integration.Test\bin\Debug\Integration.Test.dll<span style="color: blue">&lt;</span>/<span style="color: maroon">assembly</span><span style="color: blue">&gt;</span>
    <span style="color: blue">&lt;</span>/<span style="color: maroon">assemblies</span><span style="color: blue">&gt;</span>
   <span style="color: blue">&lt;</span>/<span style="color: maroon">nunit</span><span style="color: blue">&gt;</span>

  <span style="color: blue">&lt;</span>/<span style="color: maroon">tasks</span><span style="color: blue">&gt;</span>
 <span style="color: blue">&lt;</span>/<span style="color: maroon">project</span><span style="color: blue">&gt;</span>
<span style="color: blue">&lt;</span>/<span style="color: maroon">cruisecontrol</span><span style="color: blue">&gt;</span></pre>
<p>&#8212;&#8211;</p>
<p>Sondre is a <a href="http://www.microsoftregionaldirectors.com/">Microsoft Regional Director</a> with 11 years of experience in software and web development. He currently works as Technology Leader for the Microsoft department at <a href="http://www.capgemini.no/">Capgemini</a> in Oslo, Norway. Sondre is additionally the leader of the Norwegian .NET User Group in Oslo and a speaker at various technology and software development events. Active blogger, writer and technology enthusiast with a special passion for robotics, intelligent systems and open source.</p>
]]></content:encoded>
			<wfw:commentRss>http://devshaped.com/2009/04/getting-started-with-continuous-integration/feed/</wfw:commentRss>
		<slash:comments>2</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>6</slash:comments>
		</item>
		<item>
		<title>Remaining Valuable to Employers</title>
		<link>http://devshaped.com/2009/04/remaining-valuable-to-employers/</link>
		<comments>http://devshaped.com/2009/04/remaining-valuable-to-employers/#comments</comments>
		<pubDate>Wed, 01 Apr 2009 09:00:00 +0000</pubDate>
		<dc:creator>Derek</dc:creator>
				<category><![CDATA[Features]]></category>
		<category><![CDATA[jobs]]></category>
		<category><![CDATA[skills]]></category>
		<category><![CDATA[video]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://devshaped.com/2009/04/remaining-valuable-to-employers/</guid>
		<description><![CDATA[ The current economic turmoil has left many developers with uncertainties about their jobs. A big question on many people&#8217;s minds is &#34;What can I do to make sure I am the most valuable developer to my current or prospective employer?&#34;
Recently we asked 6 technology leaders to provide some advice on what developers should be [...]]]></description>
			<content:encoded><![CDATA[<p> The current economic turmoil has left many developers with uncertainties about their jobs. A big question on many people&#8217;s minds is &quot;What can I do to make sure I am the most valuable developer to my current or prospective employer?&quot;</p>
<p>Recently we asked 6 technology leaders to provide some advice on what developers should be doing to make themselves more valuable at work.</p>
<p>You might find their perspectives surprising:</p>
<p><object width="560" height="322"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=3869641&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=ff9933&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=3869641&amp;server=vimeo.com&amp;show_title=1&amp;show_byline=1&amp;show_portrait=0&amp;color=ff9933&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="560" height="322"></embed></object></p>
<p><em>(There&#8217;s an embed code if you want to share this video with others on your own site.)</em></p>
]]></content:encoded>
			<wfw:commentRss>http://devshaped.com/2009/04/remaining-valuable-to-employers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>On Strike at the Software Factory</title>
		<link>http://devshaped.com/2009/04/on-strike-at-the-software-factory/</link>
		<comments>http://devshaped.com/2009/04/on-strike-at-the-software-factory/#comments</comments>
		<pubDate>Wed, 01 Apr 2009 09:00:00 +0000</pubDate>
		<dc:creator>Derek</dc:creator>
				<category><![CDATA[Devstory]]></category>
		<category><![CDATA[Crenna]]></category>
		<category><![CDATA[DSL]]></category>
		<category><![CDATA[PeX]]></category>
		<category><![CDATA[software factories]]></category>

		<guid isPermaLink="false">http://devshaped.com/2009/04/on-strike-at-the-software-factory/</guid>
		<description><![CDATA[by Daniel Crenna
 Since there has been software, there has been the dream of the big green button. 
Predictions of the future usually involve elaborate thought-capturing machines that deduce the true desire of an end user and effortlessly create their ideal application, ready for orders, often in the form of a simple form and a [...]]]></description>
			<content:encoded><![CDATA[<p>by <a href="http://dimebrain.com" target="_blank">Daniel Crenna</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="daniel-crenna" border="0" alt="daniel-crenna" align="right" src="http://devshaped.com/wp-content/uploads/2009/03/danielcrenna.jpg" width="85" height="57" /> Since there has been software, there has been the dream of the big green button. </p>
<p>Predictions of the future usually involve elaborate thought-capturing machines that deduce the true desire of an end user and effortlessly create their ideal application, ready for orders, often in the form of a simple form and a big green button promising magic with a label like &#8216;Go&#8217;. This is great for the futurist daydreamer, but terrible for the software developer who lives a life of continuous improvement, watching in horror as their profession is reduced to an afterthought somewhere between waking and the business application someone dreamt up before lunch. This is right around the time that the very emotional craftsmanship debate kicks in, and the humans vs. machines themes spring to awkward, robotic life. </p>
<p>Since the term &quot;software factories&quot; was coined in the late 60&#8217;s by Hitachi, it has been linked inexorably to the manufacturing process it is meant to emulate: people fear that the automation of software components will put developers out of work, or reduce their capacity down to mere assemblers of components rather than authors of code. We hear the buzz in technical communities about the emergence of powerful new software factories, developed by Microsoft and others, and can&#8217;t help but wonder if the intended goal of these new innovations is exactly along those lines. Yet, the people most involved in the software factory movement see it as just the opposite, a way to harness factory processes simply to meet the surging global demand for software at all, let alone with chairs to spare. </p>
<p> <span id="more-96"></span>
<p><em>&quot;We see a capacity crisis looming. The industry continues to hand-stitch applications distributed over multiple platforms housed by multiple businesses located around the planet, automating business processes like health insurance claim processing and international currency arbitrage, using strings, integers and line by line conditional logic. Most developers build every application as though it is the first of its kind anywhere. </em></p>
<p><em><strong>Without significant changes in our methods and practices, global demand for software development and maintenance will vastly exceed the pace at which the industry can deliver in the very near future.</strong>&quot;</em> (from <a href="http://softwarefactories.com)">http://softwarefactories.com)</a></p>
<p>Why should you care about software factories? After all they have that irksome quality of sounding like something meant to replace you. The reality is that software factories are a potential answer to a problem that you live with on a daily basis: change. When a software system changes, it creates risk which often hits your desk in the form of bugs to fix. When businesses change, they adopt new technologies, abandon others, or leverage what they already have in new ways. For developers on the ground, this means you either need to predict the future, or jump hoops in the present to keep up with this change and maintain or acquire the skills that make it work. </p>
<p>The future of computing, arguably, is a repeated pattern from its past: enabling technologies are introduced, adopted, and eventually reach maturity in the wake of the next round of capabilities introduced by innovators. Developers working with bleeding edge technologies knows it&#8217;s their blood. Developers working on mature or sunset systems feel a little out in the cold when they hear what&#8217;s on the horizon. The software factory is rising in popularity as a way to preempt the technology adoption cycle by introducing automation where a developer would spend time on low yield tasks, and encapsulating domain knowledge where a developer would need lengthy, dedicated time with domain experts. Today, factories are even used to allow business experts themselves to change core behavior of their software, without interrupting the software development life cycle. </p>
<p>You already understand the value of re-usability (think open source), maintainability (think unit testing), and replaceable architecture (think layers or seams); what&#8217;s a software factory if only more of the same on a grand, possibly unworkable scale, and what&#8217;s in it for you? Who cares? </p>
<p>As a developer, you should care because the goal of a software factory is to clear a path for you to get to &quot;the good bits&quot;; the business strategy that changes markets, the social networking feature that changes how people communicate, the custom solution that runs a small business like clockwork. In the end you&#8217;re remembered for how you solved a problem, not how separated your concerns were. The sooner you can get to writing the code that matters to your customer, the better. </p>
<p>Within Microsoft itself, a quiet revolution is forming in the labs and in upcoming updates to our most central development tools. Let&#8217;s look at some of the software factories that make up the future of computing on the Microsoft stack. </p>
<h2><strong>Factories for Business Problems </strong></h2>
<p><strong>Domain Specific Language Tools</strong> (<a href="http://msdn.microsoft.com/en-us/library/bb126235.aspx">http://msdn.microsoft.com/en-us/library/bb126235.aspx</a> ) </p>
<p>A domain-specific language, or DSL, is all the rage at the moment and is likely to crop up in many new development projects in the near future. The power of a DSL lies in its ability to define a specific domain (such as the shipping business, or indoor pool maintenance) in a small utility language that is either used by a developer to quickly script up new modules for a large software package, or taught to business users so they can adapt their software to meet their changing needs. Want to change the business logic around preferred customer treatment? It&#8217;s one very human readable line in a script, as opposed to a code change, a check-in, and a redeploy across an organization. A DSL is a software factory because it automates the processes of a specific domain, and the artifacts it creates, in this case scripts for customer treatment behaviors, are as reusable as the language definition itself. Microsoft&#8217;s Domain Specific Language Tools are a collection of visual designers that let you model a DSL visually, similar to the Visual Studio Class Designer or the LINQ to SQL mapping design surface. </p>
<p><strong>M Grammar</strong> (<a href="http://msdn.microsoft.com/en-us/library/dd129870.aspx">http://msdn.microsoft.com/en-us/library/dd129870.aspx</a> ) </p>
<p>Destined to ship as a feature of Visual Studio 2010 and available today as a technical preview, Mg is first class support for DSL language design. Originally intended to work with other tools for defining and parsing schema, such as XML, directly to databases, Mg is useful in its own right for declarative development of DSLs and it will become a popular tool and topic for the future of DSL modelling with Microsoft technologies. </p>
<p>A video detailing Mg from Paul Vick, Microsoft Architect    <br />(<a href="http://www.informit.com/podcasts/episode.aspx?e=E8D94BA1-1B77-4F4D-99CC-BFCE8CE36489)">http://www.informit.com/podcasts/episode.aspx?e=E8D94BA1-1B77-4F4D-99CC-BFCE8CE36489)</a></p>
<h2>Factories for Architecture </h2>
<p>While a DSL would provide a factory for a generalized language, more robust needs require generalized solutions. Several evolutions of full-scale software factories exist in the Microsoft ecosystem, here are a few established and emerging technologies that will allow you to re-brand, repackage, or reconfigure code you&#8217;ve already written, for customers you will have down the line. </p>
<p><strong>Microsoft Enterprise Library</strong> (<a href="http://msdn.microsoft.com/en-us/library/cc467894.aspx">http://msdn.microsoft.com/en-us/library/cc467894.aspx</a> ) </p>
<p>Microsoft&#8217;s Patterns &amp; Practices team developed a true software factory long ago when it introduced the Microsoft Enterprise Library. Designed for composing applications out of blocks of clearly defined enterprise features, MEL reduces the number and scale of repetitive tasks that you face every day on a new software project, such as logging, messaging, services, and to some extent, even the flow and functionality of UI. This library requires a fairly low commitment in terms of education as it builds on existing Microsoft technologies but provides a unified set of repeatable features that every enterprise project needs. </p>
<p><strong>Microsoft Managed Extensibility Framework</strong> (<a href="http://www.codeplex.com/MEF)">http://www.codeplex.com/MEF)</a></p>
<p>A lighter-weight library for building composite applications is available with MEF. Borrowing the term composition from the manufacturing domain, the Managed Extensibility Framework is designed to make it easy for a developer to define application features based on components and configuration rather than reinvent the spinning wheel with one-off software implementations for products that exist in many different instances to satisfy specific customer needs. Still in development, look to MEF to be the application block strategy of the future. </p>
<p><strong>T4 Templates</strong> (<a href="http://msdn.microsoft.com/en-us/library/bb126445.aspx)">http://msdn.microsoft.com/en-us/library/bb126445.aspx)</a></p>
<p>Revisiting the manufacturing paradigm in software factories, the end result of any factory process is a collection of artifacts. Without artifacts, there is no output and no value to use once the smokestack clears. Arguably the lynch pin behind all software factory approaches, template generation is the artifact concept that what you define at a high level can be broken down and generated into working source code at a lower level. In fact, the very same template engine behind the DSL tools developed by Microsoft is available for you, today, with Visual Studio T4 templates. After defining a T4 template, dropping them into your Visual Solution awakens them, using meta-data to create entire frameworks, if necessary. One well-known use of T4 templates is within the SubSonic 3.0 database technology (<a href="http://code.google.com/p/subsonicthree/)">http://code.google.com/p/subsonicthree/)</a>, developed by Rob Conery of Microsoft; the entire framework for database persistence is created using T4 templates dynamically built around your database&#8217;s connection string. </p>
<p><strong>Prism: Composite Application Guidance for WPF and Silverlight</strong> (<a href="http://www.codeplex.com/CompositeWPF/)">http://www.codeplex.com/CompositeWPF/)</a></p>
<p>Need a software factory for differentiated, rich user experiences with the latest Microsoft stack on desktops and the web? Another software factory making a big splash now and in the next few years will undoubtedly be the evolution of Prism. The future of application interfaces involves dynamically assembling behaviors, interactions, effects, and transitions together while being able to reuse each piece in new views. Composition is the buzz word for this new breed of applications that favor declaring what the UI could do, over coding what the UI must do. </p>
<h2>Factories for Code Quality </h2>
<p>Five years ago, the idea that code testing tools could &quot;predict&quot;, &quot;discover&quot;, or &quot;experiment&quot; with source code to find fatal flaws and defend against future quality problems would sound like science fiction, but a new breed of heuristic software factory is emerging from Microsoft Labs in the form of intelligent tools for breaking, and mending, software source code. These will be exciting, cutting-edge projects in your near future, and they&#8217;re available for preview use right now. </p>
<p><strong>PeX</strong> (<a href="http://research.microsoft.com/en-us/projects/Pex)">http://research.microsoft.com/en-us/projects/Pex)</a></p>
<p>The goal of PeX is to automate &quot;white box&quot; unit testing. You already know that unit testing is a safeguard, not a guarantee, of quality programs. You try very hard to achieve 100% code &quot;coverage&quot;, or all possible paths through an application hunting for bugs both glaring and devious. PeX promises the precision of a computer with the craftiness of a human when looking for software programming flaws. It won&#8217;t be a stand-in for writing real unit tests by hand, but will help catch what you miss. </p>
<p><strong>CHESS</strong> (<a href="http://research.microsoft.com/en-us/projects/Chess)">http://research.microsoft.com/en-us/projects/Chess)</a></p>
<p>To paraphrase the immortal Wesley in The Princess Bride, &quot;Concurrent programming is painful, Highness. Anyone who says otherwise is selling something&quot;. Well, in this case, Microsoft Research is on track to improving detecting threading complications in an automated fashion, and you can try it out for free. CHESS looks for &quot;Heisenbugs&quot;, a pet term for uncertain, undefinable, intermittent software defects. You know these as the accounting glitch that only happens on Tuesdays, or the dynamically loaded assembly that crashes every one thousand successful operations. CHESS attempts to bring tooling to finding, and more importantly reproducing the conditions that lead to these strange bugs, so you can squash them. </p>
<h2>Conclusion </h2>
<p>We&#8217;re very far from the big green button, and thankfully so, but the next five to ten years of software development will bring increasing factory-mindedness to the tasks that return the least value-to-investment ratio, accelerate the time to working software iterations, and assist human innovation with computer precision. Developers should embrace anything that allows them to move from the menial to the meaningful, and should not fear the software factory. Life is too short for one developer to deliver all of the technology that his or her world demands, but software factories in the hands of skilled developers can; factories are the past, present, and future of computing.</p>
<p>&#8212;&#8211;</p>
<p>Daniel Crenna is a Microsoft MVP and creator of TweetSharp, an open-source Twitter API development library. Daniel is focused on improving the landscape for .NET developers building social software through founding <a href="http://www.dimebrain.com">www.dimebrain.com</a>. Daniel was a contributor to the Microsoft AJAX Control Toolkit, and is a Microsoft Certified Professional Developer.</p>
]]></content:encoded>
			<wfw:commentRss>http://devshaped.com/2009/04/on-strike-at-the-software-factory/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Ted Neward on Programming Languages</title>
		<link>http://devshaped.com/2009/03/ted-neward-on-programming-languages/</link>
		<comments>http://devshaped.com/2009/03/ted-neward-on-programming-languages/#comments</comments>
		<pubDate>Sun, 01 Mar 2009 10:00:00 +0000</pubDate>
		<dc:creator>Derek</dc:creator>
				<category><![CDATA[Audio]]></category>

		<guid isPermaLink="false">http://devshaped.com/?p=59</guid>
		<description><![CDATA[ In this audio interview, Ted Neward provides some guidance for VB and C# developers interested in learning a new programming languages.
Be sure to read Ted&#8217;s article &#34;Beyond VB and C#&#34;.
]]></description>
			<content:encoded><![CDATA[<p><img style="border-bottom: 0px; border-left: 0px; margin: 0px 0px 22px 22px; display: inline; border-top: 0px; border-right: 0px" title="ted_neward" border="0" alt="ted_neward" align="right" src="http://devshaped.com/wp-content/uploads/2009/02/ted-neward2.jpg" width="85" height="57" /> In this audio interview, Ted Neward provides some guidance for VB and C# developers interested in learning a new programming languages.</p>
<p>Be sure to read Ted&#8217;s article &quot;<a href="http://devshaped.com/2009/03/beyond-vb-and-c/" target="_blank">Beyond VB and C#</a>&quot;.</p>
]]></content:encoded>
			<wfw:commentRss>http://devshaped.com/2009/03/ted-neward-on-programming-languages/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
			<enclosure url="http://devshaped.com/audio/TedNewardOnLanguages.mp3" length="9808385" type="audio/mpeg"/>
<itunes:duration>20:26</itunes:duration>
		<itunes:subtitle>In this audio interview, Ted Neward provides some guidance for VB and C# developers interested in learning a new programming languages.  Be sure ...</itunes:subtitle>
		<itunes:summary>In this audio interview, Ted Neward provides some guidance for VB and C# developers interested in learning a new programming languages.  Be sure to read Ted's article #34;Beyond VB and C##34;.
</itunes:summary>
		<itunes:keywords>Audio</itunes:keywords>
		<itunes:author>derek@webradius.com</itunes:author>
		<itunes:explicit>no</itunes:explicit>
		<itunes:block>No</itunes:block>
	</item>
	</channel>
</rss>
