<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://mail.simple-talk.com/community/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Donahue, Crash Scene Investigator</title><link>http://mail.simple-talk.com/community/blogs/brian_donahue/default.aspx</link><description>Red Gate Support Engineer</description><dc:language>en-US</dc:language><generator>CommunityServer 2.0 (Build: 60217.2664)</generator><item><title>Installing databases using Wix</title><link>http://mail.simple-talk.com/community/blogs/brian_donahue/archive/2008/11/06/70374.aspx</link><pubDate>Thu, 06 Nov 2008 22:07:00 GMT</pubDate><guid isPermaLink="false">f46e5dea-70cd-4a69-a7e1-fd07a313bd4d:70374</guid><dc:creator>Brian Donahue</dc:creator><slash:comments>1</slash:comments><comments>http://mail.simple-talk.com/community/blogs/brian_donahue/comments/70374.aspx</comments><wfw:commentRss>http://mail.simple-talk.com/community/blogs/brian_donahue/commentrss.aspx?PostID=70374</wfw:commentRss><description>In the promised second half of my &lt;A href="http://wix.sourceforge.net/"&gt;Wix&lt;/A&gt; installment, I am going to demonstrate how you can install a SQL Server database as part of a software deployment using Wix and &lt;A href="http://www.red-gate.com/Products/SQL_Packager"&gt;SQL Packager &lt;/A&gt;from Red Gate. &lt;BR&gt;&lt;BR&gt;In my experience, your average software company has exactly one "Installer Guy". Typically, this is a very unappreciated fellow who does tons of tedious work to effectively jimmy components onto a user's computer using the blunt instrument known as Windows Installer. If there was a "hot or not" scale of development sexiness, you would put "Installer Guy" at the definitive "not" end of the scale. But I digress.&lt;BR&gt;&lt;BR&gt;One of the many things Windows Installer can't do is to put a SQL database on someone's computer, and given the number of programs being shipped that have a SQL Server back-end database, this is&amp;nbsp;darn shame.&amp;nbsp;How to accomplish this herculean task has been approached in many different ways by many third-parties, and Wix even has an extension that will get an installer to create databases and run rudimentary SQL.&lt;BR&gt;&lt;BR&gt;However, there is more to database deployment than just pushing a SQL script into an installer, there is the maintainability factor, or how to seperate the development of the SQL from the development of the installer code. There is the recovery factor, or which SQL to run if the installer fails. Finally, there is the upgrade factor, or how to ship database upgrade scripts with the conventional component upgrades such as files and assemblies.&lt;BR&gt;&lt;BR&gt;Considering the above factors, SQL Packager can solve a lot of the&amp;nbsp;SQL maintanence&amp;nbsp;challenges by wrapping the scripts to create or upgrade database into a single program that will run the database creation or upgrade scripts when executed. Wix allows you to build "Custom Actions" that include the ability to run console-based programs and even suppress the output from them.&lt;BR&gt;&lt;BR&gt;For my example, I have created a database package using SQL Packager for the version 1.0 of my sample product "Packager Test", called SQLPackagerBaseline.exe. I want to run this silently, and I can accomplish this using the wixca library that comes with Wix, which provides a function called CAQuietExec. In the InstallExecuteSequence table, we add these custom actions, their sequencing, and the condition which will cause them to execute. In this example, for instance, a database is only installed if this is a new installation, and if the user specified SQL authentication, the properties are set appropriately.&lt;BR&gt;&lt;BR&gt;&amp;lt;!-- Add wixca.dll into the Binary table --&amp;gt;&lt;BR&gt;&lt;FONT color=#0000ff size=2&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;Binary&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Id&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;wixca&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;src&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;$(env.WIXROOT)\wixca.dll&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;gt;&lt;BR&gt;&lt;/FONT&gt;&amp;lt;!-- Deferred custom actions can't access properties, so they have to be set using a custom action --&amp;gt;&lt;BR&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;CustomAction&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Id&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Database.Install.Properties&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Property&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Database.Install&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Value&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&amp;amp;quot;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;[SQLPACKAGEFOLDER]SQLPackagerBaseline.exe&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&amp;amp;quot;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; /server:[SERVERNAME] /database:[DATABASENAME] /quiet /makedatabase&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;CustomAction&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Id&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Database.Install.Properties.Sql&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Property&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Database.Install&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Value&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&amp;amp;quot;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;[SQLPACKAGEFOLDER]SQLPackagerBaseline.exe&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&amp;amp;quot;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; /server:[SERVERNAME] /database:[DATABASENAME] /username:[DBUSERNAME] /password:[PASSWORD] /quiet /makedatabase&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;gt;&lt;BR&gt;&lt;FONT color=#000000 size=3&gt;&amp;lt;!-- The custom action itself --&amp;gt;&lt;BR&gt;&lt;/FONT&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;CustomAction&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Id&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Database.Install&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Impersonate&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;yes&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;BinaryKey&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;wixca&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;DllEntry&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;CAQuietExec&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Execute&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;deferred&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Return&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;check&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;gt;&lt;/FONT&gt;&lt;BR&gt;&amp;lt;!-- Our custom tasks run in the InstallExecuteSequence --&amp;gt;&lt;BR&gt;&lt;FONT color=#0000ff size=2&gt;&amp;lt;!--&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt; install and uninstall conditions included &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;--&amp;gt;&lt;BR&gt;&amp;lt;!--&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt; (componentname=2 means to run only on uninstall) &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;--&amp;gt;&lt;BR&gt;&amp;lt;!--&lt;/FONT&gt;&lt;FONT color=#008000 size=2&gt; (componentname&amp;amp;gt;2 means to run only on install) &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;--&amp;gt;&lt;/P&gt;
&lt;P&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;InstallExecuteSequence&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;RemoveExistingProducts&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;After&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Database.Drop&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;/FONT&gt;&lt;FONT size=2&gt;$PackagerTest.Packages=2&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;lt;/&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;RemoveExistingProducts&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;Custom&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Action&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Database.Drop.Properties&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Before&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;RemoveFiles&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;/FONT&gt;&lt;FONT size=2&gt;$PackagerTest.Packages=2&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;lt;/&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;Custom&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;Custom&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Action&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Database.Drop&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;After&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Database.Drop.Properties&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;/FONT&gt;&lt;FONT size=2&gt;$PackagerTest.Packages=2&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;lt;/&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;Custom&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;Custom&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Action&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Database.Install.Properties&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;After&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;InstallFiles&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;/FONT&gt;&lt;FONT size=2&gt;$PackagerTest.Packages&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&amp;amp;gt;&lt;/FONT&gt;&lt;FONT size=2&gt;2&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;lt;/&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;Custom&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;Custom&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Action&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Database.Install.Properties.Sql&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;After&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Database.Install.Properties&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;/FONT&gt;&lt;FONT size=2&gt;$PackagerTest.Packages&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&amp;amp;gt;&lt;/FONT&gt;&lt;FONT size=2&gt;2 AND USEINTEGRATEDSECURITY=0&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;lt;/&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;Custom&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;Custom&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Action&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Database.Install&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;After&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Database.Install.Properties.Sql&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;/FONT&gt;&lt;FONT size=2&gt;$PackagerTest.Packages&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&amp;amp;gt;&lt;/FONT&gt;&lt;FONT size=2&gt;2 AND USEINTEGRATEDSECURITY=1&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;lt;/&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;Custom&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;lt;/&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;InstallExecuteSequence&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;/P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;BR&gt;The second major bit of work installing a database is to build a user interface. Wix comes with several vanilla user interfaces, such as Wix_Mondo, that you can use without having to design anything yourself. Unfortunately, there is no set of dialogs that you can use to specify the properties of a database, and you may find, like I have, that it's better to hand-code the whole user interface yourself to get exactly the kind of dialogs that you want. In my example, for instance, the "user name" and "password" edit boxes are grayed-out when Integrated Security is used. I have also included my own banner to brand my installation with.&lt;BR&gt;&lt;BR&gt;One thing that is not documented too well is that the coordinates for placing controls on an Installer dialog are in "installer units" and nobody on planet Earth knows how many pixels correspond to an installer unit. For instance, the dialog below is 370x220 "Installer Units", but the banner is 494x59 pixels in size.&lt;BR&gt;&lt;BR&gt;&lt;IMG src="/blogbits/chris_massey/SqlServerDlg.png"&gt;&lt;BR&gt;&lt;BR&gt;Something that you can do in Wix that you cannot do in Visual Studio Setup and Deployment is to write custom action progress messages to the progress bar. The only way to make the progress bar move, unfortunately, is to code this into your custom action. But at least your user will know what the installer is doing if your database package takes a long time to run!&lt;BR&gt;&lt;FONT color=#0000ff size=2&gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;ProgressText&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Action&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Database.Install&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;/FONT&gt;&lt;FONT size=2&gt;Installing database &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&amp;amp;quot;&lt;/FONT&gt;&lt;FONT size=2&gt;[DATABASENAME]&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&amp;amp;quot;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;lt;/&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;ProgressText&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&lt;/FONT&gt;&lt;BR&gt;I have highlighted a lot of the more interesting points of deploying a database as part of a product installation based on Wix and Windows Installer technologies, but there is so much more going on, that it wouldn't fit into a simple blog. In fact I think I can see you dozing off already!&lt;BR&gt;&lt;BR&gt;If you want to see the complete Wix project, including the user interface dialogs and SQL Package file, please download the zip file at the end of this post and feel free to probe and dissect the wix code. Hopefully this sample makes it easier for someone to install a database as part of a Windows product installation.&lt;/P&gt;&lt;img src="http://mail.simple-talk.com/community/aggbug.aspx?PostID=70374" width="1" height="1"&gt;</description><enclosure url="http://mail.simple-talk.com/community/blogs/brian_donahue/attachment/70374.ashx" length="150663" type="application/x-zip-compressed" /></item><item><title>Arrrrgh! Wix!</title><link>http://mail.simple-talk.com/community/blogs/brian_donahue/archive/2008/10/21/70135.aspx</link><pubDate>Tue, 21 Oct 2008 23:56:00 GMT</pubDate><guid isPermaLink="false">f46e5dea-70cd-4a69-a7e1-fd07a313bd4d:70135</guid><dc:creator>Brian Donahue</dc:creator><slash:comments>4</slash:comments><comments>http://mail.simple-talk.com/community/blogs/brian_donahue/comments/70135.aspx</comments><wfw:commentRss>http://mail.simple-talk.com/community/blogs/brian_donahue/commentrss.aspx?PostID=70135</wfw:commentRss><description>&lt;P&gt;This week's time-eater, for me, was to try to create an installer package (MSI) with custom actions that install databases on SQL Servers. Typically, I had grown to like Microsoft Visual Studio Deployment Projects, because I could easily knock out some C# code and slam it into an installer and get it to do, basically, anything I want.&lt;/P&gt;
&lt;P&gt;A few days ago, though, all I had at my disposal was Mister Pokey, the Little Computer That Couldn't. Since Mister Pokey is less than gifted in the processor department, all he runs is the "Express" version of Visual Studio. It's nice for sticking together little projects, writing a little puzzle game, and things like that, but it is minus the Deployment Project Wizard.&lt;/P&gt;
&lt;P&gt;I remember some developers telling me that VS Deployment is for girls, and the manly-man programmer type uses WIX, you know, because it's bl**dy difficult to understand, which makes them feel all better about themselves, or something. How hard could that be? Well, it's not entirely obvious how to use it.&lt;/P&gt;
&lt;P&gt;To make a long story short, you'll need to know installers inside-and-out before you can attempt to compile a WIX installer. There is no UI (well there is Votive, which I haven't tried out), and the documentation isn't brilliant. But on the plus side it is a gimmie and allows for incredibly fine-grained control.&lt;/P&gt;
&lt;P&gt;If you do want to&amp;nbsp;deploy&amp;nbsp;an existing Windows Installer class that you had created using the VS deployment project in WIX, this is a hard-won battle, but possible. Even though the author of WIX is dead against it and every Installer Jockey at Red Gate tells me that managed installers cause grief and famine and cataclysm beyond imagination. Just to irk them, here is the code. If you want to know how to get these .ibd files, what you basically have to do is reverse-engineer one of your existing VS deployment MSIs using Orca. Actually you could use WIX (dark -x &amp;lt;msiname&amp;gt;.msi, to be specific) but I couldn't get that going. I used Orca to export the Binary table of my old installer and plopped the whole mess into a subfolder called "Binary".&lt;/P&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;&amp;lt;?&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;xml&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;version&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;1.0&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;encoding&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;utf-8&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;?&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;Wix&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;xmlns&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;http://schemas.microsoft.com/wix/2003/01/wi&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;Product&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;UpgradeCode&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;79C0A2EF-7A27-4227-9323-376F8D643C42&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Name&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Packager Test&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Id&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;4AD025EB-922B-44E1-84B6-B5CC05F19A00&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Version&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;1.0.0&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Manufacturer&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Brian Donahue&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Language&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;1033&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;Package&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Id&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;C83C3011-4205-40AA-8E0B-4106A33E9391&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Manufacturer&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Brian Donahue&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;InstallerVersion&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;200&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Platforms&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Intel&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Languages&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;1033&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Compressed&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;yes&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;SummaryCodepage&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;1252&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;Media&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Id&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;1&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;EmbedCab&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;yes&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Cabinet&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Test.cab&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;Binary&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Id&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;InstallUtil&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;src&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Binary\InstallUtil.ibd&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;Binary&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Id&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;MSVBDPCADLL&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;src&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Binary\MSVBDPCADLL.ibd&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;Binary&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Id&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;VSDNETCFG&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;src&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Binary\VSDNETCFG.ibd&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;gt;&lt;/P&gt;
&lt;P&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;Directory&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Id&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;TARGETDIR&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Name&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;SourceDir&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;Directory&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Id&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;TestDir&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Name&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Test&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;Component&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Id&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;TestInstaller.dllComponent&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Guid&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;2B6D1187-9DBC-7A6F-B9ED-E6AD9DD6D248&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;File&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Id&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;PkgInstaller.dllFile&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Name&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;SQLPAC.dll&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;LongName&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;SqlPackagerDeployment.dll&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Vital&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;yes&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;KeyPath&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;yes&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;DiskId&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;1&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;src&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;SQLPackagerDeployment.dll&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;File&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Id&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;BaselinePackage.exeFile&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Name&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;SQLPAB.exe&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;LongName&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;SQLPackagerBaseline.exe&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Vital&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;yes&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;DiskId&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;1&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;src&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;SQLPackagerBaseline.exe&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;File&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Id&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;UpgradePackage.exeFile&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Name&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;SQLPA1.exe&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;LongName&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;SQLPackagerUpgrade1.exe&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Vital&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;yes&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;DiskId&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;1&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;src&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;SQLPackagerUpgrade1.exe&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;gt;&lt;BR&gt;&amp;lt;/&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;Component&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;lt;/&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;Directory&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;lt;/&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;Directory&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;/P&gt;
&lt;P&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;Feature&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Id&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;DefaultFeature&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Level&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;1&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;ConfigurableDirectory&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;TARGETDIR&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;ComponentRef&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Id&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;TestInstaller.dllComponent&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;gt;&lt;BR&gt;&amp;lt;/&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;Feature&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;/P&gt;
&lt;P&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;CustomAction&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Id&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;SetPrereqs&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;BinaryKey&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;MSVBDPCADLL&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;DllEntry&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;CheckFX&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;CustomAction&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Id&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;TestInstaller.dllUninstall.uninstall&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;BinaryKey&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;InstallUtil&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;DllEntry&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;ManagedInstall&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Execute&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;deferred&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;CustomAction&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Id&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;TestInstaller.dllUninstall.uninstall.SetProperty&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Property&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;TestInstaller.dllUninstall.uninstall&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Value&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;/installtype=notransaction /action=uninstall /LogFile= &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&amp;amp;quot;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;[#PkgInstaller.dllFile]&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&amp;amp;quot;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&amp;amp;quot;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;[VSDFxConfigFile]&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&amp;amp;quot;&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;CustomAction&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Id&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;TestInstaller.dllInstall.install&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;BinaryKey&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;InstallUtil&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;DllEntry&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;ManagedInstall&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Execute&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;deferred&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;CustomAction&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Id&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;TestInstaller.dllInstall.install.SetProperty&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Property&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;TestInstaller.dllInstall.install&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Value&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;/installtype=notransaction /action=install /LogFile= /SERVER=localhost /DATABASE=SqlPackagerExample &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&amp;amp;quot;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;[#PkgInstaller.dllFile]&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&amp;amp;quot;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&amp;amp;quot;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;[VSDFxConfigFile]&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&amp;amp;quot;&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;InstallExecuteSequence&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;/P&gt;
&lt;P&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;Custom&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Action&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;SetPrereqs&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Before&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;AppSearch&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;Custom&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Action&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;TestInstaller.dllUninstall.uninstall.SetProperty&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;After&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;MsiUnpublishAssemblies&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;/FONT&gt;&lt;FONT size=2&gt;$TestInstaller.dllComponent=2&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;lt;/&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;Custom&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;Custom&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Action&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;TestInstaller.dllUninstall.uninstall&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;After&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;TestInstaller.dllUninstall.uninstall.SetProperty&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;/FONT&gt;&lt;FONT size=2&gt;$TestInstaller.dllComponent=2&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;lt;/&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;Custom&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;Custom&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Action&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;TestInstaller.dllInstall.install.SetProperty&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;After&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;SetPrereqs&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;/FONT&gt;&lt;FONT size=2&gt;$TestInstaller.dllComponent&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&amp;amp;gt;&lt;/FONT&gt;&lt;FONT size=2&gt;2&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;lt;/&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;Custom&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;Custom&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;Action&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;TestInstaller.dllInstall.install&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;After&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;TestInstaller.dllInstall.install.SetProperty&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;/FONT&gt;&lt;FONT size=2&gt;$TestInstaller.dllComponent&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;&amp;amp;gt;&lt;/FONT&gt;&lt;FONT size=2&gt;2&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;lt;/&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;Custom&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;lt;/&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;InstallExecuteSequence&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;/P&gt;
&lt;P&gt;&amp;lt;/&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;Product&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;lt;/&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;Wix&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;/P&gt;&lt;/FONT&gt;
&lt;P&gt;Now we can compile the WIX script using the very intuitive tools that come with it. And by "intuitive" I mean "batch file". The file above has been named "DBInstaller.wxs".&lt;/P&gt;&lt;FONT size=2&gt;
&lt;P&gt;@Echo please ensure candle, light and csc are on the path!&lt;BR&gt;del /Q output\*&lt;BR&gt;rmdir output&lt;BR&gt;mkdir output&lt;BR&gt;..\candle DBInstaller.wxs /out output\DBInstaller.wixobj&lt;BR&gt;..\light output\DBInstaller.wixobj /out output\DBInstaller.msi&lt;BR&gt;msiexec -lv* output\log.txt -i output\DBInstaller.msi&lt;/P&gt;&lt;/FONT&gt;
&lt;P&gt;What this WIX package does is to run a very simple installer with no UI. On Install, the SQLPackagerDeployment.dll is used with the arguments /SERVER=localhost and /DATABASE=SqlPackagerExample. You have to be very careful about the order of the arguments... whatever you do, the last two arguments to the CustomAction value have to remain intact! &lt;FONT size=2&gt;$TestInstaller.dllComponent=2&amp;nbsp; &lt;/FONT&gt;makes the custom action run only when uninstalling, and &amp;gt;2 makes the custom action run only when installing.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Of course, since managed installers will cause a rift in the space-time continuum, I have re-implemented the whole thing in VBScript. I'm saving that story for later!&lt;/P&gt;&lt;img src="http://mail.simple-talk.com/community/aggbug.aspx?PostID=70135" width="1" height="1"&gt;</description></item><item><title>ASP .NET: when a crash is not a crash</title><link>http://mail.simple-talk.com/community/blogs/brian_donahue/archive/2008/09/24/69695.aspx</link><pubDate>Wed, 24 Sep 2008 15:39:00 GMT</pubDate><guid isPermaLink="false">f46e5dea-70cd-4a69-a7e1-fd07a313bd4d:69695</guid><dc:creator>Brian Donahue</dc:creator><slash:comments>2</slash:comments><comments>http://mail.simple-talk.com/community/blogs/brian_donahue/comments/69695.aspx</comments><wfw:commentRss>http://mail.simple-talk.com/community/blogs/brian_donahue/commentrss.aspx?PostID=69695</wfw:commentRss><description>&lt;P&gt;In the mysterious viscera of Microsoft Internet Information Server, nothing is as it seems. When applications are designed to work over the web, they must bristle with all sorts of&amp;nbsp;bits designed to make the stateless stateful and many users become one inside the web server's inner sanctum.&lt;/P&gt;
&lt;P&gt;What I am talking about are the fundamental differences in behavior between a bit of .NET code and ASP .NET code, and the processes that keep ASP .NET applications capable and highly available.&lt;/P&gt;
&lt;P&gt;In traditional desktop applications, an unhandled exception would cause an exit with an error condition and probably log it&amp;nbsp;to the application event log. If this were to happen in a web application, it would become unavailable without the end-user having the ability to restart it. For this reason, ASP .NET web applications have a number of features that allow it to recover almost seamlessly from an unhandled exception or a lack of resources on the server. Unfortunately for troubleshooting purposes, this means that your web application can exit gracefully before you even hit the problem you're trying to debug.&lt;/P&gt;
&lt;P&gt;The Application Domain, or AppDomain, can isolate many "applications" which are actually running in the same process. If one of these applications misbehaves, it can be "unloaded" from the process, and in many cases the objects inside can be recovered and copied into a new AppDomain. The ASP .NET Worker Process, which is the process that can host one or more of these AppDomains, has many functions that can determine when to load and unload an application, and to detect whether or not the application is "healthy". In many cases, the parameters for determining application health are set by the administrator, whether he knows it or not!&lt;/P&gt;
&lt;P&gt;An AppDomain recycle can occur for many reasons:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;The application is using too much memory&lt;/LI&gt;
&lt;LI&gt;The application has&amp;nbsp;serviced a set number of requests&lt;/LI&gt;
&lt;LI&gt;The application is taking a long time to respond&lt;/LI&gt;
&lt;LI&gt;The application has remained idle for a long time&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;In the case of newer versions of IIS, particularly versions 6 and 7, the Worker Process Isolation model will log the reasons for an application recycle, but not for all reasons. In IIS 5, your worker process simply exits if there are no more AppDomains loaded into it. The fact that the worker process can just exit without leaving an event log entry or throwing an unhandled exception makes debugging incredibly frustrating.&lt;/P&gt;
&lt;P&gt;I have not found a foolproof method for stopping an ASP .NET worker process from recycling, so I rely on ASP .NET 2.0 health monitoring to log any "conventional" application restarts due to a lack of memory or other environmental factors and then adjust my machine.config processModel and web.config to try to prevent the recycle while I am trying to debug the application. All that is needed is one line added to the master web.config, which you will find in the .NET Framework configuration folder (%systemroot%\microsoft.net\framework\v2.0.50727\config). Adding a rule to log every application recycle will actually allow you to see the reason why an application has shut down for a recycle.&lt;/P&gt;
&lt;P&gt;First, look for the healthMonitoring node, then rules, and add the following:&lt;/P&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;healthMonitoring&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;...&lt;BR&gt;&lt;FONT color=#0000ff size=2&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;rules&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;add&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;name&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Application Lifetime Events Default&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;eventName&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Application Lifetime Events&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;provider&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;EventLogProvider&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;profile&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Default&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;minInstances&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;1&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;maxLimit&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;Infinite&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;minInterval&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;00:01:00&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;custom&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;""&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;gt;&lt;BR&gt;...&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#000000&gt;Once this has been saved, ASP .NET will leave behind a friendly reminder that it has recycled the application pool:&lt;/FONT&gt;&lt;/P&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;Event Type:&lt;SPAN&gt;&amp;nbsp; &lt;/SPAN&gt;Information&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;Event Source:&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;ASP.NET 2.0.50727.0&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;Event Category:&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;Web Event &lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;Event ID:&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;1305&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;Date:&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;2008-09-23&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;Time:&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;13:33:19&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;User:&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/SPAN&gt;N/A&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;Computer:&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; XXXXXXX&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;Description:&lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;Event code: 1002 &lt;o:p&gt;&lt;/o:p&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;B&gt;&lt;SPAN&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;Event message: Application is shutting down. Reason: Configuration changed. &lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/B&gt;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;B&gt;&lt;SPAN&gt;&lt;FONT face="Courier New"&gt;&lt;FONT size=2&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/B&gt;&amp;nbsp;&lt;/P&gt;
&lt;P class=MsoNormal&gt;&lt;SPAN&gt;&lt;FONT face="Times New Roman" color=#000000 size=3&gt;In this case, I would recommend disabling any anti-virus software, as it may be modifying some of the ASP .NET application source code. There are many other reasons for an application shutdown that can usually be solved by &lt;/FONT&gt;&lt;A href="http://msdn.microsoft.com/en-us/library/system.web.configuration.processmodelsection.aspx"&gt;&lt;FONT face="Times New Roman" color=#000000 size=3&gt;modifying the Framework's machine.config&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face="Times New Roman" color=#000000 size=3&gt;&amp;nbsp;file.&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;BR&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://mail.simple-talk.com/community/aggbug.aspx?PostID=69695" width="1" height="1"&gt;</description></item><item><title>Object-level recovery from backup is here!</title><link>http://mail.simple-talk.com/community/blogs/brian_donahue/archive/2008/08/16/68713.aspx</link><pubDate>Sat, 16 Aug 2008 17:04:00 GMT</pubDate><guid isPermaLink="false">f46e5dea-70cd-4a69-a7e1-fd07a313bd4d:68713</guid><dc:creator>Brian Donahue</dc:creator><slash:comments>5</slash:comments><comments>http://mail.simple-talk.com/community/blogs/brian_donahue/comments/68713.aspx</comments><wfw:commentRss>http://mail.simple-talk.com/community/blogs/brian_donahue/commentrss.aspx?PostID=68713</wfw:commentRss><description>&lt;P&gt;Version 7 of the &lt;A href="http://www.red-gate.com/products/SQL_Comparison_SDK/index.htm"&gt;Red Gate SQL Comparison SDK &lt;/A&gt;has finally brought the possibility&amp;nbsp;of recovering&amp;nbsp;individual objects from a Microsoft SQL Server backup to a live database. I found this an exciting opportunity to flex the old noggin and design a program that can restore schema and associated data from a backup file to a real database.&lt;/P&gt;
&lt;P&gt;The reasons why you would want to do this are vaired. For example, I've heard it would be useful for database normalization, inserting test data, and some obscure disaster recovery situations. Of course, the compelling reason for me is "because I can"!&lt;/P&gt;
&lt;P&gt;Simply restoring a table and its' data alone could have unintended consequences. For example, what happens when foreign keys exist between the table you want to restore and other tables? What if the table has dependent objects, such as a default bound to a user-defined function? The SQL Compare Engine can handle all of these things because of its' dependency engine which can create all dependencies in the proper order. The Data Compare Engine can also handle foreign key relationships, triggers, and unique constraints.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;IMG src="/community/blogs/brian_donahue/attachment/68713.ashx"&gt;&lt;/P&gt;
&lt;P&gt;This means that you could insert a stored procedure from a backup, and the API can add the tables and other objects that the procedure needs, or even adjust the existing schema so that the stored procedure will run without errors!&lt;/P&gt;
&lt;P&gt;The example program can do this and more: if the schema object being recovered is a table, all existing data will be altered, superfluous data deleted, and new data inserted so the live database will exactly match the data in the backup. In this example, the table must have a primary key or unique index to match rows of data together. It would be possible to add extra logic to allow the user to pick one or more columns to act as&amp;nbsp;the basis for a&amp;nbsp;comparison key.&lt;/P&gt;
&lt;P&gt;The only downside to combining schema and data recovery from backup using the SDK is that, because the SQL Compare Engine is optimized to retrieve schema and the Data Compare Engine is optimized to retrieve data, it is necessary to read the backup twice in order to retrieve schema and data. Hopefully Red Gate can combine the two engines in the future to make the process more efficient!&lt;/P&gt;
&lt;P&gt;The example C# project can be downloaded from the Red Gate Labs site: &lt;A href="http://labs.red-gate.com/uploads/5/54/SQL_Object-Level_Restore.zip"&gt;http://labs.red-gate.com/uploads/5/54/SQL_Object-Level_Restore.zip&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;You will also need to install the assemblies from SQL Compare and SQL Data Compare by downloading the &lt;A href="http://www.red-gate.com/products/SQL_Comparison_SDK/index.htm"&gt;SQL Comparison SDK&lt;/A&gt;.&lt;/P&gt;&lt;img src="http://mail.simple-talk.com/community/aggbug.aspx?PostID=68713" width="1" height="1"&gt;</description><enclosure url="http://mail.simple-talk.com/community/blogs/brian_donahue/attachment/68713.ashx" length="25858" type="image/x-png" /></item><item><title>Man eats crow, film at eleven</title><link>http://mail.simple-talk.com/community/blogs/brian_donahue/archive/2008/08/12/67949.aspx</link><pubDate>Tue, 12 Aug 2008 15:57:00 GMT</pubDate><guid isPermaLink="false">f46e5dea-70cd-4a69-a7e1-fd07a313bd4d:67949</guid><dc:creator>Brian Donahue</dc:creator><slash:comments>0</slash:comments><comments>http://mail.simple-talk.com/community/blogs/brian_donahue/comments/67949.aspx</comments><wfw:commentRss>http://mail.simple-talk.com/community/blogs/brian_donahue/commentrss.aspx?PostID=67949</wfw:commentRss><description>&lt;P&gt;Last week I'd had a bit of&amp;nbsp;a rant here about not using software for anything other than what it is designed to do. Thinking back, though, I have done this quite a few times myself, particularly by employing a code profiler to do the job of a debugger.&lt;/P&gt;
&lt;P&gt;When good software goes bad, the right axe to wield at it is usually a debugger. Anyone who has used a debugger will probably tell you that this is a last resort, though, unless they are masochists who enjoy inflicting mental anguish on themselves. Even with the whizzy .NET runtime environment we have now, trying to find the cause of a crash or hang using a debugger requires quite a lot of patience, skill, and experience.&lt;/P&gt;
&lt;P&gt;Yesterday, I had to try to diagnose a program hang --&amp;nbsp;not my favorite thing in the world. So off I went as I have done squillions of times, using the old auto-dumper from Microsoft to get a dump file for analysis:&lt;/P&gt;
&lt;P&gt;cscript adplus.vbs -hang -pn MyFlakyProgram.exe&lt;/P&gt;
&lt;P&gt;Only this time, the debugger died before reaching the critical part of the code, making a dump too early and detatching from MyFlakyProgram. What now? Debug the debugger?&lt;/P&gt;
&lt;P&gt;It was time to rummage through the old toolbox and see what else I could do. I have a code profiler -- sure, why not? I had attached a code profiler to the flaky application, got to the critical bit, and took a snapshot. Then another. It seemed that the application had been running a SqlDataReader.Close() method for about 214 seconds by then, which sounds about as far from normal as Timbuktu is from where I'm sitting.&lt;/P&gt;
&lt;P&gt;Honestly, I still haven't worked out &lt;EM&gt;why&lt;/EM&gt; this had happened yet, but I am that critical one step closer, no thanks to the CDB debugger that crashed out on me.&lt;/P&gt;
&lt;P&gt;The other time I had used a code profiler in an unorthodox way was to try to figure out why an application was crashing with a TypeInitializationException. Again, this happened too quickly to have time to attach a debugger (yes, I know about the ImageFileExecutionOptions registry key, but haven't you figured out how unapologetically lazy I am yet?).&lt;/P&gt;
&lt;P&gt;TypeInitializationExceptions are thrown when an application is first being loaded into the .NET runtime, so there is no possibility to get a stack trace when the program bombs. You'll never, ever figure out what has happened without some sort of Intermediate Language X-Ray machine, which is&amp;nbsp;sort-of what a code profiler does.&lt;/P&gt;
&lt;P&gt;The profiler also shows the method results in more-or-less chronological order, so maybe, just maybe, I could work out what the last method executed by the errant program had been. And&amp;nbsp;as by&amp;nbsp;a &lt;A href="http://en.wikipedia.org/wiki/Crepuscular_rays"&gt;crepuscular ray of light&lt;/A&gt;, the answer was illuminated -- someone had put a method that enumerates printers inside a type initializer (the bit of a class where variables are declared and have their initial values set). Here was the culprit:&lt;/P&gt;&lt;FONT size=2&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;internal&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;class&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;MyForm&lt;/FONT&gt;&lt;FONT size=2&gt; : System.Windows.Forms.&lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;Form&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;{...&lt;/P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;private&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;static&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;bool&lt;/FONT&gt;&lt;FONT size=2&gt; s_HavePrinters = &lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;PrinterSettings&lt;/FONT&gt;&lt;FONT size=2&gt;.InstalledPrinters.Count &amp;gt; 0;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;As fate would have it, this code doesn't work so well when your &lt;STRONG&gt;Print Spooler&lt;/STRONG&gt; service is stopped!&lt;/P&gt;
&lt;P&gt;.NET managed code profilers are designed to show where performace problems may exist in applications by measuring the time taken to enter and exit a method in the code. They could also, however, be leveraged as a powerful potential fault-finding tool. I wouldn't absolutely depend on&amp;nbsp;one for this purpose, but it's nice to have a backup troubleshooting method when my debugger is on the fritz.&lt;/P&gt;&lt;img src="http://mail.simple-talk.com/community/aggbug.aspx?PostID=67949" width="1" height="1"&gt;</description></item><item><title>DOH! It's the DaftOperationHandler</title><link>http://mail.simple-talk.com/community/blogs/brian_donahue/archive/2008/08/05/66352.aspx</link><pubDate>Tue, 05 Aug 2008 16:26:00 GMT</pubDate><guid isPermaLink="false">f46e5dea-70cd-4a69-a7e1-fd07a313bd4d:66352</guid><dc:creator>Brian Donahue</dc:creator><slash:comments>0</slash:comments><comments>http://mail.simple-talk.com/community/blogs/brian_donahue/comments/66352.aspx</comments><wfw:commentRss>http://mail.simple-talk.com/community/blogs/brian_donahue/commentrss.aspx?PostID=66352</wfw:commentRss><description>&lt;P&gt;&amp;nbsp;&amp;nbsp; Probably my least favourite question in the world, professionally anyway, is "Does your software support &amp;lt;choose a technology&amp;gt;". Well, first off, define support. &lt;A href="http://www.dictionary.com/"&gt;Dictionary.com &lt;/A&gt;provides for no less than nineteen definitions for that particular word, and I can probably think of about a dozen more.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp; If&amp;nbsp;my answer to this question is "yes", and when I say "yes", it means that&amp;nbsp;the program has&amp;nbsp;been documented, tried, and thoroughly tested, the fun is yet to begin. When customers ask this question, eight times out of ten it's purely rhetorical, and it's&amp;nbsp;about to&amp;nbsp;slap you in the face with&amp;nbsp;a "well, we tried it, and it doesn't work" reply.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp; For example, we get a phone call about a log shipping problem in our backup application. "Do you support log shipping"?&lt;/P&gt;
&lt;P&gt;"Yes, we do." (It's right there in the manual)&lt;/P&gt;
&lt;P&gt;"Well, it doesn't work!"&lt;/P&gt;
&lt;P&gt;*sigh* "Fine, tell me about the problem."&lt;/P&gt;
&lt;P&gt;"Every&amp;nbsp;five seconds, we do a log backup at our site in Los Angeles, copy&amp;nbsp;the file&amp;nbsp;over a Virtual Private Network over a T1 to La Paz, where it is copied via FTP over a 56Kb modem to Tel Aviv."&lt;/P&gt;
&lt;P&gt;"Uh-huh."&lt;/P&gt;
&lt;P&gt;"The log backups are only 200 megabytes each".&lt;/P&gt;
&lt;P&gt;"Uh. Huh."&lt;/P&gt;
&lt;P&gt;This is why the new frontier of software supportability features should be DOH, or Daft Operation Handlers.&lt;/P&gt;
&lt;P&gt;The first generation of error messages in software told you that something has gone wrong.&lt;/P&gt;
&lt;P&gt;The second generation of error handling messages had told you exactly what went wrong.&lt;/P&gt;
&lt;P&gt;The third generation tell you what to do about the problem.&lt;/P&gt;
&lt;P&gt;DOH is the fourth generation of error handling (4G!), in which you are told that you are about to do something that is more than likely going to result in an error because it defies the immutable laws of physics or would require some sort of time machine to work.&lt;/P&gt;
&lt;P&gt;My DOH provides for four types of daft operations:&lt;/P&gt;&lt;FONT size=2&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;enum&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;DaftType&lt;/P&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;
&lt;P&gt;{&lt;BR&gt;Insane=0x01,&lt;BR&gt;NotVeryBright=0x02,&lt;BR&gt;ExpectTheImpossible=0x04,&lt;BR&gt;HaveLotsOfSpareTime=0x08&lt;BR&gt;} &lt;/FONT&gt;
&lt;P&gt;When the program detects that it is about to be used in a supported, but nevertheless&amp;nbsp;impossible fashion, it should trigger a DaftOperationHandler.&lt;/P&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;delegate&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;void&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;DaftOperationHandler&lt;/FONT&gt;&lt;FONT size=2&gt;(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;object&lt;/FONT&gt;&lt;FONT size=2&gt; o, &lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;DaftOperationArgs&lt;/FONT&gt;&lt;FONT size=2&gt; e);&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;class&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;DaftOperationArgs&lt;/FONT&gt;&lt;FONT size=2&gt; : &lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;EventArgs&lt;BR&gt;&lt;/FONT&gt;&lt;FONT size=2&gt;{&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;public&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;DaftType&lt;/FONT&gt;&lt;FONT size=2&gt; TypeOfDaftness;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;public&lt;/FONT&gt;&lt;FONT size=2&gt; DaftOperationArgs(&lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;DaftType&lt;/FONT&gt;&lt;FONT size=2&gt; e)&lt;BR&gt;{ TypeOfDaftness = e;&lt;BR&gt;}&lt;BR&gt;}&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;The registered DOH should display the appropriate message to the user:&lt;BR&gt;&lt;/P&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;static&lt;/FONT&gt;&lt;FONT size=2&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;void&lt;/FONT&gt;&lt;FONT size=2&gt; f1_DaftStatus(&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;object&lt;/FONT&gt;&lt;FONT size=2&gt; o, &lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;DaftOperationArgs&lt;/FONT&gt;&lt;FONT size=2&gt; e)&lt;/P&gt;
&lt;P&gt;{&lt;/P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;if&lt;/FONT&gt;&lt;FONT size=2&gt; ((e.TypeOfDaftness &amp;amp; &lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;DaftType&lt;/FONT&gt;&lt;FONT size=2&gt;.Insane) == &lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;DaftType&lt;/FONT&gt;&lt;FONT size=2&gt;.Insane)&lt;/P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;MessageBox&lt;/FONT&gt;&lt;FONT size=2&gt;.Show(&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;"Are you out of your mind?"&lt;/FONT&gt;&lt;FONT size=2&gt;, &lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;"Questioning your rationality"&lt;/FONT&gt;&lt;FONT size=2&gt;, &lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;MessageBoxButtons&lt;/FONT&gt;&lt;FONT size=2&gt;.YesNo);&lt;/P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;if&lt;/FONT&gt;&lt;FONT size=2&gt; ((e.TypeOfDaftness &amp;amp; &lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;DaftType&lt;/FONT&gt;&lt;FONT size=2&gt;.ExpectTheImpossible) == &lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;DaftType&lt;/FONT&gt;&lt;FONT size=2&gt;.ExpectTheImpossible)&lt;/P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;MessageBox&lt;/FONT&gt;&lt;FONT size=2&gt;.Show(&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;"You can't get blood out of a stone"&lt;/FONT&gt;&lt;FONT size=2&gt;, &lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;"Think again..."&lt;/FONT&gt;&lt;FONT size=2&gt;);&lt;/P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;if&lt;/FONT&gt;&lt;FONT size=2&gt; ((e.TypeOfDaftness &amp;amp; &lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;DaftType&lt;/FONT&gt;&lt;FONT size=2&gt;.HaveLotsOfSpareTime) == &lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;DaftType&lt;/FONT&gt;&lt;FONT size=2&gt;.HaveLotsOfSpareTime)&lt;/P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;MessageBox&lt;/FONT&gt;&lt;FONT size=2&gt;.Show(&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;"For pete's sake, get a real job!!!"&lt;/FONT&gt;&lt;FONT size=2&gt;, &lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;"Thinking about being a writer?"&lt;/FONT&gt;&lt;FONT size=2&gt;);&lt;/P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;if&lt;/FONT&gt;&lt;FONT size=2&gt; ((e.TypeOfDaftness &amp;amp; &lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;DaftType&lt;/FONT&gt;&lt;FONT size=2&gt;.NotVeryBright) == &lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;DaftType&lt;/FONT&gt;&lt;FONT size=2&gt;.NotVeryBright)&lt;/P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT color=#2b91af size=2&gt;MessageBox&lt;/FONT&gt;&lt;FONT size=2&gt;.Show(&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;"There is a reason why software comes with a manual"&lt;/FONT&gt;&lt;FONT size=2&gt;, &lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;"RTFM warning!"&lt;/FONT&gt;&lt;FONT size=2&gt;);&lt;/P&gt;
&lt;P&gt;}&lt;/P&gt;&lt;/FONT&gt;
&lt;P&gt;Hopefully, implementing DOH! will prevent many unnecessary calls to the support desk and improve the customer experience and make everybody all-round more productive.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://mail.simple-talk.com/community/aggbug.aspx?PostID=66352" width="1" height="1"&gt;</description><enclosure url="http://mail.simple-talk.com/community/blogs/brian_donahue/attachment/66352.ashx" length="34273" type="application/x-zip-compressed" /></item><item><title>Po man's patchworkin'</title><link>http://mail.simple-talk.com/community/blogs/brian_donahue/archive/2008/03/27/45777.aspx</link><pubDate>Thu, 27 Mar 2008 23:03:00 GMT</pubDate><guid isPermaLink="false">f46e5dea-70cd-4a69-a7e1-fd07a313bd4d:45777</guid><dc:creator>Brian Donahue</dc:creator><slash:comments>0</slash:comments><comments>http://mail.simple-talk.com/community/blogs/brian_donahue/comments/45777.aspx</comments><wfw:commentRss>http://mail.simple-talk.com/community/blogs/brian_donahue/commentrss.aspx?PostID=45777</wfw:commentRss><description>&lt;P&gt;If you had come of age before Component Object Model as I have, the concept of COM registration seemed rather odd at first glance. Why is your system limited to exactly one application extension which is forced to be backwards-compatible, when, for years, other operating systems have enjoyed the ability to have many versions of the same shared library and an established probing precedence to find the appropriate library file? This has landed&amp;nbsp;us Windows users in deep doo-doo when we try to upgrade software that uses shared components (so-called DLL Hell).&lt;/P&gt;
&lt;P&gt;Thankfully, the advent of Microsoft .NET had done a lot to solve this problem. Not only can the same dll exist in multiple locations, and a predictable probing behaviour has been established, but we can even override the assembly binding by creating an assembly config file. This feature can be leveraged for an easy way to 'patch' errant software, provided that the new assembly has the same public methods and objects available as the old one.&lt;/P&gt;
&lt;P&gt;I had recently been in a situation where I could put this into practice. Our schema comparison keeps all of its' logic in a shared assembly: &lt;EM&gt;RedGate.SQLCompare.Engine.dll&lt;/EM&gt;. This shared component had been updated to support a certain SQL Server 2005 feature that I won't name, suffice to say that it wouldn't require a change to the User Interface to support it. Because the UI and the Engine were of the same major version, it seemed a perfect time to exercise my assembly binding prowess. Here is the path to dll heaven when you need to upgrade a single dll in a piece of software:&lt;/P&gt;
&lt;P&gt;Step 1: Identify the assembly name of the dll that you want to replace. The assembly name is normally the same as the file name without the extension, but this is not a given. Tools such as .NET Reflector will tell you the assembly name, and if you're really hard-core, you can code up something using Reflection: Assembly.LoadFile(@"c:\file.dll").FullName. When you configure the assemblyIdentity (below) you will need to know the assembly name.&lt;/P&gt;
&lt;P&gt;Step 2: Copy the dll, and any dependent dlls, into a subfolder in the calling application's APPATH. This is very important because .NET will not allow you to bind to an assembly originating from a&amp;nbsp;folder outside of the application's "home" folder, presumably for security reasons. I have created a folder called &lt;EM&gt;SQL Compare Engine 63&lt;/EM&gt; underneath the program's folder for this reason.&lt;/P&gt;
&lt;P&gt;Step 3: Open Notepad and create a file named after the executable that is going to load your dll, appending ".config" to the end of the filename. In my case, the file will be called RedGate.SQLCompare.UI.exe.config. The contents of this file will be in XML, the bindingRedirect element is the magic that allows me to use the new dll in place of the old one.&lt;/P&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;&amp;lt;?&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;xml&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;version&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;1.0&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;encoding&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;utf-8&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;?&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;configuration&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;runtime&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;assemblyBinding&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;xmlns&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;urn:schemas-microsoft-com:asm.v1&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;dependentAssembly&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;assemblyIdentity&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;name&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;RedGate.SQLCompare.Engine&lt;/FONT&gt;&lt;FONT size=2&gt;" &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;publicKeyToken&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;7f465a1c156d4d57&lt;/FONT&gt;&lt;FONT size=2&gt;" &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;culture&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;neutral&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;bindingRedirect &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;oldVersion&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;6.2.1.36&lt;/FONT&gt;&lt;FONT size=2&gt;" &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;newVersion&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;6.3.0.123&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;codeBase&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;version&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;6.3.0.123&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;href&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;file://c:/Program files/red gate/SQL Compare 6/sql compare engine 63/RedGate.SQLCompare.Engine.dll&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;dependentAssembly&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;runtime&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;startup&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;supportedRuntime&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;version&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;v2.0.50727&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;/&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;startup&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;lt;/&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;configuration&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#000000 size=3&gt;You may notice a few things about the contents of this file that I haven't mentioned. First of all, in addition to the elements that identify the assembly that I want to configure, I have added the &lt;EM&gt;codeBase &lt;/EM&gt;directive. This will instruct .NET to look in the &lt;EM&gt;sql compare engine 63&lt;/EM&gt; folder that I had created to hold the new version of the dll because I feel a lot safer&amp;nbsp;not overwriting the shipped SQL Compare dll. I have also added the supportedRuntime tag. This may be important if the application that you were patching was built against the .NET 1.x runtime and the replacement dll was built against 2.0. If the whole shebang loads into the 2.0 runtime, then there shouldn't really be any incompatibilities (with the requisite exceptions, of course!)&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#000000 size=3&gt;An additional complication is introduced if the replacement dll relies on updated dependant dlls. Just because we have redirected the RedGate.SQLCompare.Engine.dll doesn't mean that the runtime will probe the &lt;EM&gt;SQL Compare Engine 63 &lt;/EM&gt;for dependencies. One solution could be to add a probing path inside the assemblyBinding element:&lt;/FONT&gt;&lt;/P&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;probing&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;privatePath&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;c:\program files\red gate\sql compare 6\sql compare Engine 63&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;/&amp;gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#000000 size=3&gt;However, this doesn't seem to work for me and my guess is that it's because codeBase always overrides probing. To solve this problem, I got a list of all dependent assemblies from .NET Reflector for RedGate.SQLCompare.Engine and added the file locations for all dependencies using codeBase to make the complete config file:&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&amp;lt;?&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;xml&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;version&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;1.0&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;encoding&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;utf-8&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;?&amp;gt;&lt;BR&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;configuration&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;runtime&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;assemblyBinding&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;xmlns&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;urn:schemas-microsoft-com:asm.v1&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;dependentAssembly&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;assemblyIdentity&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;name&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;RedGate.SQLCompare.Engine&lt;/FONT&gt;&lt;FONT size=2&gt;" &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;publicKeyToken&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;7f465a1c156d4d57&lt;/FONT&gt;&lt;FONT size=2&gt;" &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;culture&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;neutral&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;bindingRedirect &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;oldVersion&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;6.2.1.36&lt;/FONT&gt;&lt;FONT size=2&gt;" &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;newVersion&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;6.3.0.123&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;codeBase&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;version&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;6.3.0.123&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;href&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;file://c:/Program files/red gate/SQL Compare 6/sql compare engine 63/RedGate.SQLCompare.Engine.dll&lt;/FONT&gt;&lt;FONT size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;dependentAssembly&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;dependentAssembly&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;assemblyIdentity&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;name&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;RedGate.SQL.Shared&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT color=#000000&gt;" &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;publicKeyToken&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;7f465a1c156d4d57&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT color=#000000&gt;" &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;culture&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;neutral&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;codeBase&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;version&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;6.2.1.30&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;href&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;file://c:/Program files/red gate/SQL Compare 6/sql compare engine 63/RedGate.SQL.Shared.dll&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;dependentAssembly&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;dependentAssembly&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;&amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;assemblyIdentity&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;name&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;RedGate.SQLCompare.ASTParser&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT color=#000000&gt;" &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;publicKeyToken&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;7f465a1c156d4d57&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT color=#000000&gt;" &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;culture&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;neutral&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;codeBase&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;version&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;6.3.0.123&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;href&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;file://c:/Program files/red gate/SQL Compare 6/sql compare engine 63/RedGate.SQLCompare.ASTParser.dll&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;dependentAssembly&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;dependentAssembly&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;assemblyIdentity&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;name&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;RedGate.SQLCompare.Rewriter&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT color=#000000&gt;" &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;publicKeyToken&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;7f465a1c156d4d57&lt;/FONT&gt;&lt;FONT size=2&gt;&lt;FONT color=#000000&gt;" &lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;culture&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;neutral&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;codeBase&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;version&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;6.3.0.123&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;href&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;file://c:/Program files/red gate/SQL Compare 6/sql compare engine 63/RedGate.SQLCompare.Rewriter.dll&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; /&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;dependentAssembly&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;/FONT&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&lt;FONT color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;runtime&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;startup&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;supportedRuntime&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt; &lt;/FONT&gt;&lt;FONT color=#ff0000 size=2&gt;version&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;=&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;v2.0.50727&lt;/FONT&gt;&lt;FONT color=#000000 size=2&gt;"&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;/&amp;gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;startup&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;BR&gt;&amp;lt;/&lt;/FONT&gt;&lt;FONT color=#a31515 size=2&gt;configuration&lt;/FONT&gt;&lt;FONT color=#0000ff size=2&gt;&amp;gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#000000&gt;This seems to work a treat! The only drawback is that your new dll may be incompatible with the application because public methods may have been deprecated or some other undesirable behaviour.&lt;/FONT&gt;&lt;/P&gt;&lt;img src="http://mail.simple-talk.com/community/aggbug.aspx?PostID=45777" width="1" height="1"&gt;</description></item><item><title>Optimize Prime</title><link>http://mail.simple-talk.com/community/blogs/brian_donahue/archive/2008/03/26/45737.aspx</link><pubDate>Wed, 26 Mar 2008 23:09:00 GMT</pubDate><guid isPermaLink="false">f46e5dea-70cd-4a69-a7e1-fd07a313bd4d:45737</guid><dc:creator>Brian Donahue</dc:creator><slash:comments>0</slash:comments><comments>http://mail.simple-talk.com/community/blogs/brian_donahue/comments/45737.aspx</comments><wfw:commentRss>http://mail.simple-talk.com/community/blogs/brian_donahue/commentrss.aspx?PostID=45737</wfw:commentRss><description>&lt;P&gt;Ever since the dark ages of programming, certain tricks have been implemented in code compilers to eke out the maximum performance from the compiled code, the most important of which is inlining. Put simply, inlining is the process by which a child method is inserted into the parent method in its' entirety. For larger methods, this would make about as much sense as a chocolate teapot because the program would suffer from serious bloating if the same method had been invoked many times from different places. For smaller methods, however, this makes perfect sense and offers a huge performance boost, especially when methods whose compiled code is 32 bytes or less, because absolutely no space is wasted considering the method pointer occupies 32 or 64 bits anyway and performance is boosted because the CPU doesn't need to "jump" across to different memory locations as often.&lt;/P&gt;
&lt;P&gt;The same optimizations are also available in the Microsoft .NET Runtime's&amp;nbsp;Just-In-Time compiler, although this is done more or less on the fly.&lt;/P&gt;
&lt;P&gt;With an eye towards performance analysis tools such as code profilers or coverage tools, this has some implications in the results because methods that have been inlined effectively cease to exist, so many of these tools disable inlining and other optimizations to save the end-user from confusing and nonsensical results. The disadvantage of this approach is that your code profiler doesn't exactly run your code in the same way as it would run in the "real world" due to the absence of JIT optimizations. Thankfully, &lt;A class="" href="http://www.red-gate.com/products/ants_profiler/index.htm?utm_source=blogs&amp;amp;utm_medium=weblink&amp;amp;utm_content=inlining&amp;amp;utm_campaign=antsprofiler" target=_blank&gt;ANTS Profiler&lt;/A&gt; allows you to profile inlined code using its fast mode profiling, and provides visual cues as to which methods had been inlined and which source code had been inlined into parent methods.&lt;/P&gt;
&lt;P&gt;I've made a brief 5-minute presentation demonstrating the speed increase effected by inlining, and the way in which ANTS Profiler will show information related to inlined methods.&lt;/P&gt;
&lt;P&gt;
&lt;a href="http://www.red-gate.com/products/ants_profiler/technical_papers/inlining_video/Brian_Inlining_Blog_640x480_skin.swf"&gt;Demonstration of inlining using ANTS Profiler&lt;/a&gt;&lt;/P&gt;&lt;img src="http://mail.simple-talk.com/community/aggbug.aspx?PostID=45737" width="1" height="1"&gt;</description></item><item><title>Exceptionally expensive </title><link>http://mail.simple-talk.com/community/blogs/brian_donahue/archive/2008/03/26/45724.aspx</link><pubDate>Wed, 26 Mar 2008 18:09:00 GMT</pubDate><guid isPermaLink="false">f46e5dea-70cd-4a69-a7e1-fd07a313bd4d:45724</guid><dc:creator>Brian Donahue</dc:creator><slash:comments>1</slash:comments><comments>http://mail.simple-talk.com/community/blogs/brian_donahue/comments/45724.aspx</comments><wfw:commentRss>http://mail.simple-talk.com/community/blogs/brian_donahue/commentrss.aspx?PostID=45724</wfw:commentRss><description>&lt;p&gt;Many years ago, when switching from programming in plain old C to the managed environment of .NET Framework, I had discovered exceptions.&amp;nbsp; The idea was not completely new to me because I'd already seen try/catch blocks in JavaScript and I liked that method of error handling a lot, especially when compared to the ON ERROR GOTO handling that VBScript uses, which is why I prefer using JScript whenever I can, although sometimes in the scripting environment you begrudgingly have to use VBS.&lt;/p&gt;
&lt;p&gt;.NET had significantly enhanced the try/catch block by allowing the programmer to extend the exceptions by adding their own properties and methods to them. In addition, the exceptions can be typed, so if you are interested in one type of exception, say a file can't be opened, but not in another type of exception, for instance an out-of-memory condition, you can have that sort of granularity.&lt;/p&gt;
&lt;p&gt;So I thought, great!, I will use exceptions&amp;nbsp;everywhere. I will use them&amp;nbsp;all over the place, not only to handle catastrophic and unusual errors, but also&amp;nbsp;anywhere&amp;nbsp;an object could not be created or a value exceeded a certain threshold&amp;nbsp;or any one of 1001 completely common situations where something happened that needed some conditional branching to happen. This, as I found out, could have some particularly nasty performance implications!&lt;/p&gt;
&lt;p&gt;Here is a simple example to demonstrate just how much slower throwing exceptions can make your .NET Program:&lt;/p&gt;&lt;font color="#0000ff" size="2"&gt;using&lt;/font&gt;&lt;font size="2"&gt; System;&lt;br&gt;&lt;font color="#0000ff" size="2"&gt;using&lt;/font&gt;&lt;font size="2"&gt; System.Collections.Generic;&lt;br&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;using&lt;/font&gt;&lt;font size="2"&gt; System.Collections;&lt;br&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;using&lt;/font&gt;&lt;font size="2"&gt; System.Text;&lt;br&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;namespace&lt;/font&gt;&lt;font size="2"&gt; ExceptionTest&lt;br&gt;{&lt;br&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;class&lt;/font&gt;&lt;font size="2"&gt; Program&lt;br&gt;{&lt;br&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;static&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;void&lt;/font&gt;&lt;font size="2"&gt; Main(&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;string&lt;/font&gt;&lt;font size="2"&gt;[] args)&lt;br&gt;{&lt;br&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;for&lt;/font&gt;&lt;font size="2"&gt; (&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;int&lt;/font&gt;&lt;font size="2"&gt; i = 0; i &amp;lt; 1000000; i++)&lt;br&gt;{&lt;br&gt;HandleViaException();&lt;br&gt;HandleViaCondition();&lt;br&gt;}&lt;br&gt;}&lt;br&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;static&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;void&lt;/font&gt;&lt;font size="2"&gt; HandleViaException()&lt;br&gt;{&lt;br&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;string&lt;/font&gt;&lt;font size="2"&gt; s = &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;null&lt;/font&gt;&lt;font size="2"&gt;;&lt;br&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;try&lt;/font&gt;&lt;font size="2"&gt;{&lt;br&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;string&lt;/font&gt;&lt;font size="2"&gt; ss = s.Substring(0, 2);&lt;br&gt;}&lt;br&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;catch&lt;/font&gt;&lt;font size="2"&gt; (System.NullReferenceException)&lt;br&gt;{&lt;br&gt;}&lt;br&gt;}&lt;br&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;static&lt;/font&gt;&lt;font size="2"&gt; &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;void&lt;/font&gt;&lt;font size="2"&gt; HandleViaCondition()&lt;br&gt;{&lt;br&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;string&lt;/font&gt;&lt;font size="2"&gt; s = &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;null&lt;/font&gt;&lt;font size="2"&gt;;&lt;br&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;if&lt;/font&gt;&lt;font size="2"&gt; (s != &lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;null&lt;/font&gt;&lt;font size="2"&gt;)&lt;br&gt;{&lt;br&gt;&lt;/font&gt;&lt;font color="#0000ff" size="2"&gt;string&lt;/font&gt;&lt;font size="2"&gt; ss = s.Substring(0, 2);&lt;br&gt;}&lt;br&gt;}&lt;br&gt;}&lt;br&gt;&lt;/font&gt;
&lt;/font&gt;&lt;p&gt;&lt;font size="2"&gt;In the HandleViaException method, I attempt to execute a method on a string object set to a null value, which will cause a NullReferenceException and make the exception handling code run. In the HandleViaCondition method, I simply check the value of the string, and if it is null, I&amp;nbsp;do not run the Substring method&amp;nbsp;on the string. Although these methods perform the same function, there should be a noticable performance difference when the methods are both run a million times. I had tested this using the &lt;strong&gt;&lt;a class="" href="http://www.red-gate.com/products/ants_profiler/index.htm?utm_source=blogs&amp;amp;utm_medium=weblink&amp;amp;utm_content=inlining&amp;amp;utm_campaign=antsprofiler" target="_blank"&gt;ANTS Profiler&lt;/a&gt;&lt;/strong&gt; code profiling tool with the following results:&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font color="#0000ff" size="2"&gt;HandleViaCondition -- Hit Count: 1000000 Total Time: 0.571 seconds&lt;/font&gt;&lt;br&gt;&lt;font color="#0000ff" size="2"&gt;HandleViaException -- HitCount: 1000000 Total Time: 50.4 seconds&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;Using Exceptions to trap a null condition is roughly a hundred times slower than simply checking to see if the string is null. I knew that using exceptions would incur a performance penalty but mama mia that is slow! I've taken a program that should return in less than a second and turned it into an excuse to hang out at the water cooler and gossip for awhile.&lt;/p&gt;
&lt;p&gt;Could I make this any worse? Oh, yes&amp;nbsp;I can, by attaching a debugger (cdb.exe) to&amp;nbsp;the program&amp;nbsp;as well!&lt;/p&gt;
&lt;p&gt;&lt;font color="#0000ff" size="2"&gt;HandleViaCondition -- Hit Count: 1000000 Total Time: 0.554 seconds&lt;/font&gt;&lt;br&gt;&lt;font color="#0000ff" size="2"&gt;HandleViaException -- HitCount: 1000000 Total Time: 54.3 seconds&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;Well, that's not too much worse, but then again, cdb is pretty lightweight. Let's attach&amp;nbsp;to it using Visual Studio 2005's debugger:&lt;/p&gt;
&lt;p&gt;&lt;font color="#0000ff" size="2"&gt;HandleViaCondition -- Hit Count: 1000000 Total Time: 0.678 seconds&lt;/font&gt;&lt;br&gt;&lt;font color="#0000ff" size="2"&gt;HandleViaException -- HitCount: 1000000 Total Time:&amp;nbsp;1936 seconds&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;See, now I have a convenient excuse to go down to the cantine and get a donut. Mmmmmm, donuts.&lt;/p&gt;
&lt;p&gt;The Visual Studio debugger is particularly invasive when it encounters an exception in the code that you're debugging. You expect a debugger to pause your code when an exception is encountered, grab information about the stack and heap, and allow your code to continue on. With CDB.exe, the overhead is pretty minimal, but Visual Studio 2005 seems to pause&amp;nbsp;my running code for much longer.&lt;/p&gt;
&lt;p&gt;The end result is that if this code was part of a real-world application, I would probably spend all day trying to debug it, and I frankly have better things to do, like eat bacon sandwiches. On toast. With some of that nice Brown Sauce they have over here.&lt;/p&gt;
&lt;p&gt;From now on, I&amp;nbsp;use exceptions in my code very sparingly, and try to avoid using them&amp;nbsp;in code loops altogether because the cumulative effect of wasting a few milliseconds in a tight code loop can turn an application into sludge if you're not careful!&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="/community/blogs/brian_donahue/attachment/45724.ashx" height="755" width="600"&gt;&lt;img src="http://mail.simple-talk.com/community/aggbug.aspx?PostID=45724" width="1" height="1"&gt;</description><enclosure url="http://mail.simple-talk.com/community/blogs/brian_donahue/attachment/45724.ashx" length="82087" type="image/x-png" /></item><item><title>Need to loosen my bindings</title><link>http://mail.simple-talk.com/community/blogs/brian_donahue/archive/2007/11/13/39598.aspx</link><pubDate>Tue, 13 Nov 2007 23:29:00 GMT</pubDate><guid isPermaLink="false">f46e5dea-70cd-4a69-a7e1-fd07a313bd4d:39598</guid><dc:creator>Brian Donahue</dc:creator><slash:comments>0</slash:comments><comments>http://mail.simple-talk.com/community/blogs/brian_donahue/comments/39598.aspx</comments><wfw:commentRss>http://mail.simple-talk.com/community/blogs/brian_donahue/commentrss.aspx?PostID=39598</wfw:commentRss><description>&lt;P&gt;Microsoft .NET's runtime provides an execution engine for Just-In-Time compiled code, but it also has the&amp;nbsp;clandestine capability to pre-compile code and cache it on disk. This at first seems a little odd, since the point of environments like .NET Framework and Java are supposedly designed to offer machine-independent, 'virtual' code. I suppose that .NET's native image support was introduced to solve some performance pitfalls of using Intermediate Language code, which needs to be compiled dynamically as it runs. Native Images would not suffer from this performance loss, since the compilation has been done in advance.&lt;/P&gt;
&lt;P&gt;Native images can become invalid, however, and cause some very strange errors. In one case, one of our programs was crashing at random points in the usage, and in most cases, the program would actually fail to even start, throwing a scary-looking invalid program exception and offering the chance to debug, which presents&amp;nbsp;some users with&amp;nbsp;&amp;nbsp;and obtuse error message&amp;nbsp;and if a debugger is installed,&amp;nbsp;a yellow arrow pointing at a machine instruction that nobody who has started programming a computer after 1987 really understands.&lt;/P&gt;
&lt;P&gt;Theoretically, of course, invalid native images should not occur. But if we understand how these native images are created, it's possible to see some holes in Microsoft's design.&lt;/P&gt;
&lt;P&gt;For starters, native images are typically created when a program is installed, and the process appears to be automatic -- Windows Installer knows that .NET assemblies are contained in an MSI by some hocus-pocus and ngen.exe is invoked to create a cache of native images for all assemblies in the MSI.&lt;/P&gt;
&lt;P&gt;If the native images are never modified, there is a possibility that they could become invalid, if, say the .NET Framework environment had changed. If the Framework is patched or re-installed, there could be outdated reference in the native image that would cause the program to crash where it would not if it were properly loaded and JITted in near-real time. Microsoft have thought about this and designed the Framework to examine the .NET Runtime for changes that would cause a problem. If, for instance, mscorwks.dll, mscoree.dll, or other runtime libraries have changed, this will force a new native image generation when a cached assembly tries to load. Likewise, any changes to dependent assemblies, even if they have cached native images, will force a 'cascading' recompilation of native images for all dependent assemblies.&lt;/P&gt;
&lt;P&gt;It sounds like Microsoft have thought of everything, but, alas, no, there are situations where an invalid native image is sitting on the hard disk, waiting to strike. Microsoft know that when they apply changes to the .NET Framework, such as the updates that may be distributed by Windows Update, that the runtime's native image cache needs to be updated. So these updates run NGEN.exe /update to refresh the native images so that they are no longer invalid. Sounds all well and good -- but there are some situations where multiple automatic updates have resulted in invalid native images that the runtime thinks are still valid, probably because the system really requires a reboot after running the first .NET update, but Automatic Updates silently suppresses it and applies a second .NET update.&lt;/P&gt;
&lt;P&gt;If you come across strange behaviour in a managed .NET program, it may be useful to rule out the native image as the cause before accusing your program's vendor of releasing buggy code! It is possible to determine if the program you are running is the JITted version, or a native image, by using our old friend, the &lt;A href="http://msdn2.microsoft.com/en-us/library/Aa309346(VS.71).aspx"&gt;Fusion Log Viewer&lt;/A&gt;. Setting this tool up as described in the previous link will create a log entry any time a .NET assembly is loaded by your program. Because Fusion Log Viewer can discriminate between bindings to native assemblies and ones that are purely Intermediate Language, it's plain to see whether the assemblies are being loaded from cache or compiled dynamically by mscorjit.dll.&lt;/P&gt;
&lt;P&gt;If the errant program is loading lots of native-image assemblies, running &lt;STRONG&gt;%systemroot%\Microsoft.net\framework\v2.0.50727\NGEN.exe /update&lt;/STRONG&gt; may just put your program, and possibly many others, back in working order.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;img src="http://mail.simple-talk.com/community/aggbug.aspx?PostID=39598" width="1" height="1"&gt;</description></item><item><title>Using the kill to cure</title><link>http://mail.simple-talk.com/community/blogs/brian_donahue/archive/2007/10/14/38305.aspx</link><pubDate>Sun, 14 Oct 2007 15:48:00 GMT</pubDate><guid isPermaLink="false">f46e5dea-70cd-4a69-a7e1-fd07a313bd4d:38305</guid><dc:creator>Brian Donahue</dc:creator><slash:comments>3</slash:comments><comments>http://mail.simple-talk.com/community/blogs/brian_donahue/comments/38305.aspx</comments><wfw:commentRss>http://mail.simple-talk.com/community/blogs/brian_donahue/commentrss.aspx?PostID=38305</wfw:commentRss><description>&lt;P&gt;I was watching a medical drama the other day, you probably know the one, where the diagnostician darn near kills the patient with bizarre tests in trying to figure out his illness, given a strangely conflicting set of symptoms. I've come across some similar situations with my inorganic patients recently which forced me to step back and look at the whole patient rather than the symptoms presented.&lt;/P&gt;
&lt;P&gt;The &lt;A href="http://en.wikipedia.org/wiki/Code_profiler#Use_of_profilers"&gt;code profiling&amp;nbsp;&lt;/A&gt;tool that I provide support for&amp;nbsp;basically works by loading one of our&amp;nbsp;DLLs into the process being profiled, and&amp;nbsp;there is a possibility&amp;nbsp;for the process to crash or hang with our&amp;nbsp;DLL hooked in when it runs perfectly fine without it. Previously, my focus was strictly on finding bugs in our DLL, but&amp;nbsp;I have come to believe that this is a pretty narrow-minded approach.&lt;/P&gt;
&lt;P&gt;Everybody over age five has heard of the proverbial camel with the lumbar malady upon which a straw too many had been loaded, causing the camel to exhibit a lack of structural integrity. Well, that's how I would word it in my bug report because I'm a stickler for the specifics.&lt;/P&gt;
&lt;P&gt;The metaphor is a good one, though. A programmer will notice poor performance or memory usage in his application and try to find the problem using our code profiler to gather information about slow methods or poor memory allocation, so a 'sick' application is going to have to carry the additional strain of&amp;nbsp;loading our dll and all of its' requirements of memory and processing time along with it. It doesn't take a master engineer to realize that this might fail for more basic reasons than a bug in our code.&lt;/P&gt;
&lt;P&gt;This is similar to a medical case in the respect that the patient needs to be fit enough to survive a procedure that may cure the underlying problem. If a patient needs an angioplasty and presents to surgery with nervous problems, the nervous system would need to be stabilized first so he isn't flopping around on the operating table like a fish out of water while surgeons try to fix a delicate artery wall.&lt;/P&gt;
&lt;P&gt;I'd like to say that our code profiler is the tool to help cure to all performance problems, but sometimes other diagnostic tools need to be employed to point at the serious problems first so that the code profiler can be used to find inefficient code.&lt;/P&gt;
&lt;P&gt;In one instance, a case came to my attention where a program appeared to hang while being profiled. Sure, profiling introduces some overhead, but this was extreme (the spash screen stayed up for an hour!). I'd suggested using performance counters, specifically the &lt;STRONG&gt;.NET CLR Memory-&amp;gt;% Time spent in GC&lt;/STRONG&gt; while profiling, and found that the application was spending 90% of its' processing time just cleaning up objects in its' own memory! Without profiling, this went down to a 'respectable' 80%. This application was in too bad a shape to be profiled because it had so many objects containing self-references. Simply adding more data to the application could reproduce the hang even without profiler, so this patient was clearly running out of time.&lt;/P&gt;
&lt;P&gt;In rare cases, it's time to wield computing's least understood tool: the debugger. But first we will need a crash or hang dump from the customer produced using adplus.vbs from the &lt;A href="http://www.microsoft.com/whdc/devtools/debugging/default.mspx"&gt;Windows Debugging Tools &lt;/A&gt;suite. This produces a big, fat file containing the memory of the application, including the .NET runtime, so it's seldom to have a customer who is willing to upload a 50MB file to us.&amp;nbsp;I can use windbg to analyze what happened at the time of failure. It's a dark art, but can reveal interesting information about the application. &lt;A href="http://blogs.msdn.com/tess/"&gt;This MSDN blog&lt;/A&gt; is probably the most useful resource I've found on how to use the Windows Debugger.&lt;/P&gt;
&lt;P&gt;Another common remark from customers is that although the code profiler shows minimal memory usage by their applications, the total space as reported by Task Manager is monumentally huge. In this case, you may not need to worry about optimizing your code, which is what a code profiler helps to do, but rather you want to examine the process memory space and have a look at how many modules are loaded into it. Then it's a question of perhaps ridding yourself of unused references or using alternative components in your code that are smaller. A simple, free tool for doing this is &lt;A href="http://labs.red-gate.com/index.php/Red_Gate_Memory_Tracker"&gt;Red Gate Memory Tracker&lt;/A&gt;, which will give you a graphical representation of what is loaded into memory. Cleaning up this memory first may give the code profiler a bit more 'elbow room' if the problem is a shortage of memory.&lt;/P&gt;
&lt;P&gt;Once the critical problems in an application are sorted out, then the task of enhancing the application performance is much easier!&lt;/P&gt;&lt;img src="http://mail.simple-talk.com/community/aggbug.aspx?PostID=38305" width="1" height="1"&gt;</description></item><item><title>One ringy dingy...</title><link>http://mail.simple-talk.com/community/blogs/brian_donahue/archive/2007/10/06/37952.aspx</link><pubDate>Sun, 07 Oct 2007 04:00:00 GMT</pubDate><guid isPermaLink="false">f46e5dea-70cd-4a69-a7e1-fd07a313bd4d:37952</guid><dc:creator>Brian Donahue</dc:creator><slash:comments>2</slash:comments><comments>http://mail.simple-talk.com/community/blogs/brian_donahue/comments/37952.aspx</comments><wfw:commentRss>http://mail.simple-talk.com/community/blogs/brian_donahue/commentrss.aspx?PostID=37952</wfw:commentRss><description>&lt;P&gt;I should really count my blessings. Technical Support, to some companies, means a bank of Rhesus monkeys picking up telephones and telling customers to 'turn it off and then on again'. Previous to this&amp;nbsp;prevalent statement, 'is it plugged in?' was de rigeur until customers found this too insulting to their intelligence -- particularly the ones who did actually forget to plug it in. The point is that a lot of technical support managers live and die by the stats: ring time, hold time, and wrap-up.&lt;/P&gt;
&lt;P&gt;It's almost conventional wisdom down in the trenches that this type of management is self-defeating and results in poor service. For instance, if you penalize staff for breaking your arbitrary ten-minute wrap-time, the support representatives are going to dole out bogus information and the customer will inevitably have to call back! But that's just fine with management, because there will be one more call to add to thei