<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://gormanonline.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Lifestyle of the MSIdle</title><link>http://gormanonline.com/blogs/msidle/default.aspx</link><description>Join me on my journey to become one of the &amp;quot;MSIdle&amp;quot; -- those elite geeks who code an MSI patch faster than a speeding bullet, can write custom actions in a single bound, and make the world of deployment safe for the rest of us.</description><dc:language>en</dc:language><generator>CommunityServer 2007.1 (Build: 20917.1142)</generator><item><title>How much Virus scanning is enough?</title><link>http://gormanonline.com/blogs/msidle/archive/2009/05/07/how-much-virus-scanning-is-enough.aspx</link><pubDate>Thu, 07 May 2009 19:29:00 GMT</pubDate><guid isPermaLink="false">45bc9128-c309-4a47-b6b1-7705e21af830:668</guid><dc:creator>SusanGorman</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://gormanonline.com/blogs/msidle/rsscomments.aspx?PostID=668</wfw:commentRss><comments>http://gormanonline.com/blogs/msidle/archive/2009/05/07/how-much-virus-scanning-is-enough.aspx#comments</comments><description>&lt;p&gt;As a person responsible for getting software builds from Development out into the &amp;#39;real world&amp;#39;, one of my reponsibilities is to ensure that the software we let out the door is malware-free.Unfortunately, there are a number of points along the development path when the code is potentially vulnerable. When it comes time to build the software, I see a three-part approach to producing a clean software product &lt;/p&gt;&lt;ul&gt;&lt;li&gt;The INPUTS to the build must be clean.&lt;/li&gt;&lt;li&gt;The platform on which the build is done must be clean.&lt;/li&gt;&lt;li&gt;The OUTPUT from the build must be clean. &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Some of this might seem paranoid or redundant, but then again anything may be worth avoiding a virus in your code that gets sent to customers! A few tactics aimed at having a clean Input, Platform and Output are: &lt;br /&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Virus scan (deep scan) the build machine on a daily basis. Rotate virus scanning products and/or scan with more than one product. Ensure that Windows updates are applied on a regular basis. (weekly). And in case of trouble, BACKUP your build machine to reduce down time. These things keep the platform clean. &lt;/li&gt;&lt;li&gt;During the build process, run a virus scan after you&amp;#39;ve pulled all the needed files to the local box and before you actually compile anything. If something malicious got into the source code repository, this step will catch it.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The build output from my builds is stored on a separate machine from the build machine itself. Before the build output is copied out to the build storage, scan the build output. This ensure that the build output is clean. &lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Now there&amp;#39;s one last area to consider.&lt;/p&gt;&lt;p&gt;My build storage location is pretty locked down -- read-only for most users. But even so, just because the build output was clean when it got put on the storage server, that doesn&amp;#39;t guarantee that it&amp;#39;s still clean 3 weeks later when we need to cut another CD of the product or want to ship a copy of a build off to a 3rd party vendor for evaluation. So.. before a build is sent outside the building for any reason, it gets scanned again - just to ensure that nothing untoward happened to the code while it sat around on the build storage server.&lt;/p&gt;&lt;p&gt;&amp;nbsp;All of this is in addition to the standard precautions that the IT department should have in place throughout the company.&lt;/p&gt;&lt;p&gt;&amp;nbsp;Good luck! &lt;br /&gt;&lt;/p&gt;&lt;img src="http://gormanonline.com/aggbug.aspx?PostID=668" width="1" height="1"&gt;</description><category domain="http://gormanonline.com/blogs/msidle/archive/tags/Best+Practices/default.aspx">Best Practices</category><category domain="http://gormanonline.com/blogs/msidle/archive/tags/Build+Management/default.aspx">Build Management</category><category domain="http://gormanonline.com/blogs/msidle/archive/tags/Virus+Protection/default.aspx">Virus Protection</category></item><item><title>CVS error - temp directory permission denied</title><link>http://gormanonline.com/blogs/msidle/archive/2009/04/18/cvs-error-temp-directory-permission-denied.aspx</link><pubDate>Sat, 18 Apr 2009 19:48:00 GMT</pubDate><guid isPermaLink="false">45bc9128-c309-4a47-b6b1-7705e21af830:665</guid><dc:creator>SusanGorman</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://gormanonline.com/blogs/msidle/rsscomments.aspx?PostID=665</wfw:commentRss><comments>http://gormanonline.com/blogs/msidle/archive/2009/04/18/cvs-error-temp-directory-permission-denied.aspx#comments</comments><description>&lt;p&gt;I blogged about this CVS error a while ago. &lt;a href="http://gormanonline.com/blogs/msidle/archive/2008/10/02/what-causes-automated-builds-to-fail.aspx"&gt;http://gormanonline.com/blogs/msidle/archive/2008/10/02/what-causes-automated-builds-to-fail.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Bottom line is - CVS sometimes does not clean up temp directory folders that it creates, then at a later time, it attempts to re-use that same temp directory folder name and burps because that folder already exists. To work around this problem, my IT department made me a sweet little script that runs at 3AM every day and deletes any temp folders out of the CVS temp directory.&lt;/p&gt;
&lt;p&gt;This helped, for a while. But every once in a while we get a new recurrence of this temp directory problem.&lt;/p&gt;
&lt;p&gt;I know! I know! You get what you pay for - Switch to a different source control system, etc.&lt;/p&gt;
&lt;p&gt;Yeah, well.. money is tight and CVS is free. I&amp;#39;m sure a number of us are stuck with the same mandate of having to make do with what we&amp;#39;ve got. &lt;img src="http://gormanonline.com/emoticons/emotion-4.gif" alt="Stick out tongue" /&gt;&lt;/p&gt;
&lt;p&gt;Our newest theory is that the script that cleans up the temp folders isn&amp;#39;t always able to delete folders because sometimes CVS leaves a lock open. &lt;/p&gt;
&lt;p&gt;Thus our newest solution is that we are going to shut down the CVS service, *then* run the cleanup script, then start back up the CVS service, every night at 3AM. Hopefully this will help!&lt;/p&gt;
&lt;p&gt;&amp;nbsp;Meanwhile -- if anybody out there discovers what the actual cause of this situation is, please pass it on.&lt;/p&gt;
&lt;p&gt;*Update* The IT department has looked at the temp directory folders that are getting left behind and thinks there is a pattern. It looks like most of the folders are being created under the username of a set of users that are located on a remote site, who are probably using an older version of TortoiseCVS. We are having all those users upgrade to the newest version of Tortoise and we&amp;#39;ll see if that makes any difference.&lt;/p&gt;&lt;img src="http://gormanonline.com/aggbug.aspx?PostID=665" width="1" height="1"&gt;</description><category domain="http://gormanonline.com/blogs/msidle/archive/tags/CVS/default.aspx">CVS</category><category domain="http://gormanonline.com/blogs/msidle/archive/tags/Build+Management/default.aspx">Build Management</category></item><item><title>Installing SQL Express - error 110 - system cannot open the device or file specified</title><link>http://gormanonline.com/blogs/msidle/archive/2009/04/17/installing-sql-express-error-110-system-cannot-open-the-device-or-file-specified.aspx</link><pubDate>Fri, 17 Apr 2009 18:25:00 GMT</pubDate><guid isPermaLink="false">45bc9128-c309-4a47-b6b1-7705e21af830:664</guid><dc:creator>SusanGorman</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://gormanonline.com/blogs/msidle/rsscomments.aspx?PostID=664</wfw:commentRss><comments>http://gormanonline.com/blogs/msidle/archive/2009/04/17/installing-sql-express-error-110-system-cannot-open-the-device-or-file-specified.aspx#comments</comments><description>&lt;p&gt;Here&amp;#39;s a link to another install developer that ran into much the same problem as I did with the SQL Express 2005 installation.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.darinhiggins.com/2007/10/24/NestingTheSQLExpress2005Install.aspx" target="_blank"&gt;http://www.darinhiggins.com/2007/10/24/NestingTheSQLExpress2005Install.aspx&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Bottom line&lt;/b&gt; - when trying to launch Microsoft&amp;#39;s redistributable SQLEXPR32.exe you are likely to see an MSI error 110 &amp;quot;the system cannot open the device or file specified&amp;quot;.&lt;/p&gt;&lt;p&gt;&lt;b&gt;The Cause&lt;/b&gt; - for some bizarre reason this exe unpacks itself into a directory off the c drive that the LocalService doesn&amp;#39;t have permissions to access.&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;b&gt;Solution &lt;/b&gt;- Darin resorted to a little bit different method than I did, so I&amp;#39;ll give you my alternative. &lt;/p&gt;&lt;p&gt;I launched SQLEXPR32 on my local box, then while it was running, I went out to the directory in which it had unpacked itself (it&amp;#39;s c:\somelongguid on my box) and copied off the entire contents of that folder. (Now you can cancel out of the SQL install)&lt;/p&gt;&lt;p&gt;Then I used winrar to re-zip that directory and used the winrar options to create a self-extracting EXE that automatically launches the setup.exe that is included in the zip. &lt;/p&gt;&lt;p&gt;So now in my installer, during the execute sequence, I can execute my new self-extracting EXE and on the command line send it all the same switches that I want to use with SQLEXPR32.exe. &lt;/p&gt;&lt;p&gt;This seems to work great so far. &lt;br /&gt;&lt;/p&gt;&lt;img src="http://gormanonline.com/aggbug.aspx?PostID=664" width="1" height="1"&gt;</description><category domain="http://gormanonline.com/blogs/msidle/archive/tags/custom+actions/default.aspx">custom actions</category><category domain="http://gormanonline.com/blogs/msidle/archive/tags/InstallShield/default.aspx">InstallShield</category><category domain="http://gormanonline.com/blogs/msidle/archive/tags/SQL+Express/default.aspx">SQL Express</category></item><item><title>Installing .NET and SQL Server Express</title><link>http://gormanonline.com/blogs/msidle/archive/2009/04/17/installing-net-and-sql-server-express.aspx</link><pubDate>Fri, 17 Apr 2009 15:04:00 GMT</pubDate><guid isPermaLink="false">45bc9128-c309-4a47-b6b1-7705e21af830:663</guid><dc:creator>SusanGorman</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://gormanonline.com/blogs/msidle/rsscomments.aspx?PostID=663</wfw:commentRss><comments>http://gormanonline.com/blogs/msidle/archive/2009/04/17/installing-net-and-sql-server-express.aspx#comments</comments><description>&lt;p&gt;Yee Haw! Now I get the excitement of trying to install .NET Framework 3.5 SP1 and SQL Server 2005 Express as part of an installation. &lt;/p&gt;&lt;p&gt;Big deal, you say. There&amp;#39;s prerequisites already created for these things - so what&amp;#39;s the problem?&lt;/p&gt;&lt;p&gt;Well..... Couple of things.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;First, the prerequisite for .NET Framework 3.5 SP1 seems to act a little oddly -- it *always* requires a reboot at the end of the .NET installation and doesn&amp;#39;t seem to apply any of the other options that *should* let you delay rebooting until the end of the whole installation. This creates a startling user experience.&lt;/p&gt;&lt;p&gt;It looks like this:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Add a prerequisite for &amp;quot;Microsoft .NET Framework 3.5 SP1 (Web Download)&amp;quot;. Right click that prereq and Edit Prerequisite.&lt;/li&gt;&lt;li&gt;Click the Application to Run tab. Notice that the command line already includes a /norestart option. According to Microsoft - using this option tells the .NET installation not to restart the computer after
installation completes. The redistributable installer returns
ERROR_SUCCESS_REBOOT_REQUIRED (3010) if a reboot is required.&lt;/li&gt;&lt;li&gt;In the bottom field noticewhat values are listed as reboot-required return codes.Notice it includes 3010.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Now click the Behavior tab. Look at the options for &amp;quot;If the prerequisite appears to need a reboot&amp;quot;. By default it is set to Exit and resume on rebooot.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Here&amp;#39;s a clip from the &lt;a href="http://kb.acresso.com/selfservice/microsites/search.do?cmd=displayKC&amp;amp;docType=kc&amp;amp;externalId=installshield15helplib-SetupPrereqEditorRebootBehavhtm&amp;amp;sliceId=&amp;amp;docTypeID=DT_MACROVISIONHELPNET_1_1&amp;amp;dialogID=52388753&amp;amp;stateId=0%200%2052390106"&gt;InstallShield 2009 Prequisite Editor Behavior Tab Help Article&lt;/a&gt; &lt;/p&gt;&lt;blockquote&gt;Specify the behavior that should occur if the InstallShield prerequisite requires that a target machine be restarted.
&lt;div class="pSmartList1"&gt;&lt;ul class="pSmartList1"&gt;&lt;a class="" title="wp1025814" name="wp1025814"&gt;&lt;/a&gt; &lt;div class="pSmartList1"&gt;&lt;li&gt;&lt;span style="color:Black;font-family:Verdana,Helvetica,Arial,MS Sans Serif;font-size:8pt;font-style:normal;font-variant:normal;font-weight:bold;text-decoration:none;text-transform:none;"&gt;Exit and resume on reboot&lt;/span&gt;—To
end the InstallShield prerequisite installation, allow the
InstallShield prerequisite to restart the target machine, and then
continue the installation, select this option.&lt;/li&gt;&lt;/div&gt;&lt;a class="" title="wp1027942" name="wp1027942"&gt;&lt;/a&gt; &lt;div class="pSmartList1"&gt;&lt;li&gt;&lt;span style="color:Black;font-family:Verdana,Helvetica,Arial,MS Sans Serif;font-size:8pt;font-style:normal;font-variant:normal;font-weight:bold;text-decoration:none;text-transform:none;"&gt;Note it, fail to resume if the machine is rebooted, and reboot after the installation&lt;/span&gt;—To
note that the target machine should be restarted if it is required, to
schedule the restart for the end of the main installation, but to exit
if the target machine restarts after the InstallShield prerequisite
installation, select this option. Thus, if it appears that a restart is
required but you want to postpone it until the end of the main
installation (or until a subsequent InstallShield prerequisite triggers
a restart), select this option. At run time, the value of the Windows Installer property &lt;span style="color:Black;font-family:Verdana,Helvetica,Arial,MS Sans Serif;font-size:8pt;font-style:normal;font-variant:normal;font-weight:bold;text-decoration:none;text-transform:none;"&gt;ISSCHEDULEREBOOT&lt;/span&gt; is set to 1 in the main installation when a restart is still pending.
&lt;/li&gt;&lt;/div&gt;&lt;a class="" title="wp1025815" name="wp1025815"&gt;&lt;/a&gt; &lt;div class="pSmartList1"&gt;&lt;li&gt;&lt;span style="color:Black;font-family:Verdana,Helvetica,Arial,MS Sans Serif;font-size:8pt;font-style:normal;font-variant:normal;font-weight:bold;text-decoration:none;text-transform:none;"&gt;Ignore it, and fail to resume if machine is rebooted&lt;/span&gt;—To
continue the installation but end it if the target machine is
restarted, select this option. Thus, if it appears that a restart is
required but you want to try to skip it, select this option.&lt;/li&gt;&lt;/div&gt;&lt;a class="" title="wp1025798" name="wp1025798"&gt;&lt;/a&gt; &lt;div class="pSmartList1"&gt;&lt;li&gt;&lt;span style="color:Black;font-family:Verdana,Helvetica,Arial,MS Sans Serif;font-size:8pt;font-style:normal;font-variant:normal;font-weight:bold;text-decoration:none;text-transform:none;"&gt;Prompt the user only if no reboot is detected, but always reboot the machine and resume on reboot&lt;/span&gt;—To
prompt the end user to restart the target machine only if it appears
that the target machine does not need to be restarted, select this
option. The target machine is restarted if the end user agrees to allow
it, and then the installation continues.&lt;/li&gt;&lt;/div&gt;&lt;a class="" title="wp1025799" name="wp1025799"&gt;&lt;/a&gt; &lt;div class="pSmartList1"&gt;&lt;li&gt;&lt;span style="color:Black;font-family:Verdana,Helvetica,Arial,MS Sans Serif;font-size:8pt;font-style:normal;font-variant:normal;font-weight:bold;text-decoration:none;text-transform:none;"&gt;Prompt the user to reboot the machine even if nothing is detected, and resume on reboot&lt;/span&gt;—To
prompt the end user to restart the target machine even if it appears
that the target machine does not need to be restarted, select this
option. The target machine is restarted if the end user agrees to allow
it, and then the installation continues.&lt;/li&gt;&lt;/div&gt;&lt;a class="" title="wp1025532" name="wp1025532"&gt;&lt;/a&gt; &lt;div class="pSmartList1"&gt;&lt;li&gt;&lt;span style="color:Black;font-family:Verdana,Helvetica,Arial,MS Sans Serif;font-size:8pt;font-style:normal;font-variant:normal;font-weight:bold;text-decoration:none;text-transform:none;"&gt;Reboot the machine and resume on reboot&lt;/span&gt;—To restart the target machine and then continue the installation, select this option.&lt;/li&gt;&lt;/div&gt;&lt;/ul&gt;&lt;/div&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;With the prereq set up this way the behavior I get is that at the end of the .NET installation a dialog displays&amp;nbsp; &lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;a href="http://gormanonline.com/blogs/msidle/rebootrequired.bmp"&gt;&lt;img src="http://gormanonline.com/blogs/msidle/rebootrequired.bmp" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;If you click yes - it ends the prereq installation and reboots, as expected.&lt;/p&gt;&lt;p&gt;if you click no - it ends the prereq installation. And that&amp;#39;s it! No further communication to the user - no warning that the installation is unfinished. It just... stops. Now having said that, when the user does finally reboot, the installation starts back up automatically - which also is startling to the user. &lt;/p&gt;&lt;p&gt;We found this behavior to be a startling and undesirable user experience. So I wanted to change it so that we defer the reboot until after the entire installation is finished.&lt;/p&gt;&lt;p&gt;Looking at the options above, I changed the option to &lt;span style="color:Black;font-family:Verdana,Helvetica,Arial,MS Sans Serif;font-size:8pt;font-style:normal;font-variant:normal;font-weight:bold;text-decoration:none;text-transform:none;"&gt;Note it, fail to resume if the machine is rebooted, and reboot after the installation.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Unfortunately, this doesn&amp;#39;t work as advertised. Using that option, I get exactly the same behavior: At the end of the .NET install, the user sees the above dialog and unless they say Yes to reboot now, the installation just ends.&amp;nbsp;&lt;/p&gt;&lt;p&gt;At this point I tried each one of the possible options and found that they ALL seem to produce the same behavior with this .NET installation.&lt;/p&gt;&lt;p&gt;YUK! &lt;/p&gt;&lt;br /&gt;&lt;img src="http://gormanonline.com/aggbug.aspx?PostID=663" width="1" height="1"&gt;</description><category domain="http://gormanonline.com/blogs/msidle/archive/tags/InstallShield/default.aspx">InstallShield</category><category domain="http://gormanonline.com/blogs/msidle/archive/tags/MSI/default.aspx">MSI</category><category domain="http://gormanonline.com/blogs/msidle/archive/tags/Prerequisites/default.aspx">Prerequisites</category><category domain="http://gormanonline.com/blogs/msidle/archive/tags/.NET/default.aspx">.NET</category></item><item><title>Followup: Need ideas for setting up build process</title><link>http://gormanonline.com/blogs/msidle/archive/2009/01/13/followup-need-ideas-for-setting-up-build-process.aspx</link><pubDate>Tue, 13 Jan 2009 20:45:00 GMT</pubDate><guid isPermaLink="false">45bc9128-c309-4a47-b6b1-7705e21af830:662</guid><dc:creator>SusanGorman</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://gormanonline.com/blogs/msidle/rsscomments.aspx?PostID=662</wfw:commentRss><comments>http://gormanonline.com/blogs/msidle/archive/2009/01/13/followup-need-ideas-for-setting-up-build-process.aspx#comments</comments><description>&lt;p&gt;So.. this whole project became a moot point.&lt;/p&gt;
&lt;p&gt;We upgraded to InstallShield 2009, and in this version I found a variable &amp;quot;SETUPEXENAME&amp;quot; which contains the name of the setup.exe that launches the installation.&lt;/p&gt;
&lt;p&gt;We decided to use this value, at install time, to set a registry key. This registry key then drives the versioning features. So.. if the file is named &amp;quot;VERSION for WILMA.exe&amp;quot;, then we turn on the features for Wilma, and if it is named &amp;quot;VERSION for BOB.exe&amp;quot; then the code turns on the features for Bob.&lt;/p&gt;
&lt;p&gt;I know this is subject to user modification because the user could rename the EXE very easily, but for our purposes, this isn&amp;#39;t a big issue.&lt;/p&gt;
&lt;p&gt;NOTE: The variable DISK1SETUPEXE is &amp;quot;supposed&amp;quot; to return the same thing as SETUPEXENAME, but I found that in InstallShield 12, this variable just didn&amp;#39;t work. It was always empty. So upgrading to IS 2009 gave me access to a value that DID work (plus I needed to upgrade anyway.) Another option that I considered was reading the LauncherName value out of the setup.ini. I hoped that LauncherName would be dynamically updated when installation runs -- but is it Not. Which means that LauncherName will hold whatever the *original* setup EXE name was, in case that is useful to you.&lt;/p&gt;
&lt;p&gt;Bottom line -- we needed a way to make the installation do different things without having to A) build a new version of the installer or B) requiring the user to have to pass switches on the command line. This little solution of using the setup.exe name solved it.&lt;/p&gt;&lt;img src="http://gormanonline.com/aggbug.aspx?PostID=662" width="1" height="1"&gt;</description><category domain="http://gormanonline.com/blogs/msidle/archive/tags/InstallShield/default.aspx">InstallShield</category><category domain="http://gormanonline.com/blogs/msidle/archive/tags/InstallShield+Automation/default.aspx">InstallShield Automation</category><category domain="http://gormanonline.com/blogs/msidle/archive/tags/Installer+Fundamentals/default.aspx">Installer Fundamentals</category><category domain="http://gormanonline.com/blogs/msidle/archive/tags/InstallScript/default.aspx">InstallScript</category><category domain="http://gormanonline.com/blogs/msidle/archive/tags/Build+Management/default.aspx">Build Management</category></item><item><title>Need ideas for setting up build process</title><link>http://gormanonline.com/blogs/msidle/archive/2008/12/29/need-ideas-for-setting-up-build-process.aspx</link><pubDate>Mon, 29 Dec 2008 19:26:00 GMT</pubDate><guid isPermaLink="false">45bc9128-c309-4a47-b6b1-7705e21af830:661</guid><dc:creator>SusanGorman</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://gormanonline.com/blogs/msidle/rsscomments.aspx?PostID=661</wfw:commentRss><comments>http://gormanonline.com/blogs/msidle/archive/2008/12/29/need-ideas-for-setting-up-build-process.aspx#comments</comments><description>&lt;p&gt;I have my build process divided up into the building of the binaries (as one CruiseControl project) and the packaging of the binaries into deployable packages (MSI installations) as a separate project. &lt;/p&gt;
&lt;p&gt;This is valuable for a couple of reasons, but the main thing is that we can build the binaries once, then package those same binaries in several different ways without having to rebuild the binaries each time.&lt;/p&gt;
&lt;p&gt;So, in CruiseControl the build number is determined by the build of the binaries. This is stored in the state file for the project which builds the binaries. Example, build 2500. The results of the build ( a set of binaries) are stored on the network under the build number (a folder named 2500).&lt;/p&gt;
&lt;p&gt;The packaging process uses the build number from the build of the binaries (it looks in the state file for the binaries build and grabs the build number from there) and uses that as its own build number. It also uses that build number to generate the path to the binaries so that it knows where to get them from in order to package them up.&lt;/p&gt;
&lt;p&gt;This all works great. Now I have&amp;nbsp;a new feature request...&lt;/p&gt;
&lt;p&gt;At times we need to RE-package an older build.&lt;/p&gt;
&lt;p&gt;Say that the most recent build was 2550, but we have need to go back and repackage 2500. Currently, I have to do this little jury rig to make that work:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;div&gt;shut down the CruseControl service&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;manually edit the state file for the binaries and change the last successful build number to 2500&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;restart CruiseControl&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;Kick off the build of the packaging process (it builds 2500, as desired)&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;When the build is done, shut down CruiseControl&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;manually set the state file for binaries back to the correct last build number of 2550&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;restart CruiseControl&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;This is inefficient, at best.&lt;/p&gt;
&lt;p&gt;I&amp;#39;m looking for a way to restructure the CruiseControl projects so that I can give the packaging process a different build number to use without having to shut down CruiseControl and preferably without having to touch the true build number of the binaries project either.&lt;/p&gt;
&lt;p&gt;Anybody have any suggestions?&lt;/p&gt;
&lt;p&gt;I&amp;#39;m currently using CruiseControl version 1.2.1.7 (ccservice.exe) and the projects are built using MSBuild.&lt;/p&gt;&lt;img src="http://gormanonline.com/aggbug.aspx?PostID=661" width="1" height="1"&gt;</description><category domain="http://gormanonline.com/blogs/msidle/archive/tags/CruiseControl.NET/default.aspx">CruiseControl.NET</category><category domain="http://gormanonline.com/blogs/msidle/archive/tags/Build+Management/default.aspx">Build Management</category></item><item><title>What causes automated builds to fail? - follow up</title><link>http://gormanonline.com/blogs/msidle/archive/2008/11/12/what-causes-automated-builds-to-fail-follow-up.aspx</link><pubDate>Wed, 12 Nov 2008 19:41:00 GMT</pubDate><guid isPermaLink="false">45bc9128-c309-4a47-b6b1-7705e21af830:660</guid><dc:creator>SusanGorman</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://gormanonline.com/blogs/msidle/rsscomments.aspx?PostID=660</wfw:commentRss><comments>http://gormanonline.com/blogs/msidle/archive/2008/11/12/what-causes-automated-builds-to-fail-follow-up.aspx#comments</comments><description>&lt;p&gt;I had IT check the CVS server for any error event in the event log and we found that there were disk I/O errors that often occurred right around the same time as some (all?) of my mysterious CVS errors. IT dropped in some new hardware, but that still hasn&amp;#39;t reduced the errors.&lt;/p&gt;
&lt;p&gt;Looking in the event viewer, the errors are&amp;nbsp;event (type)&amp;nbsp;15, category of none, and source is &amp;quot;disk&amp;quot;.&lt;/p&gt;
&lt;p&gt;The errors happen in 3 second groups...like from 11:21:08 through 11:21:10 there will be about 9 of these errors, a few each second.&lt;/p&gt;
&lt;p&gt;Our current theory is that it&amp;#39;s some sort of throttling issue where the sheer bulk of activity involved in doing the CVS update and CVS Labelling is just too much for our system. No real idea of a solution to fix it yet, but... there ya go.&lt;/p&gt;
&lt;p&gt;We also modified our build schedule so that builds are not occurring at the same time as the daily backups. Again this has improved things to some degree. Another line of attack on that problem is doing some Spring Cleaning on our development servers to reduce the amount of items to be backed up. It&amp;#39;s easy to consider disk space as &amp;#39;cheap&amp;#39; -- and it is -- but there is still overhead to having a lot of disk space in use. So.. it&amp;#39;s wise to go ahead and spend some time cleaning up the servers and doing the basics: delete the obsolete, archive the historical but no longer active data off to off-line storage, trash the &amp;#39;let me just store this here temporarily&amp;#39; stuff, etc.&lt;/p&gt;
&lt;p&gt;The roles of IT and Build engineers sometimes overlap, so do whatever you need to to maintain a good relationship with the hardcord IT guys. Me, I make it a point to find out what their favorite food is and bring them a treat every couple months. &lt;img src="http://gormanonline.com/emoticons/emotion-22.gif" alt="Beer" /&gt;&lt;/p&gt;&lt;img src="http://gormanonline.com/aggbug.aspx?PostID=660" width="1" height="1"&gt;</description><category domain="http://gormanonline.com/blogs/msidle/archive/tags/Best+Practices/default.aspx">Best Practices</category><category domain="http://gormanonline.com/blogs/msidle/archive/tags/CVS/default.aspx">CVS</category><category domain="http://gormanonline.com/blogs/msidle/archive/tags/Build+Management/default.aspx">Build Management</category></item><item><title>Learning to build on Linux and FreeBSD</title><link>http://gormanonline.com/blogs/msidle/archive/2008/11/12/learning-to-build-on-linux-and-freebsd.aspx</link><pubDate>Wed, 12 Nov 2008 19:34:00 GMT</pubDate><guid isPermaLink="false">45bc9128-c309-4a47-b6b1-7705e21af830:659</guid><dc:creator>SusanGorman</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://gormanonline.com/blogs/msidle/rsscomments.aspx?PostID=659</wfw:commentRss><comments>http://gormanonline.com/blogs/msidle/archive/2008/11/12/learning-to-build-on-linux-and-freebsd.aspx#comments</comments><description>&lt;p&gt;Here&amp;#39;s a fun new project! &lt;/p&gt;
&lt;p&gt;My current build process uses CruiseControl on a (windows) machine to kick off an nant or msbuild build script that also runs on that same windows machine.&lt;/p&gt;
&lt;p&gt;For one of my projects I&amp;#39;ve just been informed that we are branching out to other platforms.&lt;/p&gt;
&lt;p&gt;The project is being ported to both Linux and FreeBSD. I know very little to nothing about either of these platforms. Yee haw! &lt;img src="http://gormanonline.com/emoticons/emotion-7.gif" alt="Tongue Tied" /&gt;&lt;/p&gt;
&lt;p&gt;My first thought is that I&amp;#39;ll use the same CruiseControl on a windows machine as the &amp;#39;master&amp;#39; control on the build process, and have that kick off a win32 build on a windows build machine, and remotely kick off a linux build on a linux machine, etc. In this way we could have a single control point from which all flavors of the same build number could be produced. &lt;/p&gt;
&lt;p&gt;I have no idea if this is doable, but... that&amp;#39;s my starting thought.&lt;/p&gt;
&lt;p&gt;First things first -- I&amp;#39;ve asked for a VM (virtual machine) of a linux machine so that I can start the research process on linux.&lt;/p&gt;&lt;img src="http://gormanonline.com/aggbug.aspx?PostID=659" width="1" height="1"&gt;</description><category domain="http://gormanonline.com/blogs/msidle/archive/tags/nAnt/default.aspx">nAnt</category><category domain="http://gormanonline.com/blogs/msidle/archive/tags/CruiseControl.NET/default.aspx">CruiseControl.NET</category><category domain="http://gormanonline.com/blogs/msidle/archive/tags/Build+Management/default.aspx">Build Management</category><category domain="http://gormanonline.com/blogs/msidle/archive/tags/Linux/default.aspx">Linux</category><category domain="http://gormanonline.com/blogs/msidle/archive/tags/FreeBSD/default.aspx">FreeBSD</category></item><item><title>What causes automated builds to fail?</title><link>http://gormanonline.com/blogs/msidle/archive/2008/10/02/what-causes-automated-builds-to-fail.aspx</link><pubDate>Thu, 02 Oct 2008 13:52:00 GMT</pubDate><guid isPermaLink="false">45bc9128-c309-4a47-b6b1-7705e21af830:658</guid><dc:creator>SusanGorman</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://gormanonline.com/blogs/msidle/rsscomments.aspx?PostID=658</wfw:commentRss><comments>http://gormanonline.com/blogs/msidle/archive/2008/10/02/what-causes-automated-builds-to-fail.aspx#comments</comments><description>&lt;p&gt;In the past 8-10 weeks I&amp;#39;ve had a nightmare trying to get a reliable build process. Here&amp;#39;s the numbers of what&amp;#39;s causing the build to fail *other* than normal coding errors:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div class="MsoNormal"&gt;&lt;font face="Arial" size="2"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;30 failures due to CVS temp directory problems&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div class="MsoNormal"&gt;&lt;font face="Arial" size="2"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Arial" size="2"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;2 failures due to CVS file corruption&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div class="MsoNormal"&gt;&lt;font face="Arial" size="2"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Arial" size="2"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;2 failures due to unknown CVS error&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div class="MsoNormal"&gt;&lt;font face="Arial" size="2"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Arial" size="2"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;13 failures due to timeout when doing CVS tagging&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div class="MsoNormal"&gt;&lt;font face="Arial" size="2"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Arial" size="2"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;4 failures due to email error&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div class="MsoNormal"&gt;&lt;font face="Arial" size="2"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Arial" size="2"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;2 failures due to internal network problems&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div class="MsoNormal"&gt;&lt;font face="Arial" size="2"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;&lt;/span&gt;&lt;/font&gt;&lt;font face="Arial" size="2"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;11&amp;nbsp;failures on the build machine due to not enough disk space&lt;/span&gt;&lt;/font&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p class="MsoNormal"&gt;&lt;font face="Arial" size="2"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;To solve the CVS temp directory problems we&amp;#39;ve resorted to having a script run on the CVS server that periodically deletes any CVS temp folder that is older than 6 hours old. Even so, there are times when the script can&amp;#39;t delete the folder because it is locked open. Something is happening in CVS to cause processes on the server to hang around even though the client action is long gone.&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;font face="Arial" size="2"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;The CVS timeouts -- I have no clue on that one yet.&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;font face="Arial" size="2"&gt;&lt;span style="FONT-SIZE:10pt;FONT-FAMILY:Arial;"&gt;Not enough disk space on the build machine -- that one was deceptive because the errors never actually said &amp;quot;disk space&amp;quot;. They were all just unexplained failures or file not found or something of the sort. Now that I realize that&amp;#39;s an issue I&amp;#39;ve set up an alert to warn me when disk space goes below 10% free. Just something to keep in mind!&lt;/span&gt;&lt;/font&gt;&lt;/p&gt;&lt;img src="http://gormanonline.com/aggbug.aspx?PostID=658" width="1" height="1"&gt;</description><category domain="http://gormanonline.com/blogs/msidle/archive/tags/CVS/default.aspx">CVS</category><category domain="http://gormanonline.com/blogs/msidle/archive/tags/Build+Management/default.aspx">Build Management</category></item><item><title>CVS and CruiseControl.NET and password exposure</title><link>http://gormanonline.com/blogs/msidle/archive/2008/09/19/cvs-and-cruisecontrol-net-and-password-exposure.aspx</link><pubDate>Fri, 19 Sep 2008 17:20:00 GMT</pubDate><guid isPermaLink="false">45bc9128-c309-4a47-b6b1-7705e21af830:656</guid><dc:creator>SusanGorman</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://gormanonline.com/blogs/msidle/rsscomments.aspx?PostID=656</wfw:commentRss><comments>http://gormanonline.com/blogs/msidle/archive/2008/09/19/cvs-and-cruisecontrol-net-and-password-exposure.aspx#comments</comments><description>&lt;p&gt;I&amp;#39;m setting up a new build server using these applications:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div&gt;CVSNT 2.5.03.2382 (open source source control, command line based)&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;TortoiseCVS 1.10.9 (GUI for interacting with CVS)&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;CruiseControl.NET 1.4 (service for automating builds)&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;When using CruiseControl to automate the checkout from CVS of the most recent source code, you have to setup a CVS section in your CruiseControl project.&lt;/p&gt;
&lt;p&gt;According to the CruiseControl documentation, you are required to provide the cvsroot, which includes among other things&amp;nbsp;the name of the CVS server, the user name with which to interact with CVS and that user&amp;#39;s password. (Caveat: I don&amp;#39;t know much about security and connection methods, but I do know that CVS offers several connection methods and I believe part of the reason that a password is required is because I&amp;#39;m using the pserver access method.)&lt;/p&gt;
&lt;p&gt;As you can imagine, I wasn&amp;#39;t excited about having to have my build user password in plain text in the cruise control project files. &lt;/p&gt;
&lt;p&gt;I discovered a way to avoid this requirement.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;div&gt;Go to the build machine on which the cruise control project will run.&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;At a command prompt run this CVS command: cvs -d :pserver:cvsuser@cvsserver:/cvsrepository login&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;After hitting Enter, supply the password&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;Now you&amp;#39;ve setup a remembered recognition of the cvsuser on that cvs repository and it won&amp;#39;t require the password every time you try to run a CVS command.&lt;/p&gt;
&lt;p&gt;If you move the CruiseControl project to a different machine, I believe you need to repeat the process of logging in from the new machine.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://gormanonline.com/aggbug.aspx?PostID=656" width="1" height="1"&gt;</description><category domain="http://gormanonline.com/blogs/msidle/archive/tags/CruiseControl.NET/default.aspx">CruiseControl.NET</category><category domain="http://gormanonline.com/blogs/msidle/archive/tags/CVS/default.aspx">CVS</category></item><item><title>Common Task: Optionally Cleanup User Data on Uninstall</title><link>http://gormanonline.com/blogs/msidle/archive/2008/09/04/common-task-optionally-cleanup-user-data-on-uninstall.aspx</link><pubDate>Thu, 04 Sep 2008 20:18:00 GMT</pubDate><guid isPermaLink="false">45bc9128-c309-4a47-b6b1-7705e21af830:649</guid><dc:creator>SusanGorman</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://gormanonline.com/blogs/msidle/rsscomments.aspx?PostID=649</wfw:commentRss><comments>http://gormanonline.com/blogs/msidle/archive/2008/09/04/common-task-optionally-cleanup-user-data-on-uninstall.aspx#comments</comments><description>&lt;p&gt;This is a common scenario... Your application, when it runs, creates log files, registry entries, and customized data files on the machine. These are files that were not installed by the installer. Therefore when you go to uninstall, these files would not normally be cleaned up.&lt;/p&gt;
&lt;p&gt;It ought to be simple to add code to the installer to tackle removing these files. But... how do you handle it if an uninstall is happening because the user is upgrading? In that case, the user probably wants to KEEP those &amp;#39;hanging chads&amp;#39;.&lt;/p&gt;
&lt;p&gt;So you are left with a situation where you want the removal of items to be conditional - under some conditions remove them, under other conditions don&amp;#39;t.&lt;/p&gt;
&lt;p&gt;This gets tricky. I&amp;#39;ve worked up a solution to it. I&amp;#39;m not claiming it&amp;#39;s ideal or anything.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Deleting Files and Folders&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Before I begin, let me say that as I understand it the best practice is for an application NOT to create data files in its INSTALLDIR. Instead, files like this should go under a Documents and Settings folder either for the current user or under All Users. Further, my understanding is that you don&amp;#39;t technically have to remove files under Doc n Settings. However, the requirements I&amp;#39;m usually given say &amp;quot;must remove all traces of product on uninstall&amp;quot;. So having said all that...&lt;/p&gt;
&lt;p&gt;For this example let&amp;#39;s say that the product creates a folder called Logs, under INSTALLDIR. You&amp;#39;ll need a Directory table entry for this path, such as INSTALLDIR_LOGS. To cause this folder to get removed on uninstall you add 2 entries to the&amp;nbsp;RemoveFile table. One entry with FileName of *.* and DirProperty of INSTALLDIR_LOGS. This entry causes all files under Logs to get deleted. A second entry with FileName blank and DirProperty of INSTALLDIR_LOGS. This entry causes the (now empty) folder to get deleted. Both of these table entries should be associated with a component that will be uninstalled at uninstall time.&lt;/p&gt;
&lt;p&gt;Now let&amp;#39;s get tricky and make this conditional. Let&amp;#39;s assume that by default you want to KEEP this folder. The reason to keep it by default is so that a silent uninstall (such as when upgrading) will keep the folder.&lt;/p&gt;
&lt;p&gt;In the Directory table, create an entry for UNINSTALL_INSTALLDIR_LOGS. Directory_Parent is TempFolder. DefaultDir is ThisFolderShouldNotExist. Yeah, that&amp;#39;s a weird name, but it is self-explanatory. We are setting the path to a path which we do NOT expect to actually exist on the target machine - a subdirectory of the Temp folder. The point being, we don&amp;#39;t intend for any files to actually get removed at this path.&lt;/p&gt;
&lt;p&gt;Go back to RemoveFile table and change the DirProperty for both entries so that they point to UNINSTALL_INSTALLDIR_LOGS.&lt;/p&gt;
&lt;p&gt;Now.. when uninstall occurs, it looks in RemoveFile table and tries to delete&amp;nbsp;TempFolder\ThisFolderShouldNotExist\*.*. This folder won&amp;#39;t exist and there will not be any errors as a result of that. All is well.&lt;/p&gt;
&lt;p&gt;Now we go to Custom Actions. Create a Set Directory custom action that will, based on a flag, set UNINSTALL_INSTALLDIR_LOGS to the REAL path where the log files exist. For example, my cusotm action is called Uninstall_SetLogsDir. The Directory value is [INSTALLDIR_LOGS]. This goes in the Install Exec sequence with a condition of FULLCLEANUP=&amp;quot;yes&amp;quot;.&lt;/p&gt;
&lt;p&gt;So if the FULLCLEANUP property is set to &amp;quot;yes&amp;quot;, then our fake path will get reset to the real path, and as a result the log files will get deleted.&lt;/p&gt;
&lt;p&gt;Now all you need is a method of setting FULLCLEANUP to yes. In the Property table, create FULLCLEANUP and set it to no, by default. Using whatever method you want, cause a dialog to pop up during uninstall that asks the user if they want to do a full cleanup and if they say yes, then set FULLCLEANUP to yes.&lt;/p&gt;
&lt;p&gt;NOTE: When the user uninstalls from Add/Remove Programs using the Remove button, it launches the uninstall with reduced UI, so any custom dialog you write will NOT appear. Therefore, you have to either A) disable the Remove button and force them to use Change button instead or B) display your full cleanup question dialog using some other method via a custom action (InstallScript?).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&amp;nbsp;Deleting Registry Keys&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;You can apply the same basic methods to conditionally removing a registry key using the Property table (instead of the Directory table) and the Registry table (instead of the RemoveFile table).&lt;/p&gt;
&lt;p&gt;Create a&amp;nbsp;Property that holds the path to the registry key. By default set the Property to something that will not exist, for example, a Property called MyRegKey which is set to &amp;quot;Software\ThisKeyWillNotExist&amp;quot;. &lt;/p&gt;
&lt;p&gt;In the Registry table, create an entry for the key you want to conditionally remove. The fields for this entry are:&lt;/p&gt;
&lt;p&gt;Key = &amp;quot;[MyRegKey]&amp;quot;&lt;br /&gt;Name=&amp;quot;-&amp;quot;&lt;br /&gt;Value=&amp;quot;&amp;quot;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;And set the Component to whatever component makes sense. It is the minus sign in the Name column that tells MSI to remove the reg key on uninstall.&lt;/p&gt;
&lt;p&gt;In the Custom Actions, create an action that will set the MyRegKey property to the *real* path when FULLCLEANUP=&amp;quot;yes&amp;quot;. The real path might be something like: &amp;quot;Software\[CompanyName]\[ProductName]\MyCustomRegKey&amp;quot;. &lt;/p&gt;
&lt;p&gt;NOTE: This only works with whole reg keys, you cannot remove a registry VALUE using this method. In fact, there is not a clean way to remove only a registry value, as far as I know. I find this odd, but true.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;There ya go. It appears to work, and it isn&amp;#39;t too clunky. Have fun!&lt;/p&gt;&lt;img src="http://gormanonline.com/aggbug.aspx?PostID=649" width="1" height="1"&gt;</description><category domain="http://gormanonline.com/blogs/msidle/archive/tags/registry/default.aspx">registry</category><category domain="http://gormanonline.com/blogs/msidle/archive/tags/InstallShield/default.aspx">InstallShield</category><category domain="http://gormanonline.com/blogs/msidle/archive/tags/MSI/default.aspx">MSI</category><category domain="http://gormanonline.com/blogs/msidle/archive/tags/Installer+Fundamentals/default.aspx">Installer Fundamentals</category><category domain="http://gormanonline.com/blogs/msidle/archive/tags/Best+Practices/default.aspx">Best Practices</category></item><item><title>I'm a slacker!</title><link>http://gormanonline.com/blogs/msidle/archive/2008/09/02/i-m-a-slacker.aspx</link><pubDate>Tue, 02 Sep 2008 16:26:00 GMT</pubDate><guid isPermaLink="false">45bc9128-c309-4a47-b6b1-7705e21af830:640</guid><dc:creator>SusanGorman</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://gormanonline.com/blogs/msidle/rsscomments.aspx?PostID=640</wfw:commentRss><comments>http://gormanonline.com/blogs/msidle/archive/2008/09/02/i-m-a-slacker.aspx#comments</comments><description>&lt;p&gt;I was reminded that I haven&amp;#39;t posted in a while and that I&amp;#39;ve been a slacker. I profusely apologize and hereby seek to remedy that situation. &lt;img src="http://gormanonline.com/emoticons/emotion-1.gif" alt="Smile" /&gt;&lt;/p&gt;
&lt;p&gt;So here&amp;#39;s what I&amp;#39;ve been up to...&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&amp;nbsp;Why should you avoid using the&amp;nbsp;TypeLib table ?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I have a&amp;nbsp;customer&amp;nbsp;trying to consume a merge module that we produce. The customer is creating his installer using Wise. &lt;/p&gt;
&lt;p&gt;I created the merge module using InstallShield 12. The merge module includes a COM dll that is self-registered. In my merge module I set the DLL to extract COM data at build time. This is so that the registration data stays up to date in the installer. Unfortunately, the way that InstallShield works, this causes it to create the registry entries in the TypeLib, AppId, Class&amp;nbsp;and ProgID tables instead of lumping it all in the Registry table.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The Wise system refuses to consume a merge module with entries in the TypeLib table and errors out. Why? &lt;/p&gt;
&lt;p&gt;See the Remarks in this MSDN article about the TypeLib table&amp;nbsp;&lt;a href="http://msdn.microsoft.com/en-us/library/aa372092(VS.85).aspx"&gt;http://msdn.microsoft.com/en-us/library/aa372092(VS.85).aspx&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So... I&amp;#39;m left wondering at this point, how am I supposed to use InstallShield to dynamically update the COM registration information at build time and yet still produce an &amp;#39;acceptable&amp;#39; MSI/MSM? I haven&amp;#39;t resolved this issue yet. So far I&amp;#39;ve had to manually modify the MSM for that one customer who&amp;#39;s using Wise. Customers using InstallShield don&amp;#39;t have a problem.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;strong&gt;CVS is problematic and my builds aren&amp;#39;t reliable&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I&amp;#39;ve been having problems with builds failing on an irregular, but annoyingly often basis. I use CruiseControl.NET and CVS at the moment, because these are open source (free!) tools. I&amp;#39;m NOT on the most up to date version of these tools due to the fact that I need to test out these tools in a non-production environment before I can implement the newer versions and I don&amp;#39;t have access to a non-production environment yet. It&amp;#39;s in process though! The problems I&amp;#39;m having with the builds are these main issues:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div&gt;CVS &amp;quot;cannot change permissions on temporary directory&amp;quot; errors. This error appears multiple times a week. I haven&amp;#39;t been able to find any solution or explanation for this error in all my googling. All I can find is &amp;quot;yeah, this happens, we don&amp;#39;t know why, just try again and it will work&amp;quot;. This is true, in that if you immediately do another build it does succeed. But that doesn&amp;#39;t make it acceptable to have builds failing. This is an unresolved problem for me at this time.&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;CVS times out when trying to apply a label/tag. CruiseControl is using its internal APIs (?) to effect the CVS tagging so I can&amp;#39;t get a good detailed log of what&amp;#39;s going on during this process of why it&amp;#39;s freezing up. Since tagging doesn&amp;#39;t happen until after the build is finished and successful, this is really annoying to have it fail at the very end. One potential handling is to stop using CruiseControl to do the tagging, but I hate to so obviously bypass the built-in functionality.I&amp;#39;ll probably try this technique soon.&amp;nbsp;Unresolved at this time though I do have this technique to try out.&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div&gt;Network briefly blips and loses access to the network device on which files are being copied. Using MSBuild to do a copy task which copies dozens to hundeds of files. If there&amp;#39;s a momentary blip and it can&amp;#39;t copy a single file -- this causes the entire build to fail. The network shouldn&amp;#39;t be blipping in the first place, but.. until that is solved, it would be ideal to have a copy function that is more robust which could try copying - if it fails, wait a sec and try again, and don&amp;#39;t fail out unless more than one copy attempt fails. I could do this pretty easily in nAnt, but this particular build is in MSBuild and I&amp;#39;m not very familiar with MSBuild yet. The suggestion that was given me was that I need a custom MSBuild task written in a DLL. (sigh! More DLL writing) Haven&amp;#39;t tackled this one as yet because we&amp;#39;d prefer to fix the network instead.&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;InstallScript custom actions fail due to ISBE.dll not registering on Windows Server 2008&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Lastly, in a big installer I started working on converting all the VBScripts to InstallScript because management prefers InstallScript to writing new DLLs for custom actions. Unfortunately, The test machine for this installer is a Windows Server 2008 OS and we immediately started gettting install failures due to the InstallScript CA engine (ISBE.dll) failing to register on the machine. I made a test installer and tried it out on other 64-bit machines (XP and Vista) and it works fine, but it fails on this one Windows Server 2008 machine. Currently working with InstallShield to see if they can help get rid of this error. Until this is solved, I can&amp;#39;t work any further on converting scripts to InstallScript because it creates a perception in management that InstallScript is&amp;nbsp;unreliable.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://gormanonline.com/aggbug.aspx?PostID=640" width="1" height="1"&gt;</description><category domain="http://gormanonline.com/blogs/msidle/archive/tags/DLL/default.aspx">DLL</category><category domain="http://gormanonline.com/blogs/msidle/archive/tags/custom+actions/default.aspx">custom actions</category><category domain="http://gormanonline.com/blogs/msidle/archive/tags/InstallShield/default.aspx">InstallShield</category><category domain="http://gormanonline.com/blogs/msidle/archive/tags/MSI/default.aspx">MSI</category><category domain="http://gormanonline.com/blogs/msidle/archive/tags/InstallScript/default.aspx">InstallScript</category><category domain="http://gormanonline.com/blogs/msidle/archive/tags/Self-registration/default.aspx">Self-registration</category></item><item><title>What to do when there's nothing to do?</title><link>http://gormanonline.com/blogs/msidle/archive/2008/07/01/what-to-do-when-there-s-nothing-to-do.aspx</link><pubDate>Tue, 01 Jul 2008 13:25:00 GMT</pubDate><guid isPermaLink="false">45bc9128-c309-4a47-b6b1-7705e21af830:632</guid><dc:creator>SusanGorman</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://gormanonline.com/blogs/msidle/rsscomments.aspx?PostID=632</wfw:commentRss><comments>http://gormanonline.com/blogs/msidle/archive/2008/07/01/what-to-do-when-there-s-nothing-to-do.aspx#comments</comments><description>&lt;p&gt;I&amp;#39;m in one of this situations where the product is in Beta,&amp;nbsp;stable but&amp;nbsp;not yet actually released. Therefore the codebase is locked down such that only the most pressing code changes are allowed to get checked in. In the ideal situation we&amp;#39;d have a branch of the code and a set of tasks to work on for the *next* release. For various reasons we don&amp;#39;t have that at the moment. So.. it means unless a critical bug comes in in my code, then I&amp;#39;m locked out from doing any coding work at the moment.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;*twiddle thumbs*&lt;/p&gt;
&lt;p&gt;Here&amp;#39;s my recommendation on what to do in this situation: Document!&lt;/p&gt;
&lt;p&gt;I know most programmers hate writing any sort of documentation, but someone working on installers and configuration management tasks is dealing with an area that even more urgently requires documentation. Most sorts of code you can write comments into it to give some explanation of why&amp;nbsp;it is done that way. Some new programmer walking in off the street has a reasonable opportunity to grasp the basic flow and policies that went into how the code works.&lt;/p&gt;
&lt;p&gt;Because MSI installers are table-driven, there isn&amp;#39;t any good way to comment like this. Not only does a new install developer have to fumble around blindly, but I even forget why I did things the way I did if I&amp;#39;m away from the installer for a couple months.&lt;/p&gt;
&lt;p&gt;The solution here is to document, at least in a basic form, the thinking behind why the install does what it does. I do this by making the document feature-based. For example, I have a feature where I want to validate the path a user has entered on a dialog. In order to support this feature there are entries in about 5 different tables (ControlEvent, Property, CustomAction, AppSearch, Etc.)&lt;/p&gt;
&lt;p&gt;In my document I make a heading for this feature, explain what the feature is supposed to accomplish (in plain English), then list the 5 table entries that are required to provide this feature and explain in simple english how those entries relate to each other. For most features this takes a small paragraph and a 4 to 8 item bulleted list. Simple. I keep the document going, adding features to it as I add them into the installer. I guess you might call this a technical spec - I don&amp;#39;t know the official term for it. I also go ahead and check this document into source control right alongside the installer project so that the two are easily located together.&lt;/p&gt;
&lt;p&gt;A great benefit of writing this kind of documentation is that if you ever need to add this feature to another installer, you already have the pattern for how to do it. Similarly, if you ever need to remove that feature, you know all the little pieces that go with it and can remove it cleanly.&lt;/p&gt;
&lt;p&gt;This is the type of documentation that often gets left out, but can really make a difference in providing&amp;nbsp;long-term quality of code. Also, managers love it!&lt;/p&gt;
&lt;p&gt;Hope you are enjoying living the Lifestyle of the MSIdle!&lt;/p&gt;
&lt;p&gt;Susan&lt;/p&gt;&lt;img src="http://gormanonline.com/aggbug.aspx?PostID=632" width="1" height="1"&gt;</description><category domain="http://gormanonline.com/blogs/msidle/archive/tags/MSI/default.aspx">MSI</category><category domain="http://gormanonline.com/blogs/msidle/archive/tags/Installer+Fundamentals/default.aspx">Installer Fundamentals</category><category domain="http://gormanonline.com/blogs/msidle/archive/tags/Best+Practices/default.aspx">Best Practices</category></item><item><title>Vacation's Over!</title><link>http://gormanonline.com/blogs/msidle/archive/2008/07/01/vacation-s-over.aspx</link><pubDate>Tue, 01 Jul 2008 13:24:00 GMT</pubDate><guid isPermaLink="false">45bc9128-c309-4a47-b6b1-7705e21af830:631</guid><dc:creator>SusanGorman</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://gormanonline.com/blogs/msidle/rsscomments.aspx?PostID=631</wfw:commentRss><comments>http://gormanonline.com/blogs/msidle/archive/2008/07/01/vacation-s-over.aspx#comments</comments><description>&lt;p&gt;Vacation was longer than I expected, but now it&amp;#39;s over and it&amp;#39;s back to work!&lt;/p&gt;&lt;img src="http://gormanonline.com/aggbug.aspx?PostID=631" width="1" height="1"&gt;</description></item><item><title>On Vacation</title><link>http://gormanonline.com/blogs/msidle/archive/2008/06/03/on-vacation.aspx</link><pubDate>Tue, 03 Jun 2008 14:23:00 GMT</pubDate><guid isPermaLink="false">45bc9128-c309-4a47-b6b1-7705e21af830:629</guid><dc:creator>SusanGorman</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://gormanonline.com/blogs/msidle/rsscomments.aspx?PostID=629</wfw:commentRss><comments>http://gormanonline.com/blogs/msidle/archive/2008/06/03/on-vacation.aspx#comments</comments><description>&lt;p&gt;School&amp;#39;s out and&amp;nbsp;it&amp;#39;s officially summer!&amp;nbsp;&lt;/p&gt;
&lt;p&gt;I&amp;#39;m on vacation for 2 weeks. I&amp;#39;ll be back and posting more MSI, InstallShield and Configuration Management related items in mid-June.&lt;/p&gt;
&lt;p&gt;Enjoy your summer!&lt;/p&gt;
&lt;p&gt;Susan&lt;/p&gt;&lt;img src="http://gormanonline.com/aggbug.aspx?PostID=629" width="1" height="1"&gt;</description><category domain="http://gormanonline.com/blogs/msidle/archive/tags/personal/default.aspx">personal</category></item></channel></rss>