<?xml version="1.0" encoding="utf-8" ?>

<rss version="2.0" 
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:admin="http://webns.net/mvcb/"
   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/"
   xmlns:content="http://purl.org/rss/1.0/modules/content/"
   >
<channel>
    
    <title>vagmi's personal blog - Setup</title>
    <link>http://vagmi.supersized.org/</link>
    <description>Another ubercool s9y blog</description>
    <dc:language>en</dc:language>
    <generator>Serendipity 1.6-alpha1 - http://www.s9y.org/</generator>
    <pubDate>Fri, 07 Oct 2005 14:37:13 GMT</pubDate>

    <image>
        <url>http://vagmi.supersized.org/templates/default/img/s9y_banner_small.png</url>
        <title>RSS: vagmi's personal blog - Setup - Another ubercool s9y blog</title>
        <link>http://vagmi.supersized.org/</link>
        <width>100</width>
        <height>21</height>
    </image>

<item>
    <title>Multi Platform versus Cross Platform</title>
    <link>http://vagmi.supersized.org/archives/18-Multi-Platform-versus-Cross-Platform.html</link>
            <category>Open Source</category>
            <category>Setup</category>
    
    <comments>http://vagmi.supersized.org/archives/18-Multi-Platform-versus-Cross-Platform.html#comments</comments>
    <wfw:comment>http://vagmi.supersized.org/wfwcomment.php?cid=18</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://vagmi.supersized.org/rss.php?version=2.0&amp;type=comments&amp;cid=18</wfw:commentRss>
    

    <author>nospam@example.com (Vagmi)</author>
    <content:encoded>
    
&lt;p&gt;
I have lately been pondering over methods to deploy cross platform
products. I investigated certain options like 
&lt;a href=&quot;http://www.installshield.com/products/installshield/premier/universal.asp&quot;&gt;
InstallShield&#039;s Universal Project&lt;/a&gt; and 
&lt;a href=&quot;http://zerog.com/installanywhere-create-deploy-java-multiplatform-installers.html&quot;&gt;
ZeroG&#039;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;br /&gt;&lt;a href=&quot;http://vagmi.supersized.org/archives/18-Multi-Platform-versus-Cross-Platform.html#extended&quot;&gt;Continue reading &quot;Multi Platform versus Cross Platform&quot;&lt;/a&gt;
    </content:encoded>

    <pubDate>Fri, 07 Oct 2005 16:34:27 +0200</pubDate>
    <guid isPermaLink="false">http://vagmi.supersized.org/archives/18-guid.html</guid>
    
</item>
<item>
    <title>Anders Helsberg + Whiteboard + C# = really cool</title>
    <link>http://vagmi.supersized.org/archives/2-Anders-Helsberg-+-Whiteboard-+-C-really-cool.html</link>
            <category>Setup</category>
    
    <comments>http://vagmi.supersized.org/archives/2-Anders-Helsberg-+-Whiteboard-+-C-really-cool.html#comments</comments>
    <wfw:comment>http://vagmi.supersized.org/wfwcomment.php?cid=2</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://vagmi.supersized.org/rss.php?version=2.0&amp;type=comments&amp;cid=2</wfw:commentRss>
    

    <author>nospam@example.com (Vagmi)</author>
    <content:encoded>
    &lt;!-- Converted from text/plain format --&gt; &lt;font face=&quot;Verdana&quot; size=&quot;2&quot;&gt;While I was browsing the MSDN, I came across this very &lt;/font&gt;&lt;a href=&quot;http://msdn.microsoft.com/msdntv/episode.aspx?xml=episodes/en/20040624csharpah/manifest.xml&quot;&gt;&lt;font face=&quot;Verdana&quot; size=&quot;2&quot;&gt;interesting video&lt;/font&gt;&lt;/a&gt;&lt;font face=&quot;Verdana&quot; size=&quot;2&quot;&gt; which features &lt;/font&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Anders_Hejlsberg&quot;&gt;&lt;font face=&quot;Verdana&quot; size=&quot;2&quot;&gt;Anders Helsberg&lt;/font&gt;&lt;/a&gt;&lt;font face=&quot;Verdana&quot;&gt;&lt;font size=&quot;2&quot;&gt; and his skills with the whiteboard. I really wish &lt;span class=&quot;476013103-27042005&quot;&gt;that &lt;/span&gt;he &lt;span class=&quot;476013103-27042005&quot;&gt;teach&lt;/span&gt; me programming.&lt;span class=&quot;476013103-27042005&quot;&gt; A must see for every C# programmer.&lt;/span&gt;&lt;/font&gt;&lt;/font&gt;&lt;img height=&quot;1&quot; src=&quot;http://geekswithblogs.net/vagmi.mudumbai/aggbug/38495.aspx&quot; width=&quot;1&quot; alt=&quot;&quot;  /&gt;  
    </content:encoded>

    <pubDate>Wed, 27 Apr 2005 11:36:00 +0200</pubDate>
    <guid isPermaLink="false">http://vagmi.supersized.org/archives/2-guid.html</guid>
    
</item>
<item>
    <title>Unit Testing MSI Packages... Maybe</title>
    <link>http://vagmi.supersized.org/archives/5-Unit-Testing-MSI-Packages...-Maybe.html</link>
            <category>Setup</category>
    
    <comments>http://vagmi.supersized.org/archives/5-Unit-Testing-MSI-Packages...-Maybe.html#comments</comments>
    <wfw:comment>http://vagmi.supersized.org/wfwcomment.php?cid=5</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://vagmi.supersized.org/rss.php?version=2.0&amp;type=comments&amp;cid=5</wfw:commentRss>
    

    <author>nospam@example.com (Vagmi)</author>
    <content:encoded>
    &lt;p&gt;I was recently reading the article by &lt;a href=&quot;http://www.martinfowler.com/articles/continuousIntegration.html&quot;&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=&quot;http://www.installshield.com/&quot;&gt;InstallShield&lt;/a&gt; DevStudio. We have used the InstallShield &lt;a href=&quot;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&quot;&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=&quot;http://www.extremeprogramming.org/rules/testfirst.html&quot;&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=&quot;http://geekswithblogs.net/vagmi.mudumbai/archive/2004/11/23/15669.aspx&quot;&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;img height=&quot;1&quot; src=&quot;http://geekswithblogs.net/vagmi.mudumbai/aggbug/26523.aspx&quot; width=&quot;1&quot; alt=&quot;&quot;  /&gt;  
    </content:encoded>

    <pubDate>Thu, 17 Mar 2005 09:54:00 +0100</pubDate>
    <guid isPermaLink="false">http://vagmi.supersized.org/archives/5-guid.html</guid>
    
</item>
<item>
    <title>ATL RGS Woes</title>
    <link>http://vagmi.supersized.org/archives/6-ATL-RGS-Woes.html</link>
            <category>Setup</category>
    
    <comments>http://vagmi.supersized.org/archives/6-ATL-RGS-Woes.html#comments</comments>
    <wfw:comment>http://vagmi.supersized.org/wfwcomment.php?cid=6</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://vagmi.supersized.org/rss.php?version=2.0&amp;type=comments&amp;cid=6</wfw:commentRss>
    

    <author>nospam@example.com (Vagmi)</author>
    <content:encoded>
    &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=&quot;http://msdn.microsoft.com/newsgroups/default.aspx?dg=microsoft.public.vstudio.extensibility&amp;amp;mid=f64b09ca-578f-406a-a6e3-886b89ee15ac&quot;&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&#039;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=&quot;http://blogs.msdn.com/dr._ex/archive/2005/02/13/371990.aspx&quot;&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&#039;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 &amp;quot;Use Managed Code&amp;quot; on every show.&lt;/p&gt;&lt;img height=&quot;1&quot; src=&quot;http://geekswithblogs.net/vagmi.mudumbai/aggbug/25841.aspx&quot; width=&quot;1&quot; alt=&quot;&quot;  /&gt;  
    </content:encoded>

    <pubDate>Wed, 09 Mar 2005 20:25:00 +0100</pubDate>
    <guid isPermaLink="false">http://vagmi.supersized.org/archives/6-guid.html</guid>
    
</item>
<item>
    <title>Breeds of Setup Engineers</title>
    <link>http://vagmi.supersized.org/archives/8-Breeds-of-Setup-Engineers.html</link>
            <category>Setup</category>
    
    <comments>http://vagmi.supersized.org/archives/8-Breeds-of-Setup-Engineers.html#comments</comments>
    <wfw:comment>http://vagmi.supersized.org/wfwcomment.php?cid=8</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://vagmi.supersized.org/rss.php?version=2.0&amp;type=comments&amp;cid=8</wfw:commentRss>
    

    <author>nospam@example.com (Vagmi)</author>
    <content:encoded>
    &lt;p&gt;A little earlier, &lt;a href=&quot;http://chrpai.blogspot.com/&quot;&gt;Chris&lt;/a&gt; had put &lt;a href=&quot;http://www.geekswithblogs.net/vagmi.mudumbai/archive/2004/11/23/15669.aspx#19119&quot;&gt;this comment&lt;/a&gt; on my blog about &lt;a href=&quot;http://geekswithblogs.net/vagmi.mudumbai/archive/2004/11/23/15669.aspx&quot;&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 &amp;quot;script&amp;quot; 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&#039;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&#039;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=&quot;http://geekswithblogs.net/vagmi.mudumbai/archive/2004/11/23/15669.aspx&quot;&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;img height=&quot;1&quot; src=&quot;http://geekswithblogs.net/vagmi.mudumbai/aggbug/19267.aspx&quot; width=&quot;1&quot; alt=&quot;&quot;  /&gt;  
    </content:encoded>

    <pubDate>Thu, 06 Jan 2005 13:12:00 +0100</pubDate>
    <guid isPermaLink="false">http://vagmi.supersized.org/archives/8-guid.html</guid>
    
</item>
<item>
    <title>Configuration Data is such a Pain</title>
    <link>http://vagmi.supersized.org/archives/10-Configuration-Data-is-such-a-Pain.html</link>
            <category>Setup</category>
    
    <comments>http://vagmi.supersized.org/archives/10-Configuration-Data-is-such-a-Pain.html#comments</comments>
    <wfw:comment>http://vagmi.supersized.org/wfwcomment.php?cid=10</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://vagmi.supersized.org/rss.php?version=2.0&amp;type=comments&amp;cid=10</wfw:commentRss>
    

    <author>nospam@example.com (Vagmi)</author>
    <content:encoded>
    I have finally got my computer to my new house in &lt;a href=&quot;http://hulk.bu.edu/misc/karnataka/cities/bangalore&quot;&gt;Bangalore&lt;/a&gt;. I dont have access to the internet, so I will essentially by offline. I am yet to install &lt;a href=&quot;http://icsharpcode.com/OpenSource/SD&quot;&gt;SharpDevelop&lt;/a&gt; and &lt;a href=&quot;http://www.microsoft.com/downloads/details.aspx?FamilyID=9B3A2CA6-3647-4070-9F41-A333C6B9181D&amp;amp;displaylang=en&quot;&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 &amp;quot;application development&amp;quot; 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=&quot;http://www.installshield.com/&quot;&gt;InstallShield&lt;/a&gt;&lt;a href=&quot;http://community.installshield.com/&quot;&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;&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&#039;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=&quot;http://www.geekswithblogs.net/rikoe&quot;&gt;Riko&lt;/a&gt; is back. It seems that he is going to &lt;a href=&quot;http://www.geekswithblogs.net/rikoe/archive/2004/12/28/18643.aspx&quot;&gt;submit his tallow source&lt;/a&gt; to the community. I can&#039;t wait to get my hands on it. &lt;smile /&gt;&lt;/p&gt;&lt;img height=&quot;1&quot; src=&quot;http://geekswithblogs.net/vagmi.mudumbai/aggbug/18727.aspx&quot; width=&quot;1&quot; alt=&quot;&quot;  /&gt;  
    </content:encoded>

    <pubDate>Wed, 29 Dec 2004 18:16:00 +0100</pubDate>
    <guid isPermaLink="false">http://vagmi.supersized.org/archives/10-guid.html</guid>
    
</item>
<item>
    <title>My 2 cents</title>
    <link>http://vagmi.supersized.org/archives/11-My-2-cents.html</link>
            <category>Setup</category>
    
    <comments>http://vagmi.supersized.org/archives/11-My-2-cents.html#comments</comments>
    <wfw:comment>http://vagmi.supersized.org/wfwcomment.php?cid=11</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://vagmi.supersized.org/rss.php?version=2.0&amp;type=comments&amp;cid=11</wfw:commentRss>
    

    <author>nospam@example.com (Vagmi)</author>
    <content:encoded>
    &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=&quot;http://msmvps.com/michael/&quot;&gt;Michael&lt;/a&gt; creating a validation tool for the WIX Toolset called &#039;&lt;a href=&quot;http://www.deploynow.com/Articles/Details.aspx?ID=2&quot;&gt;smoke&lt;/a&gt;&#039;. 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=&quot;http://msmvps.com/michael/&quot;&gt;Michael&lt;/a&gt; seemed to be put off by that and included a &lt;a href=&quot;http://msmvps.com/michael/archive/2004/12/13/23808.aspx&quot;&gt;disturbing update&lt;/a&gt; to his blog entry. &lt;a href=&quot;http://blogs.msdn.com/robmen&quot;&gt;Rob&lt;/a&gt; immediately acknowledged it and posted a blog entry about being &lt;a href=&quot;http://blogs.msdn.com/robmen/archive/2004/12/16/318015.aspx&quot;&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=&quot;http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/registry_tables_group.asp&quot;&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&#039;t even write to a file. &lt;a href=&quot;http://blogs.msdn.com/robmen&quot;&gt;Rob&lt;/a&gt; had said that ICE33 warnings can be ignored as it created some &amp;quot;strange behavior&amp;quot;. 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&#039;s &lt;a href=&quot;http://msmvps.com/michael/archive/2004/12/22/26726.aspx&quot;&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=&quot;http://msdn.microsoft.com/library/default.asp?url=/library/en-us/msi/setup/registry_tables_group.asp&quot;&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=&quot;http://geekswithblogs.net/rikoe&quot;&gt;Riko&lt;/a&gt;&#039;s Tallow that does write to the Regsitry table&#039;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=&quot;http://wix.sourceforge.net/&quot;&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&#039;s blog and comments with certain &lt;a href=&quot;http://msmvps.com/michael/archive/2004/12/22/26809.aspx&quot;&gt;conspiracy theories&lt;/a&gt;, I wanted to voice my opinion too. I am sorry if I have hurt anybody&#039;s feelings.&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;img height=&quot;1&quot; src=&quot;http://geekswithblogs.net/vagmi.mudumbai/aggbug/18399.aspx&quot; width=&quot;1&quot; alt=&quot;&quot;  /&gt;  
    </content:encoded>

    <pubDate>Thu, 23 Dec 2004 17:18:00 +0100</pubDate>
    <guid isPermaLink="false">http://vagmi.supersized.org/archives/11-guid.html</guid>
    
</item>
<item>
    <title>Using an InstallScript application as the setup launcher</title>
    <link>http://vagmi.supersized.org/archives/12-Using-an-InstallScript-application-as-the-setup-launcher.html</link>
            <category>Setup</category>
    
    <comments>http://vagmi.supersized.org/archives/12-Using-an-InstallScript-application-as-the-setup-launcher.html#comments</comments>
    <wfw:comment>http://vagmi.supersized.org/wfwcomment.php?cid=12</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://vagmi.supersized.org/rss.php?version=2.0&amp;type=comments&amp;cid=12</wfw:commentRss>
    

    <author>nospam@example.com (Vagmi)</author>
    <content:encoded>
    &lt;p&gt;This, I guess, is my first &lt;a href=&quot;http://www.installshield.com/&quot;&gt;InstallShield&lt;/a&gt; specific post. MSI is good in a lot of things but not when dealing with more than one package in a single transaction. MSI engine is designed to be run as a single instance and cannot be used effectively to install more than one package. Nested installations are possible but often lead to undesired consequences. Having a setup chainer is good but it involves writing code and handling reboots. So, for all who are using &lt;a href=&quot;http://www.installshield.com/products/installshield/default.asp&quot;&gt;InstallShield DevStudio&lt;/a&gt; and up can benefit by using the &lt;a href=&quot;http://helpnet.installshield.com/Robo/BIN/Robo.dll?tpc=/robo/projects/InstallShieldXHelpLib/ProjectType_InstallScript.htm&quot;&gt;InstallScript project&lt;/a&gt; as their setup launcher and monitor. We can effectively &amp;quot;script&amp;quot; a launcher application and have complete control over the installation process using the available libraries.&lt;/p&gt;&lt;p&gt;Why InstallScript....? I would not usually recommend InstallScript for any of the custom actions in the project, as the MSI-Scripting bridge is a little weak and has certain limitations. However, InstallScript libraries would cut down most of the code that you would have to write with a brand new C++ application. Also the scripting engine supports the silent mode. So you do not have to code separately for that either. But on the flip side, you would have an overhead of 1 Meg for the InstallScript engine. But this is okay considering the fresh set of bugs that you would introduce with the first version of the launcher application. For those not concerned about silent mode, you can check out the free open source setup launcher (&lt;a href=&quot;http://www.devage.com/dotNetInstaller/dotNetInstaller.html&quot;&gt;dotNetInstaller&lt;/a&gt;).&lt;/p&gt;&lt;p&gt;The trick here is to use the InstallScript&#039;s program....endprogram syntax instead of the event based model. This makes sure that you do not register the application and does not call unknown events in between. Good old block scripting. &amp;lt;smile/&amp;gt; This also means that you need to take care of exceptions. If you are a setup developer from the good old InstallShield Professional 5.x days, you would immediately be at home with this kind of approach. So a simple script to just display a message box would be as below.&lt;/p&gt;&lt;p&gt;#include &amp;quot;ifx.h&amp;quot; //The standard header&lt;br /&gt;//Our program block starts here&lt;br /&gt;program&lt;br /&gt; MessageBox(&amp;quot;Hello World!&amp;quot;,INFORMATION);&lt;br /&gt;endprogram&lt;/p&gt;&lt;p&gt;InstallScript engine just executes the statments present between the program and endprogram statements. As you can see, this approach gives you the flexibility of a complete scripting language with libraries custom made for creating installations. InstallScript projects are known for their flexibility but miss on the other aspects of MSI such as Elevated Privileges, Install on Demand, Source Resiliency and Self-healing. &lt;/p&gt;&lt;img height=&quot;1&quot; src=&quot;http://geekswithblogs.net/vagmi.mudumbai/aggbug/17397.aspx&quot; width=&quot;1&quot; alt=&quot;&quot;  /&gt;  
    </content:encoded>

    <pubDate>Mon, 13 Dec 2004 18:16:00 +0100</pubDate>
    <guid isPermaLink="false">http://vagmi.supersized.org/archives/12-guid.html</guid>
    
</item>
<item>
    <title>Spying on Registry Entries</title>
    <link>http://vagmi.supersized.org/archives/13-Spying-on-Registry-Entries.html</link>
            <category>Setup</category>
    
    <comments>http://vagmi.supersized.org/archives/13-Spying-on-Registry-Entries.html#comments</comments>
    <wfw:comment>http://vagmi.supersized.org/wfwcomment.php?cid=13</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://vagmi.supersized.org/rss.php?version=2.0&amp;type=comments&amp;cid=13</wfw:commentRss>
    

    <author>nospam@example.com (Vagmi)</author>
    <content:encoded>
    &lt;p&gt;I am probably letting out the best kept secret of installation industry. I always used to wonder and have now discovered how most of the installation tools spy on registry entries that are created during COM registration or similar processes without actually affecting the build system. The spying program creates temporary registry keys for each of the registry hives HKCR, HKLM, HKCU, HKU and it maps the registry hives to these temporary registry keys. It then triggers the registration function which creates registry entries withing the registry keys specified instead of including it in the hives. I came across this revelation while I was wading through the source code for Tallow in the &lt;a href=&quot;http://wix.sf.net/&quot;&gt;WIX&lt;/a&gt; toolset.&lt;/p&gt;&lt;p&gt;The core of this spying exercise relies on functions exposed by the advapi32.dll. The actual hive to key mapping is performed by the &lt;a href=&quot;http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/regoverridepredefkey.asp&quot;&gt;RegOverridePredefKey()&lt;/a&gt; function. The handle to the registry key is passed by using the &lt;a href=&quot;http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/regcreatekeyex.asp&quot;&gt;RegCreateKeyEx()&lt;/a&gt; or the &lt;a href=&quot;http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sysinfo/base/regopenkeyex.asp&quot;&gt;RegOpenKeyEx()&lt;/a&gt; function. After the mapping is done, you can invoke the DllRegisterServer() function after loading the library using the &lt;a href=&quot;http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/loadlibrary.asp&quot;&gt;LoadLibrary()&lt;/a&gt; function. This mapping would be active for all the registry entries created by that particular process. So out of process registration for exe files may not directly work with this method. For the sake of simplicity, I am going to extract COM Interop settings from a given assembly. So let us write a simple console app in C# to do this. This app would perform the mapping and write the registry entries to a REG file and wipe out the key after the file is written.&lt;/p&gt;&lt;p&gt;Extracting registration information from a DLL file is similar but involve the importing other functions from Kernel32.dll. So I am giving that a raincheck now. You can download the Wix toolset&#039;s source package if you are interested. To start off with, let us write a class with static members to import the functions from advapi32.dll and create wrappers for them. Ensure that you have &lt;a href=&quot;http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemruntimeinteropservices.asp&quot;&gt;System.Runtime.InteropServices&lt;/a&gt; namespace included.&lt;/p&gt;&lt;div class=&quot;cf&quot;&gt;&lt;p class=&quot;cl&quot;&gt;    &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;class&lt;/font&gt;&lt;/span&gt; OverRideRegistry&lt;br /&gt;    {&lt;br /&gt;        &lt;span class=&quot;cb2&quot;&gt;&lt;font color=&quot;#008000&quot;&gt;//We first declare some stuff required. The are defined in winreg.h and windows.h&lt;/font&gt;&lt;/span&gt;        &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;public&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;static&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;readonly&lt;/font&gt;&lt;/span&gt; UIntPtr HkeyClassesRoot = (UIntPtr)0x80000000;&lt;br /&gt;        &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;public&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;static&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;readonly&lt;/font&gt;&lt;/span&gt; UIntPtr HkeyCurrentUser = (UIntPtr)0x80000001;&lt;br /&gt;        &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;public&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;static&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;readonly&lt;/font&gt;&lt;/span&gt; UIntPtr HkeyLocalMachine = (UIntPtr)0x80000002;&lt;br /&gt;        &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;public&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;static&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;readonly&lt;/font&gt;&lt;/span&gt; UIntPtr HkeyUsers = (UIntPtr)0x80000003;&lt;br /&gt;&lt;br /&gt;        &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;public&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;const&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;uint&lt;/font&gt;&lt;/span&gt; Delete = 0x00010000;&lt;br /&gt;        &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;public&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;const&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;uint&lt;/font&gt;&lt;/span&gt; ReadOnly = 0x00020000;&lt;br /&gt;        &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;public&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;const&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;uint&lt;/font&gt;&lt;/span&gt; WriteDac = 0x00040000;&lt;br /&gt;        &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;public&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;const&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;uint&lt;/font&gt;&lt;/span&gt; WriteOwner = 0x00080000;&lt;br /&gt;        &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;public&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;const&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;uint&lt;/font&gt;&lt;/span&gt; Synchronize = 0x00100000;&lt;br /&gt;        &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;public&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;const&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;uint&lt;/font&gt;&lt;/span&gt; StandardRightsRequired = 0x000F0000;&lt;br /&gt;        &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;public&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;const&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;uint&lt;/font&gt;&lt;/span&gt; StandardRightsAll = 0x001F0000;&lt;br /&gt;&lt;br /&gt;        &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;public&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;const&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;uint&lt;/font&gt;&lt;/span&gt; GenericRead = 0x80000000;&lt;br /&gt;        &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;public&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;const&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;uint&lt;/font&gt;&lt;/span&gt; GenericWrite = 0x40000000;&lt;br /&gt;        &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;public&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;const&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;uint&lt;/font&gt;&lt;/span&gt; GenericExecute = 0x20000000;&lt;br /&gt;        &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;public&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;const&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;uint&lt;/font&gt;&lt;/span&gt; GenericAll = 0x10000000;&lt;br /&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;&lt;br /&gt;        #region&lt;/font&gt;&lt;/span&gt; The Interop Import Stuff&lt;br /&gt;        &lt;span class=&quot;cb2&quot;&gt;&lt;font color=&quot;#008000&quot;&gt;//we now import the functions exposed by advapi32.dll&lt;/font&gt;&lt;/span&gt;        &lt;span class=&quot;cb2&quot;&gt;&lt;font color=&quot;#008000&quot;&gt;//Use RegCreateKeyEx to get handle to the openedKey&lt;/font&gt;&lt;/span&gt;        [DllImport(&amp;quot;advapi32.dll&amp;quot;, EntryPoint=&amp;quot;RegCreateKeyExW&amp;quot;, CharSet=CharSet.Unicode, ExactSpelling=&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;true&lt;/font&gt;&lt;/span&gt;, SetLastError=&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;true&lt;/font&gt;&lt;/span&gt;)]&lt;br /&gt;        &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;internal&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;static&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;extern&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;int&lt;/font&gt;&lt;/span&gt; RegCreateKey(UIntPtr key, &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;string&lt;/font&gt;&lt;/span&gt; subkey, &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;uint&lt;/font&gt;&lt;/span&gt; reserved, &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;string&lt;/font&gt;&lt;/span&gt; className, &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;uint&lt;/font&gt;&lt;/span&gt; options, &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;uint&lt;/font&gt;&lt;/span&gt; desiredSam, &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;uint&lt;/font&gt;&lt;/span&gt; securityAttributes, &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;out&lt;/font&gt;&lt;/span&gt; IntPtr openedKey, &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;out&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;uint&lt;/font&gt;&lt;/span&gt; disposition);&lt;br /&gt;&lt;br /&gt;        &lt;span class=&quot;cb2&quot;&gt;&lt;font color=&quot;#008000&quot;&gt;//This does the actual hive to key mapping&lt;/font&gt;&lt;/span&gt;        [DllImport(&amp;quot;advapi32.dll&amp;quot;, EntryPoint=&amp;quot;RegOverridePredefKey&amp;quot;, CharSet=CharSet.Unicode, ExactSpelling=&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;true&lt;/font&gt;&lt;/span&gt;, SetLastError=&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;true&lt;/font&gt;&lt;/span&gt;)]&lt;br /&gt;        &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;internal&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;static&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;extern&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;int&lt;/font&gt;&lt;/span&gt; RegOverridePredefKey(UIntPtr key, IntPtr newKey);&lt;br /&gt;&lt;br /&gt;        &lt;span class=&quot;cb2&quot;&gt;&lt;font color=&quot;#008000&quot;&gt;//Like good programmers, we release our handles.&lt;/font&gt;&lt;/span&gt;        [DllImport(&amp;quot;advapi32.dll&amp;quot;, EntryPoint=&amp;quot;RegCloseKey&amp;quot;, CharSet=CharSet.Unicode, ExactSpelling=&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;true&lt;/font&gt;&lt;/span&gt;, SetLastError=&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;true&lt;/font&gt;&lt;/span&gt;)]&lt;br /&gt;        &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;internal&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;static&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;extern&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;int&lt;/font&gt;&lt;/span&gt; RegCloseKey(IntPtr key);&lt;br /&gt;        &lt;span class=&quot;cb2&quot;&gt;&lt;font color=&quot;#008000&quot;&gt;//Our interops are done :-)&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;        #endregion&lt;/font&gt;&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;cb2&quot;&gt;&lt;font color=&quot;#008000&quot;&gt;//Now we actually write wrapper functions to use the imported functions&lt;/font&gt;&lt;/span&gt;        &lt;span class=&quot;cb2&quot;&gt;&lt;font color=&quot;#008000&quot;&gt;//Wrapper for creating Registry Keys&lt;/font&gt;&lt;/span&gt;        &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;internal&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;static&lt;/font&gt;&lt;/span&gt; IntPtr OpenRegistryKey(UIntPtr key, &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;string&lt;/font&gt;&lt;/span&gt; path)&lt;br /&gt;        {&lt;br /&gt;            IntPtr newKey = IntPtr.Zero;&lt;br /&gt;            &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;uint&lt;/font&gt;&lt;/span&gt; disposition = 0;&lt;br /&gt;            &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;uint&lt;/font&gt;&lt;/span&gt; security = StandardRightsAll | GenericRead | GenericWrite | GenericExecute | GenericAll;&lt;br /&gt;            &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;int&lt;/font&gt;&lt;/span&gt; error = RegCreateKey(key, path, 0, &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;null&lt;/font&gt;&lt;/span&gt;, 0, security, 0, &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;out&lt;/font&gt;&lt;/span&gt; newKey, &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;out&lt;/font&gt;&lt;/span&gt; disposition);&lt;br /&gt;            &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;return&lt;/font&gt;&lt;/span&gt; newKey;&lt;br /&gt;        }&lt;br /&gt;        &lt;span class=&quot;cb2&quot;&gt;&lt;font color=&quot;#008000&quot;&gt;//Wrapper for the mapping&lt;/font&gt;&lt;/span&gt;        &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;internal&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;static&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;void&lt;/font&gt;&lt;/span&gt; OverrideRegistryKey(UIntPtr key, IntPtr newKey)&lt;br /&gt;        {&lt;br /&gt;            &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;int&lt;/font&gt;&lt;/span&gt; error = RegOverridePredefKey(key, newKey);&lt;br /&gt;        }&lt;br /&gt;        &lt;span class=&quot;cb2&quot;&gt;&lt;font color=&quot;#008000&quot;&gt;//Wrapper for freeing the handle&lt;/font&gt;&lt;/span&gt;        &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;internal&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;static&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;void&lt;/font&gt;&lt;/span&gt; CloseRegistryKey(IntPtr key)&lt;br /&gt;        {&lt;br /&gt;            &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;int&lt;/font&gt;&lt;/span&gt; error = RegCloseKey(key);&lt;br /&gt;        }&lt;br /&gt;    }&lt;/p&gt;&lt;p class=&quot;cl&quot;&gt;Now that we have the helper class with the static methods, we can define our main Console App class, which would use the functions in the helper class to register the assembly and steal the registry entries. Let us define the functions that Map and Map the registry hives. I had initialized the RegLocation to a string &amp;quot;Software\\Vagmi\\RegInterop\\&amp;quot;. So the extracted registry entries would be put in the HKLM hive within the specified path. Also not that I have mapped HKLM as the final mapping. Else all keys that are subsequently created would be created within our registry key.&lt;/p&gt;&lt;div class=&quot;cf&quot;&gt;&lt;p class=&quot;cl&quot;&gt;        &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;void&lt;/font&gt;&lt;/span&gt; MapRegHives()&lt;br /&gt;        {&lt;br /&gt;            MapRegHive(OverRideRegistry.HkeyClassesRoot,&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;this&lt;/font&gt;&lt;/span&gt;.RegLocation+&amp;quot;HKCR&amp;quot;);&lt;br /&gt;            MapRegHive(OverRideRegistry.HkeyCurrentUser,&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;this&lt;/font&gt;&lt;/span&gt;.RegLocation+&amp;quot;HKCU&amp;quot;);&lt;br /&gt;            MapRegHive(OverRideRegistry.HkeyUsers,&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;this&lt;/font&gt;&lt;/span&gt;.RegLocation+&amp;quot;HKU&amp;quot;);&lt;br /&gt;            MapRegHive(OverRideRegistry.HkeyLocalMachine,&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;this&lt;/font&gt;&lt;/span&gt;.RegLocation+&amp;quot;HKLM&amp;quot;);&lt;br /&gt;        }&lt;br /&gt;        &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;void&lt;/font&gt;&lt;/span&gt; MapRegHive(UIntPtr key, &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;string&lt;/font&gt;&lt;/span&gt; location)&lt;br /&gt;        {&lt;br /&gt;            Console.WriteLine(&amp;quot;Mapping &amp;quot; + key + &amp;quot;  to &amp;quot; + location);&lt;br /&gt;            IntPtr createdKey=IntPtr.Zero;&lt;br /&gt;            &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;try&lt;/font&gt;&lt;/span&gt;            {&lt;br /&gt;                createdKey=OverRideRegistry.OpenRegistryKey(OverRideRegistry.HkeyLocalMachine,location);&lt;br /&gt;                OverRideRegistry.OverrideRegistryKey(key,createdKey);&lt;br /&gt;            }&lt;br /&gt;            &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;catch&lt;/font&gt;&lt;/span&gt;(Exception e)&lt;br /&gt;            {&lt;br /&gt;                Console.WriteLine(&amp;quot;Caught exception: &amp;quot; + e.Message);&lt;br /&gt;            }&lt;br /&gt;            &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;finally&lt;/font&gt;&lt;/span&gt;            {&lt;br /&gt;                &lt;span class=&quot;cb2&quot;&gt;&lt;font color=&quot;#008000&quot;&gt;//close key like responsible programmers&lt;/font&gt;&lt;/span&gt;                OverRideRegistry.CloseRegistryKey(createdKey);&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        &lt;span class=&quot;cb2&quot;&gt;&lt;font color=&quot;#008000&quot;&gt;//Functions to unmap registry hives.&lt;/font&gt;&lt;/span&gt;        &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;void&lt;/font&gt;&lt;/span&gt; UnMapRegHives()&lt;br /&gt;        {&lt;br /&gt;            OverRideRegistry.OverrideRegistryKey(OverRideRegistry.HkeyClassesRoot,IntPtr.Zero);&lt;br /&gt;            OverRideRegistry.OverrideRegistryKey(OverRideRegistry.HkeyCurrentUser,IntPtr.Zero);&lt;br /&gt;            OverRideRegistry.OverrideRegistryKey(OverRideRegistry.HkeyLocalMachine,IntPtr.Zero);&lt;br /&gt;            OverRideRegistry.OverrideRegistryKey(OverRideRegistry.HkeyUsers,IntPtr.Zero);&lt;br /&gt;        }&lt;/p&gt;&lt;p class=&quot;cl&quot;&gt;I then parse two command line arguments one for the DLL and another for the REG file to export. I then pass these as constructors to my class, which calls these functions. &lt;/p&gt;&lt;div class=&quot;cf&quot;&gt;&lt;p class=&quot;cl&quot;&gt;        &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;public&lt;/font&gt;&lt;/span&gt; RegSpyCOMInterop(&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;string&lt;/font&gt;&lt;/span&gt; AssemblyPath, &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;string&lt;/font&gt;&lt;/span&gt; RegFile)&lt;br /&gt;        {&lt;br /&gt;            &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;try&lt;/font&gt;&lt;/span&gt;            {&lt;br /&gt;                Assembly a=Assembly.LoadFrom(AssemblyPath);&lt;br /&gt;                RegistrationServices regServices=&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;new&lt;/font&gt;&lt;/span&gt; RegistrationServices();&lt;br /&gt;                &lt;span class=&quot;cb2&quot;&gt;&lt;font color=&quot;#008000&quot;&gt;//map hives to registry keys&lt;/font&gt;&lt;/span&gt;                    MapRegHives();&lt;br /&gt;                    &lt;span class=&quot;cb2&quot;&gt;&lt;font color=&quot;#008000&quot;&gt;//Register assembly for COM interop&lt;/font&gt;&lt;/span&gt;                    regServices.RegisterAssembly(a,AssemblyRegistrationFlags.SetCodeBase);&lt;br /&gt;                    &lt;span class=&quot;cb2&quot;&gt;&lt;font color=&quot;#008000&quot;&gt;//Unmap hives&lt;/font&gt;&lt;/span&gt;                    UnMapRegHives();&lt;br /&gt;                WriteToRegFile(RegFile);&lt;br /&gt;            }&lt;br /&gt;            &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;catch&lt;/font&gt;&lt;/span&gt;(Exception e)&lt;br /&gt;            {&lt;br /&gt;                Console.WriteLine(&amp;quot;Caught Exception : &amp;quot; + e.Message);&lt;br /&gt;            }&lt;br /&gt;        }&lt;/p&gt;&lt;p class=&quot;cl&quot;&gt;The WriteToRegFile() function launches regedit and exports the hive that contains our keys. It then uses simple text replacement to change the values of the exported file to make the REG file functional.&lt;/p&gt;&lt;div class=&quot;cf&quot;&gt;&lt;p class=&quot;cl&quot;&gt;        &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;public&lt;/font&gt;&lt;/span&gt;&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;void&lt;/font&gt;&lt;/span&gt; WriteToRegFile(&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;string&lt;/font&gt;&lt;/span&gt; regfile)&lt;br /&gt;        {&lt;br /&gt;            RegistryKey r=Registry.LocalMachine.OpenSubKey(RegLocation,&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;false&lt;/font&gt;&lt;/span&gt;);&lt;br /&gt;            PathToDelete=r.Name + &amp;quot;\\&amp;quot;;&lt;br /&gt;            Process pr=&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;new&lt;/font&gt;&lt;/span&gt; Process();&lt;br /&gt;            pr.StartInfo.FileName=&amp;quot;regedit&amp;quot;;&lt;br /&gt;            pr.StartInfo.Arguments=&amp;quot; /e &amp;quot; + regfile + &amp;quot; &amp;quot; + r.Name;&lt;br /&gt;            pr.Start();&lt;br /&gt;            pr.WaitForExit();&lt;br /&gt;            &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;string&lt;/font&gt;&lt;/span&gt; line;&lt;br /&gt;            StreamReader reader=&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;new&lt;/font&gt;&lt;/span&gt; StreamReader(regfile);&lt;br /&gt;            StreamWriter writer=&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;new&lt;/font&gt;&lt;/span&gt; StreamWriter(&amp;quot;TempFile.txt&amp;quot;);&lt;br /&gt;            &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;while&lt;/font&gt;&lt;/span&gt;((line=reader.ReadLine())!=&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;null&lt;/font&gt;&lt;/span&gt;)&lt;br /&gt;            {&lt;br /&gt;                writer.WriteLine(processRegistryName(line));&lt;br /&gt;            }&lt;br /&gt;            reader.Close();&lt;br /&gt;            writer.Close();&lt;br /&gt;            File.Copy(&amp;quot;TempFile.txt&amp;quot;,regfile,&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;true&lt;/font&gt;&lt;/span&gt;);&lt;br /&gt;            File.Delete(&amp;quot;TempFile.txt&amp;quot;);&lt;br /&gt;            r.Flush();&lt;br /&gt;            r.Close();&lt;br /&gt;        }&lt;/p&gt;&lt;p class=&quot;cl&quot;&gt;        &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;public&lt;/font&gt;&lt;/span&gt; String processRegistryName(&lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;string&lt;/font&gt;&lt;/span&gt; regname)&lt;br /&gt;        {&lt;br /&gt;            &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;string&lt;/font&gt;&lt;/span&gt; newRegName=&amp;quot;&amp;quot;;&lt;br /&gt;            newRegName=regname.Replace(PathToDelete,&amp;quot;&amp;quot;);&lt;br /&gt;            newRegName=newRegName.Replace(&amp;quot;[&amp;quot; + PathToDelete.Substring(0,PathToDelete.Length-1) + &amp;quot;]&amp;quot;,&amp;quot;&amp;quot;);&lt;br /&gt;            newRegName=newRegName.Replace(&amp;quot;HKCR&amp;quot;,&amp;quot;HKEY_CLASS_ROOT&amp;quot;);&lt;br /&gt;            newRegName=newRegName.Replace(&amp;quot;HKCU&amp;quot;,&amp;quot;HKEY_CURRENT_USER&amp;quot;);&lt;br /&gt;            newRegName=newRegName.Replace(&amp;quot;HKLM&amp;quot;,&amp;quot;HKEY_LOCAL_MACHINE&amp;quot;);&lt;br /&gt;            newRegName=newRegName.Replace(&amp;quot;HKU&amp;quot;,&amp;quot;HKEY_USERS&amp;quot;);&lt;br /&gt;            &lt;span class=&quot;cb1&quot;&gt;&lt;font color=&quot;#0000ff&quot;&gt;return&lt;/font&gt;&lt;/span&gt; newRegName;&lt;br /&gt;        }&lt;/p&gt;&lt;p class=&quot;cl&quot;&gt;There you have it. A command line utility to extract COM Interop Registry entries. Hope this answered some of your queries regarding registration without affecting the target system. You can find the entire source code at &lt;a href=&quot;http://www.geekswithblogs.net/vagmi.mudumbai/articles/16581.aspx&quot;&gt;http://www.geekswithblogs.net/vagmi.mudumbai/articles/16581.aspx&lt;/a&gt;.&lt;/p&gt;&lt;/div&gt;&lt;!--EndFragment--&gt;&lt;/div&gt;&lt;!--EndFragment--&gt;&lt;/div&gt;&lt;/div&gt;&lt;img height=&quot;1&quot; src=&quot;http://geekswithblogs.net/vagmi.mudumbai/aggbug/16583.aspx&quot; width=&quot;1&quot; alt=&quot;&quot;  /&gt;  
    </content:encoded>

    <pubDate>Wed, 01 Dec 2004 21:21:00 +0100</pubDate>
    <guid isPermaLink="false">http://vagmi.supersized.org/archives/13-guid.html</guid>
    
</item>
<item>
    <title>Microsoft's Whitepaper on Patch Sequencing</title>
    <link>http://vagmi.supersized.org/archives/14-Microsofts-Whitepaper-on-Patch-Sequencing.html</link>
            <category>Setup</category>
    
    <comments>http://vagmi.supersized.org/archives/14-Microsofts-Whitepaper-on-Patch-Sequencing.html#comments</comments>
    <wfw:comment>http://vagmi.supersized.org/wfwcomment.php?cid=14</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://vagmi.supersized.org/rss.php?version=2.0&amp;type=comments&amp;cid=14</wfw:commentRss>
    

    <author>nospam@example.com (Vagmi)</author>
    <content:encoded>
    &lt;p&gt;While browsing, I came across this excellent whitepaper on MSI 3.0 Patch Sequencing. &lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://www.microsoft.com/downloads/details.aspx?FamilyId=AD7AC91E-2493-4549-AE6F-BF5E007C12A3&amp;amp;displaylang=en&quot;&gt;http://www.microsoft.com/downloads/details.aspx?FamilyId=AD7AC91E-2493-4549-AE6F-BF5E007C12A3&amp;amp;displaylang=en&lt;/a&gt;&lt;/p&gt;&lt;img height=&quot;1&quot; src=&quot;http://geekswithblogs.net/vagmi.mudumbai/aggbug/15795.aspx&quot; width=&quot;1&quot; alt=&quot;&quot;  /&gt;  
    </content:encoded>

    <pubDate>Wed, 24 Nov 2004 11:54:00 +0100</pubDate>
    <guid isPermaLink="false">http://vagmi.supersized.org/archives/14-guid.html</guid>
    
</item>

</channel>
</rss>
