<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>Setup</title>
        <link>http://geekswithblogs.net/Vagmi.Mudumbai/category/1095.aspx</link>
        <description>Everything about Windows Installer, InstallShield and WIX</description>
        <language>hi-IN</language>
        <copyright>Vagmi Mudumbai</copyright>
        <managingEditor>jjulian@geekswithblogs.net</managingEditor>
        <generator>Subtext Version 0.0.0.0</generator>
        <item>
            <title>Uninstall a component during minor upgrade</title>
            <link>http://geekswithblogs.net/Vagmi.Mudumbai/archive/2006/06/11/81426.aspx</link>
            <description>It is bound to happen. You will have a developer come up to you one day
and say, "Remember the DLL file that we shipped in the previous
release, we have consolidated its functionality into the core library.
We need to remove that library in the latest release." You as a Windows
Installer developer would then be frustrated after finding out that you
cannot remove components during a minor upgrade and you will have to
manage with all the ugliness of a major upgrade. &amp;nbsp;I will write
about the ugliness of a major upgrade in some other blog.&lt;br&gt;
&lt;br&gt;
So if you really have to remove the DLL, you need not have to go
through the trouble of major upgrade. We can actually uninstall
components during a minor upgrade. But the catch is that you should not
remove the component from the existing MSI.&amp;nbsp;My colleague Kajal
Biswas calls this process as "Puncturing the component". Let me detail
the process of puncturing the component.&lt;br&gt;
&lt;ol&gt;
  &lt;li&gt;Consider the component abc.dll which has to be
removed.&amp;nbsp;&lt;/li&gt;
  &lt;li&gt;Collect the Registry, CLSID and the COM information if you
have
dynamically acquired them, you will have to fill them in manually
later. This is usually the reason why I do not use COM Extract at
Build. I usually use 'Extract COM Information' feature of InstallShield
DevStudio. This would ensure that I can find out the exact registry
entries and COM Settings. &amp;nbsp;If you had used the WiX Toolset, it
is
pretty straight forward. You will just have to go to the next step and
you can ignore this completely.&lt;/li&gt;
  &lt;li&gt;Replace abc.dll file with a zero byte&amp;nbsp;file with
the same name.&lt;/li&gt;
  &lt;li&gt;Set the transitive bit of the component. If you are using
InstallShield DevStudio, simply set the 'Reevaluate Condition' field in
the component property to 'Yes'.&amp;nbsp;&lt;/li&gt;
  &lt;li&gt;Replace any existing condition on the component with a
condition
that evaluates to false. As a habit, I and my colleagues enter the
paradoxical '1=0' as the component condition. You can also enter
something meaningful like 'GoToHell=666' or something like that.&lt;/li&gt;
&lt;/ol&gt;
During a minor upgrade, if the feature associated with the component is
reinstalled, the trasitive bit with also force the state of the
component to be reevaluated. And since the component is present and the
condition is false, the component will be uninstalled during a minor
upgrade. It is hack. But it works.
&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=81426"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=81426" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/Vagmi.Mudumbai/aggbug/81426.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Vagmi Mudumbai</dc:creator>
            <guid>http://geekswithblogs.net/Vagmi.Mudumbai/archive/2006/06/11/81426.aspx</guid>
            <pubDate>Sun, 11 Jun 2006 11:42:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/Vagmi.Mudumbai/comments/81426.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/Vagmi.Mudumbai/archive/2006/06/11/81426.aspx#feedback</comments>
            <slash:comments>3</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/Vagmi.Mudumbai/comments/commentRss/81426.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/Vagmi.Mudumbai/services/trackbacks/81426.aspx</trackback:ping>
        </item>
        <item>
            <title>The transitive bit gotcha!</title>
            <link>http://geekswithblogs.net/Vagmi.Mudumbai/archive/2006/04/02/74061.aspx</link>
            <description>&lt;p&gt;
Windows Installer's &lt;a href="http://msdn.microsoft.com/library/en-us/msi/setup/component_table.asp?frame=true"&gt;transitive bit&lt;/a&gt; is a really cool thing. It allows you to author your components in such a way that it would install if component's condition is true and uninstall if it is false even during upgrades. Well almost. Refer the &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/using_transitive_components.asp"&gt;documentation&lt;/a&gt; for more information. So this can be used to get rid of pesky components that you need to uninstall during a minor upgrade. Now we thought this stuff was really neat and applied it to all the components. We had our justifications that this setup will always be done by admins and will always be per machine. None of the components wrote anything off to HKEY_CURRENT_USER and we were pretty much safe in assuming that it would not be the case in the future either. So we turned on the transitive bit for all our components. The software behaved exceptionally well. The maintenance was driven via a external wrapper which always passed the REINSTALL parameter and hence everything worked very well.
&lt;/p&gt;
&lt;p&gt;
This allowed our MSI to behave as a state machine. You could simply throw in a bunch of properties and set its state and it would just install the ones that are required. This basically solves the problem of setup types and you do not have to write custom actions to set the feature request states.
&lt;/p&gt;
&lt;p&gt;
We had tested most of the scenarios on different operating systems and it seemed to function just fine. We had it going through the last round of validation when we got a call from one of the landscape administrators that the product had uninstalled itself. Windows Installer had triggered a repair after the application of a hotfix by one of the developers and had completely uninstalled the application. The reason being that the Windows Installer repair operation also re-evaluates the component conditions and decides that they should not exist on the machine. The problem rested in the fact that even though we did persist the properties to be retrieved later, but that was entirely upto the bootstrapper to do it as the bootstrapper was the single entity that would do all the MSI related maintenance activities. So when the MSI repair started, which of course is as good as a quick reinstall, it ran through the entire InstallExecuteSequence table and found that most of the components were not supposed to be on the machine and had them removed. The solution was fairly simple. We had to persist all the properties and its values in the registry and we had to author AppSearch entries for all the properties and do a sort of quick check for the settings and swap the values with the actual ones during such a repair operation.
&lt;p&gt;
&lt;p&gt;
So if you plan to use the MSI transitive bit for your components, be very careful. You have been warned.
&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=74061"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=74061" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/Vagmi.Mudumbai/aggbug/74061.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Vagmi Mudumbai</dc:creator>
            <guid>http://geekswithblogs.net/Vagmi.Mudumbai/archive/2006/04/02/74061.aspx</guid>
            <pubDate>Sun, 02 Apr 2006 11:09:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/Vagmi.Mudumbai/comments/74061.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/Vagmi.Mudumbai/archive/2006/04/02/74061.aspx#feedback</comments>
            <slash:comments>1</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/Vagmi.Mudumbai/comments/commentRss/74061.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/Vagmi.Mudumbai/services/trackbacks/74061.aspx</trackback:ping>
        </item>
        <item>
            <title>Multi Platform versus Cross Platform</title>
            <link>http://geekswithblogs.net/Vagmi.Mudumbai/archive/2005/10/07/56307.aspx</link>
            <description>&lt;p&gt;
I have lately been pondering over methods to deploy cross platform
products. I investigated certain options like 
&lt;a href="http://www.installshield.com/products/installshield/premier/universal.asp"&gt;
InstallShield's Universal Project&lt;/a&gt; and 
&lt;a href="http://zerog.com/installanywhere-create-deploy-java-multiplatform-installers.html"&gt;
ZeroG's InstallAnywhere&lt;/a&gt;. 
But to tell the truth, it goes against the philosophy of installation. 
They rely on the presence of the right version of JRE. Some installations 
also package the native versions of JRE along with the installation 
package. This is quite an overhead. Other products use their custom 
homegrown installers. As most of the setup developers and administrators 
know, homegrown installers are a disaster waiting to happen. A good
installation technology should do the following.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Installation - This is the easy part.

&lt;li&gt;Rollback in case of failure
&lt;li&gt;Support for dependency and conflict resolution.
&lt;li&gt;Support for transactional install/uninstall operations. This is
very important for the integrity of the system.
&lt;li&gt;Support for upgrades.
&lt;li&gt;Heal installed applications.
&lt;/ul&gt;

&lt;p&gt;Creating a custom installation technology with all these features is
difficult if not impossible. Also it is an investment that is not
required when you can reuse the wheel. Each of the operating systems
or the platform targeted have a native installation technology which
support all of the above points in some way or the other. Most of
these cross platform applications are deployed on Windows, Linux or
Solaris. Windows has the Windows Installer a.k.a MSI package format to
keep an inventory of software that is installed in an extremely
fine granular level. Linux has 
&lt;a href="http://www.rpm.org"&gt;
RPM &lt;/a&gt; and &lt;a href="http://www.debian.org/doc/manuals/distribute-deb/distribute-deb.html"&gt;DEB&lt;/a&gt; 
formats which deal with
packages at a more coarse scale than Windows Installer but have
excellent dependency and conflict resolution. Solaris has its native
&lt;a href="http://docs.sun.com/app/docs/doc/817-0406"&gt;
PKG&lt;/a&gt; format to install packages.


&lt;p&gt;So instead of a cross-platform installation program, we could have
a cross platform tool to create multiple installation packages for multiple
platforms. One of the biggest problems working in this direction would
be that the setup engineer should have a knowledge of all the
platforms that he is packing the application for. This is usually not a
easy job. For instance, I could handle Windows MSI and Linux's  RPM &amp;amp; DEB files
but would be a completely lost on a Solaris platform.

&lt;p&gt;The biggest challenge would also be the fact that the customization
scripts and custom actions would need to be coded by the setup
engineer for each platform or package format. But this is a small 
price to pay for the amount of flexibility that can be achieved. The 
software deployment becomes a breeze and would significantly lower the 
(holy grail of three letter acronyms) TCO.&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=56307"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=56307" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/Vagmi.Mudumbai/aggbug/56307.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Vagmi Mudumbai</dc:creator>
            <guid>http://geekswithblogs.net/Vagmi.Mudumbai/archive/2005/10/07/56307.aspx</guid>
            <pubDate>Fri, 07 Oct 2005 20:22:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/Vagmi.Mudumbai/comments/56307.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/Vagmi.Mudumbai/archive/2005/10/07/56307.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/Vagmi.Mudumbai/comments/commentRss/56307.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/Vagmi.Mudumbai/services/trackbacks/56307.aspx</trackback:ping>
        </item>
        <item>
            <title>Anders Helsberg + Whiteboard + C# = really cool</title>
            <link>http://geekswithblogs.net/Vagmi.Mudumbai/archive/2005/04/27/38495.aspx</link>
            <description>&lt;!-- Converted from text/plain format --&gt;&amp;nbsp;&lt;FONT face=Verdana size=2&gt;While I was browsing the MSDN, I came across this very &lt;/FONT&gt;&lt;A href="http://msdn.microsoft.com/msdntv/episode.aspx?xml=episodes/en/20040624csharpah/manifest.xml"&gt;&lt;FONT face=Verdana size=2&gt;interesting video&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Verdana size=2&gt; which features &lt;/FONT&gt;&lt;A href="http://en.wikipedia.org/wiki/Anders_Hejlsberg"&gt;&lt;FONT face=Verdana size=2&gt;Anders Helsberg&lt;/FONT&gt;&lt;/A&gt;&lt;FONT face=Verdana&gt;&lt;FONT size=2&gt; and his skills with the whiteboard. I really wish&amp;nbsp;&lt;SPAN class=476013103-27042005&gt;that &lt;/SPAN&gt;he&amp;nbsp;&lt;SPAN class=476013103-27042005&gt;teach&lt;/SPAN&gt; me programming.&lt;SPAN class=476013103-27042005&gt; A must see for every C# programmer.&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=38495"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=38495" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/Vagmi.Mudumbai/aggbug/38495.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Vagmi Mudumbai</dc:creator>
            <guid>http://geekswithblogs.net/Vagmi.Mudumbai/archive/2005/04/27/38495.aspx</guid>
            <pubDate>Wed, 27 Apr 2005 14:36:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/Vagmi.Mudumbai/comments/38495.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/Vagmi.Mudumbai/archive/2005/04/27/38495.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/Vagmi.Mudumbai/comments/commentRss/38495.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/Vagmi.Mudumbai/services/trackbacks/38495.aspx</trackback:ping>
        </item>
        <item>
            <title>Writing managed code custom actions</title>
            <link>http://geekswithblogs.net/Vagmi.Mudumbai/archive/2005/03/28/27473.aspx</link>
            <description>&lt;DIV&gt;&lt;FONT face=Verdana size=2&gt;&lt;SPAN class=403183203-28032005&gt;With the new .NET framework API providing such wonderful functionality, everybody is programming in C# or VB.NET&amp;nbsp;except setup developers. There was quite some commotion in the WIX users list on writing managed custom actions. It was finally decided that it is generally harmful to write managed code custom actions as they would&amp;nbsp;depend on .NET Framework and having dependencies for setup is plain bad design. But IMHO, we can use managed code custom actions if we are 100% sure that it would be present on the target platform or if it is a prerequisite and a part of your &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/launchconditions_action.asp"&gt;LaunchConditions&lt;/A&gt;.&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT face=Verdana size=2&gt;&lt;SPAN class=403183203-28032005&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT size=2&gt;&lt;FONT face=Verdana&gt;Writing managed code custom actions can be tricky.&amp;nbsp;&lt;SPAN class=403183203-28032005&gt;The easiest way is to &lt;/SPAN&gt;implement the &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemconfigurationinstallinstallerclasstopic.asp"&gt;System.Configuration.Install.Installer&lt;/A&gt; class. This Installer class has four methods which can be executed during the MSI thread.&amp;nbsp;&lt;SPAN class=403183203-28032005&gt;The Installer class was only meant for developers to do some dirty stuff. But it is far from perfect to be used as a part of the MSI thread. Some of my strong reasons for not using the Installer class&amp;nbsp;are as below.&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/DIV&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;FONT face=Verdana size=2&gt;&lt;SPAN class=403183203-28032005&gt;&lt;A href="http://installneo.blogspot.com/2004/09/installing-windows-services-created.html"&gt;InstallUtilLib.DLL&lt;/A&gt; is not completely silent. It still pops up an ugly message box with it fails.&lt;/SPAN&gt;&lt;/FONT&gt; 
&lt;LI&gt;&lt;FONT face=Verdana size=2&gt;&lt;SPAN class=403183203-28032005&gt;The methods do not have access to the MSI thread. So&amp;nbsp;we would not be able to use properties or write to the MSI log file.&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;DIV&gt;&lt;FONT face=Verdana size=2&gt;&lt;SPAN class=403183203-28032005&gt;We are then left with only one choice. Writing DLLs with C++ which export functions which use managed code. One of the several places that this could be used is handling XML configuration data. Windows Installer supports writing properties to both INI and Registry files but we do not have such facility for XML files. I guess this should be on the TODO list for the next version of Windows Installer &amp;lt;smile/&amp;gt;. But until then we would have to do it ourselves. There is a neat task in &lt;A href="http://nant.sf.net/"&gt;NAnt&lt;/A&gt; named &lt;A href="http://nant.sourceforge.net/release/latest/help/tasks/xmlpoke.html"&gt;&amp;lt;xmlpoke&amp;gt;&lt;/A&gt;. This custom action is&amp;nbsp;programmed in pretty much the same way without namespace support. Given the path to the XML file and the XPath expression, we would be able to replace the value with our own using the installer. And it should also support properties.&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT face=Verdana size=2&gt;&lt;SPAN class=403183203-28032005&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT face=Verdana size=2&gt;&lt;SPAN class=403183203-28032005&gt;I start off by creating a class library project in VS.NET 2003 and start editing the ProjectName.CPP file. Note that you would have to create a Module Definition file to support exporting the DLL functions that you write as symbols. Now for the fun stuff.&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT face=Verdana size=2&gt;&lt;SPAN class=403183203-28032005&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT face=Verdana size=2&gt;&lt;SPAN class=403183203-28032005&gt;Lets first write functions that can write to the log file.&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/DIV&gt;
&lt;DIV&gt;&lt;FONT face=Verdana size=2&gt;&lt;SPAN class=403183203-28032005&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV dir=ltr style="MARGIN-RIGHT: 0px"&gt;&lt;SPAN class=403183203-28032005&gt;&lt;FONT color=#0000ff&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT face=Verdana size=1&gt;UINT WriteToLog(MSIHANDLE hMSI, CHAR *strMessage)&lt;BR&gt;{&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;FONT face=Verdana size=1&gt;MSIHANDLE hrec=MsiCreateRecord(1);&lt;BR&gt;MsiRecordSetString(hrec,0, strMessage);&lt;BR&gt;MsiProcessMessage(hMSI,INSTALLMESSAGE_INFO,hrec);&lt;BR&gt;MsiCloseHandle(hrec);&lt;BR&gt;&lt;FONT color=#0000ff&gt;return&lt;/FONT&gt; ERROR_SUCCESS;&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face=Verdana size=1&gt;}&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN class=403183203-28032005&gt;&lt;FONT face=Verdana size=2&gt;The above function is a pretty simple function that just writes any string of characters to the log file. While this function is good enough, we will write another function that accepts the managed String type.&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;SPAN class=403183203-28032005&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;&lt;/FONT&gt;&lt;FONT face=Verdana&gt;&lt;FONT color=#0000ff size=1&gt;void&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;FONT face=Verdana&gt; WriteToLog1(MSIHANDLE hMSI, String* strMessage)&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face=Verdana&gt;{&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;FONT size=1&gt;&lt;FONT face=Verdana&gt;CHAR* strMessageArr={0};&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face=Verdana&gt;strMessageArr=(&lt;/FONT&gt;&lt;FONT face=Verdana&gt;&lt;FONT color=#0000ff&gt;char&lt;/FONT&gt;*)(&lt;FONT color=#0000ff&gt;void&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;FONT face=Verdana&gt;*)Marshal::StringToHGlobalAnsi(strMessage);&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face=Verdana&gt;WriteToLog(hMSI,strMessageArr);&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face=Verdana size=1&gt;}&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=+0&gt;&lt;SPAN class=403183203-28032005&gt;&lt;FONT face=Verdana size=2&gt;This functions accepts&amp;nbsp;the managed&amp;nbsp;String* and Marshals it to a character array and then writes it to the log file. Now that we have the logging functions ready, lets concentrate on the actual juice. The idea here is that we use a deferred custom action to poke values into the XML file. The custom action expects data in a '|' delimited list in the following format.&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN class=403183203-28032005&gt;&lt;FONT face=Verdana size=2&gt;[XMLFILEPATH]|[XPATHEXPRESSION]|[NEWVALUE]&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN class=403183203-28032005&gt;&lt;FONT face=Verdana size=2&gt;A immediate &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/obtaining_context_information_for_deferred_execution_custom_actions.asp"&gt;type 51&lt;/A&gt; custom action sets the &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vsintro7/html/vxgrfcustomactiondataproperty.asp"&gt;CustomActionData&lt;/A&gt; property in the above format.&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;FONT size=+0&gt;&lt;SPAN class=403183203-28032005&gt;&lt;FONT color=#0000ff size=2&gt;
&lt;P&gt;&lt;FONT face=Verdana size=1&gt;extern&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face=Verdana&gt;&lt;FONT size=1&gt; "C" &lt;FONT color=#0000ff&gt;__declspec&lt;/FONT&gt;(&lt;FONT color=#0000ff&gt;dllexport&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face=Verdana size=1&gt;) UINT XmlPoke(MSIHANDLE hMSI)&lt;BR&gt;{&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;FONT face=Verdana&gt;&lt;FONT size=1&gt;TCHAR propval[261]={0};&lt;BR&gt;DWORD len=261;&lt;BR&gt;MsiGetProperty(hMSI,TEXT("CustomActionData"),propval,&amp;amp;len);&lt;BR&gt;WriteToLog(hMSI,propval);&lt;BR&gt;String *str=&lt;FONT color=#0000ff&gt;new&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face=Verdana&gt;&lt;FONT size=1&gt; String(propval);&lt;BR&gt;String *delims="|";&lt;BR&gt;Char delim[]=delims-&amp;gt;ToCharArray();&lt;BR&gt;String* split[]=str-&amp;gt;Split(delim);&lt;BR&gt;FileInfo* fi=&lt;FONT color=#0000ff&gt;new&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face=Verdana size=1&gt; FileInfo(split[0]);&lt;BR&gt;&lt;FONT color=#0000ff&gt;if&lt;/FONT&gt;(fi-&amp;gt;Exists){&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;FONT face=Verdana&gt;&lt;FONT size=1&gt;&lt;FONT color=#0000ff&gt;try&lt;/FONT&gt;{&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;FONT face=Verdana&gt;&lt;FONT size=1&gt;XmlDocument* xdoc=&lt;FONT color=#0000ff&gt;new&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face=Verdana&gt;&lt;FONT size=1&gt; XmlDocument();&lt;BR&gt;xdoc-&amp;gt;Load(split[0]);&lt;BR&gt;XmlNodeList * nl=xdoc-&amp;gt;SelectNodes(split[1]);&lt;BR&gt;IEnumerator * nodesenum=nl-&amp;gt;GetEnumerator();&lt;BR&gt;WriteToLog1(hMSI,split[1]);&lt;BR&gt;&lt;FONT color=#0000ff&gt;while&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT size=1&gt;&lt;FONT face=Verdana&gt;(nodesenum-&amp;gt;MoveNext())&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face=Verdana&gt;{&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;FONT size=1&gt;&lt;FONT face=Verdana&gt;XmlNode* xNode=&lt;/FONT&gt;&lt;FONT face=Verdana color=#0000ff&gt;__try_cast&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face=Verdana&gt;&lt;FONT size=1&gt;&amp;lt;XmlNode*&amp;gt;(nodesenum-&amp;gt;Current);&lt;BR&gt;String* oldValue1=xNode-&amp;gt;InnerXml;&lt;BR&gt;WriteToLog1(hMSI,String::Concat(oldValue1, &lt;FONT color=#0000ff&gt;new&lt;/FONT&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face=Verdana size=1&gt; String(" was the old value")));&lt;BR&gt;xNode-&amp;gt;InnerXml=split[2];&lt;BR&gt;String* NewValue="New Value is ";&lt;BR&gt;WriteToLog1(hMSI,String::Concat(NewValue,split[2])); &lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face=Verdana size=1&gt;}&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face=Verdana size=1&gt;xdoc-&amp;gt;Save(split[0]);&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face=Verdana size=1&gt;}&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=1&gt;&lt;FONT face=Verdana color=#0000ff&gt;catch&lt;/FONT&gt;&lt;FONT face=Verdana&gt;(Exception* exc){&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;FONT face=Verdana size=1&gt;WriteToLog1(hMSI,exc-&amp;gt;Message);&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face=Verdana size=1&gt;}&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face=Verdana size=1&gt;}&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT color=#0000ff&gt;&lt;FONT face=Verdana size=1&gt;else&lt;/FONT&gt;&lt;/P&gt;&lt;/FONT&gt;
&lt;P&gt;&lt;FONT face=Verdana size=1&gt;{&lt;/FONT&gt;&lt;/P&gt;
&lt;BLOCKQUOTE dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;P&gt;&lt;FONT face=Verdana size=1&gt;WriteToLog(hMSI,"Error: The file does not exist");&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face=Verdana size=1&gt;}&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=1&gt;&lt;FONT face=Verdana color=#0000ff&gt;return&lt;/FONT&gt;&lt;FONT face=Verdana&gt; ERROR_SUCCESS;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;&lt;FONT face=Verdana size=1&gt;}&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN class=403183203-28032005&gt;&lt;FONT face=Verdana size=2&gt;The above function reads the CustomActionData property and splits it into an array. I assume that setup developers are good and they always give good data. So I have only gone for rudimentary error handling. The custom action never fails unless the error is catastrophic and is not handled by the try-catch block. It tries find if the XML file exists and if it does, it loads the XML file. I then use the SelectNodes() function to select the list of nodes as per the XPath expression. And finally I set the InnerXml value of the function to the new value. I also log these values as and when required. Thats it... as simple as it seems.&amp;nbsp;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN class=403183203-28032005&gt;&lt;FONT face=Verdana size=2&gt;Dont forget to have the following header files and namespaces on top of the file. You would also have to include reference to System.Xml.Dll.&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;SPAN class=403183203-28032005&gt;&lt;FONT color=#0000ff&gt;
&lt;P&gt;&lt;FONT face=Verdana size=1&gt;#include&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face=Verdana size=1&gt; "stdafx.h"&lt;BR&gt;&lt;FONT color=#0000ff&gt;#include&lt;/FONT&gt; "windows.h"&lt;SPAN class=403183203-28032005&gt; &lt;FONT color=#008000&gt;//Required by MSI.h&lt;/FONT&gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;#include&lt;/FONT&gt; "XmlTasksManaged.h"&lt;BR&gt;&lt;/FONT&gt;&lt;FONT face=Verdana&gt;&lt;FONT size=1&gt;&lt;FONT color=#0000ff&gt;&lt;FONT color=#008000&gt;//The MSI Stuff&lt;/FONT&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;FONT color=#0000ff&gt;#include&lt;/FONT&gt; "Msi.h"&lt;/FONT&gt;&lt;/FONT&gt;&lt;SPAN class=403183203-28032005&gt;&lt;FONT face=Verdana size=1&gt; &lt;/FONT&gt;&lt;FONT color=#0000ff&gt;&lt;BR&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;FONT face=Verdana&gt;&lt;FONT size=1&gt;&lt;FONT color=#0000ff&gt;#include&lt;/FONT&gt; "MsiQuery.h"&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT color=#008000&gt;&lt;BR&gt;&lt;FONT face=Verdana size=1&gt;//.NET Stuff goes here&lt;BR&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;FONT face=Verdana&gt;&lt;FONT size=1&gt;&lt;FONT color=#0000ff&gt;using&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;namespace&lt;/FONT&gt; System;&lt;BR&gt;&lt;FONT color=#0000ff&gt;using&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;namespace&lt;/FONT&gt; System::IO;&lt;/FONT&gt;&lt;/FONT&gt;&lt;SPAN class=403183203-28032005&gt;&lt;FONT face=Verdana size=1&gt; &lt;/FONT&gt;&lt;FONT face=Verdana color=#008000 size=1&gt;//For the FileInfo Object&lt;BR&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;FONT face=Verdana&gt;&lt;FONT size=1&gt;&lt;FONT color=#0000ff&gt;using&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;namespace&lt;/FONT&gt; System::Collections;&lt;SPAN class=403183203-28032005&gt; &lt;/SPAN&gt;&lt;FONT color=#008000&gt;//&lt;SPAN class=403183203-28032005&gt;For the IEnumerator&lt;/SPAN&gt;&lt;/FONT&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;using&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;namespace&lt;/FONT&gt; System::Xml;&lt;SPAN class=403183203-28032005&gt; &lt;FONT color=#008000&gt;//The XML Stuff&lt;/FONT&gt;&lt;/SPAN&gt;&lt;BR&gt;&lt;FONT color=#0000ff&gt;using&lt;/FONT&gt; &lt;FONT color=#0000ff&gt;namespace&lt;/FONT&gt; System::Runtime::InteropServices;&lt;SPAN class=403183203-28032005&gt; &lt;FONT color=#008000&gt;//For the Marshal object&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT size=+0&gt;&lt;FONT color=#008000 size=1&gt;&lt;SPAN class=403183203-28032005&gt;&lt;SPAN class=403183203-28032005&gt;&lt;FONT face=Verdana color=#000000 size=2&gt;As mentioned earlier the Namespace support is still not included.&amp;nbsp;It is not a very difficult&amp;nbsp;functionality to add.&amp;nbsp;We can pass it to the CustomActionData property. We can then cut and slice the CustomActionData property as we please. &amp;lt;smile/&amp;gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/DIV&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=27473"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=27473" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/Vagmi.Mudumbai/aggbug/27473.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Vagmi Mudumbai</dc:creator>
            <guid>http://geekswithblogs.net/Vagmi.Mudumbai/archive/2005/03/28/27473.aspx</guid>
            <pubDate>Tue, 29 Mar 2005 01:55:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/Vagmi.Mudumbai/comments/27473.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/Vagmi.Mudumbai/archive/2005/03/28/27473.aspx#feedback</comments>
            <slash:comments>15</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/Vagmi.Mudumbai/comments/commentRss/27473.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/Vagmi.Mudumbai/services/trackbacks/27473.aspx</trackback:ping>
        </item>
        <item>
            <title>Unit Testing MSI Packages... Maybe</title>
            <link>http://geekswithblogs.net/Vagmi.Mudumbai/archive/2005/03/17/26523.aspx</link>
            <description>&lt;P&gt;I was recently reading the article by &lt;A href="http://www.martinfowler.com/articles/continuousIntegration.html"&gt;Marting Fowler on Continuous Integration&lt;/A&gt;. Our team has set process to have daily builds of the MSI package along with the binary builds. It would have been an easier task with the WIX Toolset but most of our code still is in &lt;A href="http://www.installshield.com"&gt;InstallShield&lt;/A&gt; DevStudio. We have used the InstallShield &lt;A href="http://helpnet.installshield.com/Robo/BIN/Robo.dll?mgr=agm&amp;amp;tpc=%2Frobo%2Fprojects%2Fhelplibdevstudio9%2FStandAloneBuild.htm&amp;amp;wnd=InstallShieldLivingHelp%7CMain&amp;amp;agt=wsm&amp;amp;ctxid=search%2Fgsearch.asp"&gt;Standalone Build environment&lt;/A&gt; to build our MSI package as a batch job. We have various build machines to build different parts of the software and the Standalone Build environment helps us achieve this process without bleeding for separate licenses. As Marting Fowler had suggested, a successful build is just not a build without errors, it should be a workable output which clears some basic tests. I wondered if we could implement the &lt;A href="http://www.extremeprogramming.org/rules/testfirst.html"&gt;Test First &lt;/A&gt;approach suggested by XP as a part of the MSI Build Process. The test first approach requires you to write self testing code which does some basic smoke tests. These are called unit tests or Build Verification Tests. I am sure that most developers include such code in their applications but I have not heard of such tests for Installation programs especially MSI packages.&lt;/P&gt;
&lt;P&gt;I had blogged earlier on how &lt;A href="http://geekswithblogs.net/vagmi.mudumbai/archive/2004/11/23/15669.aspx"&gt;the WIX Toolset can be used for distributed development&lt;/A&gt;. It is really cool that the WIX Toolset can avoid building merge modules, when they are not really required. But as we currently do not have much choice regarding this, we do build different projects as merge modules and later integrated them into the main project. Thus, technically our unit tests are integration tests. &lt;/P&gt;
&lt;P&gt;A successful installation is not just an installation without errors. A successful installation should install the desired set of features and components. So, their states should be checked. This would involve parsing the verbose log file generated. The .NET Regular Expressions helps very well here &amp;lt;grin/&amp;gt;. We can check for the action return values and the feature and component installation states from the log file. Additionally, after installation, the files and registry entries on the target machine can be compared to the files and registry entries in the MSI package for the components that are marked installed. This can be done by comparing an uncompressed build or an administrative image with the files on the target machine. These criteria have a greater impact during upgrade than the first time installation.&lt;/P&gt;
&lt;P&gt;I am just toying around with this idea and not really sure if it would be feasible for complex upgrade scenarios. I will post followups if I get anywhere with this. &amp;lt;smile/&amp;gt;&lt;/P&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=26523"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=26523" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/Vagmi.Mudumbai/aggbug/26523.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Vagmi Mudumbai</dc:creator>
            <guid>http://geekswithblogs.net/Vagmi.Mudumbai/archive/2005/03/17/26523.aspx</guid>
            <pubDate>Thu, 17 Mar 2005 13:54:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/Vagmi.Mudumbai/comments/26523.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/Vagmi.Mudumbai/archive/2005/03/17/26523.aspx#feedback</comments>
            <slash:comments>4</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/Vagmi.Mudumbai/comments/commentRss/26523.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/Vagmi.Mudumbai/services/trackbacks/26523.aspx</trackback:ping>
        </item>
        <item>
            <title>ATL RGS Woes</title>
            <link>http://geekswithblogs.net/Vagmi.Mudumbai/archive/2005/03/09/25841.aspx</link>
            <description>&lt;P&gt;I had been off the blogging world for quite some time now. I was so swamped with work that I really could not collect my mind to write anything worthwhile. I recently bumped into a really sticky issue (and continue to remain stuck with that). We have a VSIP enabled COM DLL that uses a lot of ATL RGS code. Some of these values in this RGS file were dependent on some &lt;GASP /&gt;environment variables. Also the path to the satillite DLL and some project items were authored in the RGS file. I tried harvesting registry entries out of the RGS file but there were far too many parameters to handle. And hence, I had to do the unthinkable ---- SELF REGISTRATION --- &lt;SIGH /&gt;&lt;GASP /&gt;&lt;PALE_WITH_HORROR /&gt;. But despite our attempts, surprise..surprise..But that did not work either. &lt;/P&gt;
&lt;P&gt;I then remembered that the environment variables were also a part of my package. And ofcourse, the environment variables will not be effected until the installation finishes and hence the registration failed. Developers did not have the time to fix it so we had to do a really nasty workaround. We needed to have chained setup; one to setup the environment variables and other to actually install the package. This is okay at the current stage as the package is used by our internal customers who are all developers and have predictable machine configurations. However, this will be a catastrophe on an actual production environment. &lt;/P&gt;
&lt;P&gt;I had &lt;A href="http://msdn.microsoft.com/newsgroups/default.aspx?dg=microsoft.public.vstudio.extensibility&amp;amp;mid=f64b09ca-578f-406a-a6e3-886b89ee15ac"&gt;posted&lt;/A&gt; in the MS Visual Studio extensibility newsgroups about other alternatives but was informed by Bob Arson that RGS file was the only way to go. However, some of Microsoft's VSIP deployment presentations demostrated authoring these registry entries using the registry view in the Visual Studio Installer project. A little bit of googling also revealed that &lt;A href="http://blogs.msdn.com/dr._ex/archive/2005/02/13/371990.aspx"&gt;we could use VsipRegPkg.exe&lt;/A&gt; to extract these registry entries for managed plugins. But ours is an unmanaged plugin :-(. Our developers claim that they have done the right thing as per Microsoft's recommendation and that they would not require the environment variables after they acquire the PLK. But even then, there is the dependency on the satillite DLL to be present in a particular location. I wish that the other Microsoft teams run their suggestions via the deployment groups. This would greatly benifit the overall quality of the product. I guess our developers need to watch MSDN TV. They almost say "Use Managed Code" on every show.&lt;/P&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=25841"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=25841" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/Vagmi.Mudumbai/aggbug/25841.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Vagmi Mudumbai</dc:creator>
            <guid>http://geekswithblogs.net/Vagmi.Mudumbai/archive/2005/03/09/25841.aspx</guid>
            <pubDate>Thu, 10 Mar 2005 01:25:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/Vagmi.Mudumbai/comments/25841.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/Vagmi.Mudumbai/archive/2005/03/09/25841.aspx#feedback</comments>
            <slash:comments>3</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/Vagmi.Mudumbai/comments/commentRss/25841.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/Vagmi.Mudumbai/services/trackbacks/25841.aspx</trackback:ping>
        </item>
        <item>
            <title>Breeds of Setup Engineers</title>
            <link>http://geekswithblogs.net/Vagmi.Mudumbai/archive/2005/01/06/19267.aspx</link>
            <description>&lt;P&gt;A little earlier, &lt;A href="http://chrpai.blogspot.com"&gt;Chris&lt;/A&gt; had put &lt;A href="http://www.geekswithblogs.net/vagmi.mudumbai/archive/2004/11/23/15669.aspx#19119"&gt;this comment&lt;/A&gt; on my blog about &lt;A href="http://geekswithblogs.net/vagmi.mudumbai/archive/2004/11/23/15669.aspx"&gt;Using The WIX Toolset for Distributed Development&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;Firstly, I believe that Chris and I belong to different breeds of setup engineers. Chris uses tools like AdminStudio, DevStudio and Repackager to repackage setups and distribute them via SMS, Active Directory or other Change and Configuration management applications. This breed is often known as a packaging engineer. They have to often deal with hideous packages which move all sort of cryptic resources and perform changes on the system. Oh.. dont you hate repacking a setup while on a tight deadline when a custom configuration is performed on the target machine by the setup "script" which depends on the machine state/user input/configuration/location and data being moved?&lt;/P&gt;
&lt;P&gt;I belong to a breed of setup engineers who are fortunate enough to design such hideous logic. We don't have to deal with black boxes of setup and try to figure out what is being installed. But we have a challenge of a different sort. We need to ensure that the setup runs without a problem on all configurations supported by the application itself. We are called Setup Developers. The setup developers have to take care of several criteria like the media size, privileges, future upgrades and design a fool proof system that is probably going to get upgraded and maintained for 3-4 years. And believe me, we do not have such a busy release schedule as InstallShield's. By the time we release a support package (which is usually a big patch), we forget what we put in the previous package. Hence we stay away from configuration specific tasks as far as possible. Maintaining such application/configuration data during the entire lifecycle of the product is quite a challenge.&lt;/P&gt;
&lt;P&gt;Setup Developers are often found in packs. :-) Usually, more than one developer works on a setup package. My blog entry about &lt;A href="http://geekswithblogs.net/vagmi.mudumbai/archive/2004/11/23/15669.aspx"&gt;using the WIX toolset for Distributed development &lt;/A&gt;is a real life scenario. So our efforts are that we create setups which can easily be deployed over a diaspora of machine configurations. If the setup fails then customer does not get a chance to find out the amazing bugs which the application developers put in to the product.&lt;/P&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=19267"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=19267" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/Vagmi.Mudumbai/aggbug/19267.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Vagmi Mudumbai</dc:creator>
            <guid>http://geekswithblogs.net/Vagmi.Mudumbai/archive/2005/01/06/19267.aspx</guid>
            <pubDate>Thu, 06 Jan 2005 18:12:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/Vagmi.Mudumbai/comments/19267.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/Vagmi.Mudumbai/archive/2005/01/06/19267.aspx#feedback</comments>
            <slash:comments>7</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/Vagmi.Mudumbai/comments/commentRss/19267.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/Vagmi.Mudumbai/services/trackbacks/19267.aspx</trackback:ping>
        </item>
        <item>
            <title>Configuration Data is such a Pain</title>
            <link>http://geekswithblogs.net/Vagmi.Mudumbai/archive/2004/12/29/18727.aspx</link>
            <description>I have finally got my computer to my new house in&amp;nbsp;&lt;A href="http://hulk.bu.edu/misc/karnataka/cities/bangalore"&gt;Bangalore&lt;/A&gt;. I dont have access to the internet, so I will essentially by offline. I am yet to install&amp;nbsp;&lt;A href="http://icsharpcode.com/OpenSource/SD"&gt;SharpDevelop&lt;/A&gt; and&amp;nbsp;&lt;A href="http://www.microsoft.com/downloads/details.aspx?FamilyID=9B3A2CA6-3647-4070-9F41-A333C6B9181D&amp;amp;displaylang=en"&gt;.NET Framework SDK v1.1&lt;/A&gt;. Hopefully, I should be able to get it done today. I had some time today morning but I was too busy playing NFS Hot Pursuit 2 and Quake 3. (No real souls to frag. Only bots. &lt;SIGH /&gt;) 
&lt;P&gt;Currently one of our installation packages does something that it should not be doing. It is handling configuration data for several applications. Clearly this created several issues during upgrades. Now, for the next schedule major release, we (the packaging team) decided that we would let the applications handle the configuration information. This was duly presented as a proposal to other "application development" teams in a meeting. The people were a little hot under the collar during the meeting. Other development groups suspected that we were doing this to brush off our responsibility. I am sure that other setup developers would also have faced such similar predicament.&lt;/P&gt;
&lt;P&gt;I was recently browsing through the &lt;A href="http://www.installshield.com/"&gt;InstallShield&lt;/A&gt; &lt;A href="http://community.installshield.com/"&gt;Community&lt;/A&gt; forums and found that mosth setup developers were invariably including configuration data as a part of their installation. I even saw one post where a setup developer had used a VBScript custom action with the FileSystemObject and tried to replace certain place holder texts in the installed configuration file. I am sure that many of us, who have burnt their fingers with VBScript and FSO, would agree with me. Logically speaking, there is nothing wrong with this approach. But we have to realize that we are introducing a element that can go wrong. Having deferred VBScript custom actions with FSO is a lot of fun while debugging. &lt;/P&gt;
&lt;P&gt;&lt;GRIN /&gt;My recommended approach would be to have a small configurator utility, which would accept command line parameters and perform the same tasks. This serves two purposes. &lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;The configuration data is effectively taken out of the MSI. You can avoid slicing and dicing the CustomActionData property to get the desired values. There is one element less in the project that can go wrong. 
&lt;LI&gt;The user need not run the installation, if he has specified incorrect configuration. He has the option of configuring the software after installing it. While installing on locked down environments, the setup author has to ensure that the permissions table is authored such that the current user has no problems writing on the the specified resources. This should'nt be a problem for registry keys or folders as their permission tokens can always be altered by the installer.&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;Finally, &lt;A href="http://www.geekswithblogs.net/rikoe"&gt;Riko&lt;/A&gt; is back. It seems that he is going to &lt;A href="http://www.geekswithblogs.net/rikoe/archive/2004/12/28/18643.aspx"&gt;submit his tallow source&lt;/A&gt; to the community. I can't wait to get my hands on it. &lt;SMILE /&gt;&lt;/P&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=18727"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=18727" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/Vagmi.Mudumbai/aggbug/18727.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Vagmi Mudumbai</dc:creator>
            <guid>http://geekswithblogs.net/Vagmi.Mudumbai/archive/2004/12/29/18727.aspx</guid>
            <pubDate>Wed, 29 Dec 2004 23:16:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/Vagmi.Mudumbai/comments/18727.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/Vagmi.Mudumbai/archive/2004/12/29/18727.aspx#feedback</comments>
            <slash:comments>3</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/Vagmi.Mudumbai/comments/commentRss/18727.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/Vagmi.Mudumbai/services/trackbacks/18727.aspx</trackback:ping>
        </item>
        <item>
            <title>My 2 cents</title>
            <link>http://geekswithblogs.net/Vagmi.Mudumbai/archive/2004/12/23/18399.aspx</link>
            <description>&lt;P&gt;If people were following the the WIX-Users Mailing list, they would find that it has been a little hot recently. The first instance (as far as my knowledge goes) was with &lt;A href="http://msmvps.com/michael/"&gt;Michael&lt;/A&gt; creating a validation tool for the WIX Toolset called '&lt;A href="http://www.deploynow.com/Articles/Details.aspx?ID=2"&gt;smoke&lt;/A&gt;'. I personally found it very useful as it could easily be included as a part of the build process. The output is in a structured XML format that makes it easier for us to crunch and build reports. But, some of the members in the group did not share the same level of enthusiasm. &lt;A href="http://msmvps.com/michael/"&gt;Michael&lt;/A&gt; seemed to be put off by that and included a &lt;A href="http://msmvps.com/michael/archive/2004/12/13/23808.aspx"&gt;disturbing update&lt;/A&gt; to his blog entry. &lt;A href="http://blogs.msdn.com/robmen"&gt;Rob&lt;/A&gt; immediately acknowledged it and posted a blog entry&amp;nbsp;about being &lt;A href="http://blogs.msdn.com/robmen/archive/2004/12/16/318015.aspx"&gt;thick skinned&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;Recently, history repeated with Marc Bogers starting to ask about the ICE 33 warnings as Tallow populates the Registry table instead of the &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/registry_tables_group.asp"&gt;Registry Tables group&lt;/A&gt;. Firstly, Tallow is only a helper utility and is anything but perfect. It is useful but does not exactly produce usable WIX code. Heck, it doesn't even write to a file. &lt;A href="http://blogs.msdn.com/robmen"&gt;Rob&lt;/A&gt; had said that ICE33 warnings can be ignored as it created some "strange behavior". More precisely, the resiliency associated with advertisement would prompt the end user for the media when Windows Installer detects some inconsistencies with the CLSID registration. Michael dismissed the argument that it arose from sloppy authoring and had nothing to do with MSI itself. Follow Michael's &lt;A href="http://msmvps.com/michael/archive/2004/12/22/26726.aspx"&gt;blog entry on COM registration &lt;/A&gt;for more information. &lt;/P&gt;
&lt;P&gt;As we all know, Rob does not agree on a lot of things like inserting GUIDs while generating output with Tallow, using the &lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/registry_tables_group.asp"&gt;Registry Tables Group &lt;/A&gt;and so on. I am sure that he has good reasons behind them. I am also sure that many people (including me), have modified Tallow to suit their requirements. Some people are using &lt;A href="http://geekswithblogs.net/rikoe"&gt;Riko&lt;/A&gt;'s Tallow that does write to the Regsitry table's group using the Class and TypeLib elements. (On a totally different note, Riko, when are you going to release that code of yours?) I have a version of Tallow that creates components with GUIDs and names them appropriately. I am pretty sure that I am aware of the consequences and I have written code to persist the component information for future reference. &lt;/P&gt;
&lt;P&gt;This freedom is the inherent beauty of open-source software. People can use their own ingenious imagination to tailor the tool to best suit their requirements. Of course, some of our opinions differ and we need a healthy debate to analyze these opinions and make the best of it. We should refrain from flaming and should try to embrace new ideas. Rob may be the BDFL for the &lt;A href="http://wix.sourceforge.net"&gt;WIX Toolset&lt;/A&gt; but I am sure that he would like the WIX Toolset to be successful and that helps developers create better installers without breaking much sweat. I tried hard not to write about this topic but after reading Michael's blog and comments with certain &lt;A href="http://msmvps.com/michael/archive/2004/12/22/26809.aspx"&gt;conspiracy theories&lt;/A&gt;, I wanted to voice my opinion too. I am sorry if I have hurt anybody's feelings.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=18399"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=18399" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/Vagmi.Mudumbai/aggbug/18399.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Vagmi Mudumbai</dc:creator>
            <guid>http://geekswithblogs.net/Vagmi.Mudumbai/archive/2004/12/23/18399.aspx</guid>
            <pubDate>Thu, 23 Dec 2004 22:18:00 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/Vagmi.Mudumbai/comments/18399.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/Vagmi.Mudumbai/archive/2004/12/23/18399.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/Vagmi.Mudumbai/comments/commentRss/18399.aspx</wfw:commentRss>
            <trackback:ping>http://geekswithblogs.net/Vagmi.Mudumbai/services/trackbacks/18399.aspx</trackback:ping>
        </item>
    </channel>
</rss>