ISWIX, LLC View Christopher Painter's profile on LinkedIn profile for Christopher Painter at Stack Overflow, Q&A for professional and enthusiast programmers

Friday, December 28, 2007

Code Signing On The Cheap and Easy

John Robbins attracted my attention a couple of months ago with a series of posts on WiX. More recently I noticed a nice article discussing code signing on the cheap ( and easy ). It's a good read and I reccomend it. Personally I've only signed a few packages with self generated test certificates and then let my customers build the package with their certificates... a sort of design by contract scenario. John's solution is cheap enough that I might just be tempted to go buy a certificate for myself.

Thursday, December 27, 2007

Bloggers Wanted

A little over three years ago I wrote by first blog post:

I want to try to create a site where myself ( and maybe soon others ) can publish articles that go way beyond the typical newbie "how do I" discussions. A site where we inspire people to get hard core with Software Engineering.

I feel over the years that I've accomplished only part of my goal. It was and still is my intention to try to bring other voices into the discussion. I really encourage people who are passionate about build/setup/deployment to start their own blogs and/or contact me to discuss contributing to this blog as part of a team effort.

To Redist or Not To Redist, That Is The Question

Recently I blogged about issues regarding deploying the .NET Framework 3.5. I was all over the map in terms of my thoughts, and out of the resultant comments came an interesting comment that makes me wonder:

Is it really a violation of the EULA to redist the .NET Framework?

Now I am not a lawyer, and I doubt many people reading my blog are either. However, I invite comments on this subject.

Since my writing style has been distracted as of late ( no doubt because of all the personal hell that I've been going through ) I think I'm just going to stick to a bullet list of thoughts / questions that are on my mind.

1) Microsoft surely wants to cut the red tape and encourage the distribution of the framework as to achieve greater adoption of .NET by ISV's.

2) Silent installs are a fundamental requirement of enterprise deployments so surely there has to be a realistic way of cutting through the red tape ( see #1 ).

3) MSI 4.5 is all about composing applications via micro packages through a seamless installation transaction. Surely, again, that some EULA red tape isn't meant to get in the way of all this.

4) Microsoft makes the entire framework available as a free / unregistered download and they call it "Full Redistributable Package". Is it really redistributable, or is it not really redistributable?

I've seen it mentioned that an MSI package is `cleaner` without a setup.exe, without any redist packages and to simply block the install with an AppSearch/LaunchCondition type pattern. I'd say in certain circumstances that is true. However, I've also worked on some really exotic installs in my time. Some of them were years ahead of MSI 4.5 in terms of distributing literally dozens of redist packages in support of a primary product install. The teams I've supported integrated a lot of different technologies in a product line development environment and you couldn't eliminate the dependencies or tell a project manager that they needed to be installed individually. The expectation was for a seamless automated installation.

I feel myself wanting to go in left field so I'll end it with I invite your comments below.

Thursday, December 20, 2007

.NET Framework Size

This is a topic that I've been wanting to write about for awhile but I just haven't had the time: Holy Crap the .NET Framework 3.5 is HUGE!

How did we get here? Let's see....

.NET Framework 1.0 Redist: 19.7MB
.NET Framework 1.1 Redist: 23.1MB
.NET Framework 2.0 Redist: 22.4MB
.NET Framework 3.0 Redist: 50.3MB ( x86 )
.NET Framework 3.0 Redist: 90.1MB ( x64 )
.NET Framework 3.5 Redist: 197.0MB

Wow! 197MB! The funny thing is there is a Doctor Dobb's article from 2003 that was questioning the size of .NET 2.0 when it was a mere 1/5th of the size that it is now. Just what in the world would they think now?

It should be understood that the 3.5 redist contains a lot of junk under the hood. It's really invasive... it contains windows patch, patches for previous versions of the framework, different versions for different platform types and so on. There have also been a long list of installer defects already announced that are going to pose problems when it comes time for ISV's to try to integrate the framework into their bootstrappers for their own products.

Related to this topic are a couple observations that I wanted to share. The first is a long list of blogs that I've seen recently detailing installer defects in various .NET / Visual Studio installs. The quality and user experience in these installs really seem to be going downhill. It's not like taking hours to install VS 2005 SP1 wasn't bad enough. Now you are lucky if the installs work in the first place. As an aside, I really can't help wonder if all of the Virtual PC CTP's during the beta cycle didn't contribute to an environment where the installs just wasn't getting close scrutinizing.

The second observation is how many people are willing to just blindly believe in `Microsoft Best Practices`. For example, I recently read the following comment over at InstallSite:

I wonder if there's a specific reason that some of the installer products feel the need to wantonly violate Microsoft's best practices?

When asked to elaborate, the poster mentioned the use of non-standard cab compression techniques such as LZMA. This technique is used by other vendors such as InstallAware. For example, InstallAware is able to reduce the .NET Framework 3.5 Redist by 33% to 132MB. This is still huge, but atleast InstallAware is trying to do something to help out.

This advance in installation technology did not go unpunished though. WiX creator Rob Mensching flamed InstallAware over this issue with the following statement:

So why do I have a negative impression of InstallAware? Two reasons. First, they repackaged redistributable packages (such as the .NET Framework) which violates the EULAs of the products. Messing with other people's stuff then redistributing your modifications without explicit permission bothers me at a philosophical level.

The irony is InstallAware was specifically asked by Microsoft if their technology could be used to reduce the size of the framework SDK.

So it seems to me that LZMA compression really is a best practice. It's just that our overlords at Microsoft just haven't been smart enough to admit and/or support it yet.

Getting back to the framework size issue... I'm afraid I don't see magic bullet for mitigating it. Considering setup developers don't typically get to tell the architects how to code, if 3.5 comes down the pipe we are pretty much just going to have to bite the bullet. As an aside, ClickOnce apps on .NET 3.5 are officially a joke, right?

Sadly I now find myself waiting for MSI 4.5 and it's transacted prereqs patterns to see just how much more complicated ( and worse ) Windows Installer packages for .NET / Visual Studio can become.

Tuesday, December 18, 2007

Fighting The Good Fight

I really wish that I was referring to Setup related issues when I mention Fighting the Good Fight. Unfortunately, I am once again talking about the fight for survival against cancer.

Tomorrow morning my wonderful wife ( of nearly elevent years ) Cheryl will be undergoing liver surgery to attempt to deal with a metastatic tumor. The following months will involve additional surgery to deal with a lung tumor and many, many rounds of chemotherapy. With any luck the surgery will deal with the localized problems and the chemo will take care of the systemic problems.

So I once again come to you and ask that you please keep my wife and family in your thoughts, hearts and prayers in any way that you can.

Saturday, December 15, 2007

An Example of the Importance of Setup

As a result of my division being sold to another company earlier this summer, one of the many things asked of me was to complete a `Jobs Analysis Questionnaire`. Basically it's a really long form trying to figure out what the heck I do ( think of the Bobs in Office Space asking `So just what is it you do here?` ), how much responsibility I have and what could go wrong if I do it incorrectly.

A lot of people seem to think that Deployment Engineering isn't really important. Very frequently I am contacted by potential clients and recruiters who seem to grossly underestimate their needs. I even see this attitude from very seasoned developers and program managers who really should know better.

Recently I've seen a lot of postings talking about very .NET Framework and Visual Studio installer errors. However even these blatant defects are nothing compared to this gem.

The summary of the story is that a gaming company was putting together an installer using NSIS and in the process they wiped out the BOOT.INI on their customers computers. They try to explain how their entire development process failed to catch this issue but in the end it's inexcusable. In the end they are feeling the pain of trying to make it right.

Sadly this is the case in a lot of development shops. Deployment Engineering just isn't treated as a first class activity. Resources with little or no understanding of deploying applications get assigned, the requirements aren't clearly defined, inferior tools are selected and the test plan is non-existent.

Thursday, November 29, 2007

Windows Installer Useful Web Sites

This blog post is going to be a continual work in progress. Please feel free to contribute to the list via a comment.

Windows Installer Useful Web Sites

Installation Phases and In-Script Execution Options for Custom Actions in Windows Installer

More Interesting and Uninteresting Comments

Stefan Krueger recently waded into the custom action debate with some very interesting comments.

Stefan references my believe in InstallScript custom actions and mentions a couple downsizes. Mainly Installscript engine size ( package bloat ), possibility of InstallScript engine failure and the temptation to use InstallScript CA's to make system configuration changes instead of built-in MSI patterns. Specifically he says:

However I believe that the tasks of a custom action often aren't typical installation tasks (copying files, accessing the registry) but require calling some APIs to interact with other applications.

Personally my packages tend to be very large and complex so the engine overhead is a non-issue to me. However, I could see it could be a consideration for small packages. I've also found the InstallScript engine to be very reliable.

I find InstallScript's ability to call Win32 API, COM and ManagedCode with very little plumbing ( let's just say you won't be worrying about things like allocating memory, casting datatypes and hosting COM servers and the CLR ) to be one of the strongest reasons for using InstallScript. For example, in one of my client installs I prompt the user for the hostname and port number of an application server. I then pass this information off to a .NET class that invokes uses the information to invoke a webservice. Anyone want to take a guess at how many lines of InstallScript and C# that is? Anyone want to take a guess how many lines that would be in C++? I've been using this code in production for 1 1/2 years now and I've never ever seen it fail.

Another example would be where you need to make a change that MSI doesn't support. The built-in MSI functions make it easy to implement the database queries needed to author data driven CA's and the extensibility makes it easy to interop with whatever external API you need to talk to install, uninstall, commit or rollback the configuration change.

Now for the uninteresting comment. A developer named Carl replied to Stefan's blog with this nugget:

Christopher Painter is wrong. InstallScript MSIs are never appropriate. Leveraging the language into MSIs was dreamed up by InstallShield's marketing team to con people into 'upgrading' to InstallShield 7 saying that "you can upgrade to MSI and your old scripted package will still work"

It had no place in an MSI then, and it has none now.

Personally I like VBScript. It has the advantages of being easy to read, open source and can be debugged from within the MSI using the MSOffice debugger.

Well, I've said it before and I'll say it again. Some developers just LOVE to HATE InstallShield. Here is another developer who's convinced that I'm wrong and InstallShield sucks. Never mind that he doesn't know the difference between an InstallScript MSI and a Basic MSI with InstallScript CA. Never mind that he mentions InstallShield 7 and that he prefers to use ( shudder ) VBSCript CA's. InstallShield is evil and they have conned the world.

InstallShield 2008 Beta Support for Visual Studio 2008

I noticed a thread over on InstallShield Community where Mike Marino mentioned that InstallShield 2008 now has beta support for VS2008 VSIP. You can find the InstallShield Knowledge Base article here. The hotfix can be downloaded here.

Monday, November 26, 2007

WiX Takes The Next Step

I was reading on Windows Installer Expert Stefan Krueger's InstallSite Blog today that that the Visual Studio team is finally incorporating WiX into VSTS. I am very pleased to hear this and I can't help think `about time`. :-)

Regular readers of my blog are no doubt aware that I've been advocating over and over for months that Microsoft make WiX a priority.

Getting the core tool set in VSTS is a very good step but there is still a huge gap in the authoring/designer/editing tools. Considering Microsoft has purchased other products for inclusion in VSTS ( TeamPlain ), I think Microsoft should seriously consider purchasing WiXAware and incorporating it into VSTS as well. This would be a very potent combination of technology that would really make me rethink which tools I use to write my installs.

Eitherway, congratulations go to Rob Mensching.

Wednesday, October 24, 2007

InstallScript Custom Actions are GOOD

We've long heard the rants against Script based CA's, Managed Code CA's and CA's in general. Lately Microsoft has begun blogging about the horrors of even EXE CA's.

IMO when talking about CA problems, is isn't really the CA that is the problem. The problem is in the CA hosting models and therefore it's really MSI that is the problem. And when preaching against CA's in general, yes it is true, somewhere north of 90% of the CA's written by developers truly aren't needed. However the other 10% is really a result of MSI not being `feature complete` as defined by the customer instead of as defined by Microsoft. Unfortunately there doesn't seem to be any change coming in the near future.

So where does that leave us? Type 1 DLL standard call CA's:

Ultimately, avoiding CAs is the best approach but, when necessary, you should develop DLL CAs. Immediate DLL CAs can read from the installer package database and should be data driven, making it easier to service that data and providing perhaps some transparency to what your CA does. Those immediate CAs can then schedule deferred, rollback, and commit CAs as necessary based on that data and the current state of the machine. -Heath Stewart

But wait, who says they have to be written in C++? Well, no one does really. You see, as I previously blogged, starting with InstallShield 12 InstallScript CA's are really just unmanaged Type 1 CA's.

While there are a couple downsides ( mainly larger package size and slightly slower execution ), I think the upsides far outweigh them.

InstallScript is:

Not based on ActiveScript / Windows Scripting Host.

A C like language that is easier to code in then C++.

A domain specific language that has many proven functions for tackling setup related problems. This results in increased reliability as you aren't making stupid mistakes trying to roll your own everything and reinventing the wheel in C++.

Integrated into InstallShield. This makes it easier to develop, build and test in one easy to use IDE.

Doesn't add additional dependencies to your install. You won't need setup.exe to deploy some runtime to run your CA. You also won't find broken installs because someone built the debug C++ bits or didn't include some C++ runtime dll.

Can be transplanted into other installs. Stream out of one binary table and into another. It'll even work when writing transforms for packages made in other authoring tools.

Can easily use MSI API's to create data driven CA's.

I'm sure I could go on and on but I'll stop right there. InstallScript has really come a long way and is the right tool for the right job.

Monday, October 15, 2007

Some Good News

We received some good news on Saturday. Cheryl's MRI came back and there is no cancer in her brain. We are so relieved as that's not a road that we want to go down.

Still, we do face some new challenges now that Cheryl has a history of seizures. The neurologist has started her on some medication that takes awhile to adjust to. Basically I'll be taking the next week off of work to be with her and the girls until her parents arrive.

And to make life as interesting as possible, Ashley came down with the stomach bug in the middle of the night and Emma had a swollen and purple finger from an infection caused by a splinter. I just love running to three different Dr's offices in 24 hours!!!

Here's praying for better health in the days, months and years to come. Thank you everyone who's been there for me.

Friday, October 12, 2007

Exhausted from Cancer

Today was a very trying day that started with a call to 911 at 4am followed by 15 hours at a local hospital. I'm so mentally and physically exhausted right now that it's easier to just share my wife's perspective ( made possible by laptops and hospital WiFI ). My perspective would be too disturbing to post since I actually witnessed and responded to the seizure.

Early this morning we had a horrible scare. I had a grand mal seizure occur around 4:00 am. Chris was able to get me on my side, make sure I wasn't choking, and called the ambulance. All I remember is waking up to several paramedics in our room.
At this point, we are at Seton NW Hospital. They have already done an X-ray, CT scan to see if there was anything. They are planning to admit me for 1-2 days. During that time I'll have a spinal tap and an MRI done to see if there is anything happening in my brain. I will probably be put on anti-seizure medicine.

I am so grateful my in-laws are in town to help with the girls. My sister and Chris are with me right now. Please pray they find nothing in my brain, specifically no new tumours, and that this is just a 'fluke'.

I guess I should be grateful for the first aid / first responder training that I've had over the years. One of my personal hobbies is Scuba Diving and in the Rescue Diver and Nitrox courses we discussed handling O2 toxicity problems including grand mal seizures. I just never imagined that I'd be dealing with it on dry land while waking up from sleep.

Monday, October 8, 2007

WiX Code Is Pretty

I know that I frequently express my frustration with the WiX development experience. But there is one thing that I really like about WiX: How darn pretty the XML is. The declarative nature of MSI and the way the data is stored in multiple tables really makes it hard to describe an implementation detail in writing.

For example, I can describe an EXE CA stored in the binary table, scheduled in the execute sequence after InstallInitiatize with no impersonation and deferred execution.

If you have a solid MSI background, you probably have enough information to proceed. But if you are new at MSI and you need me to SHOW you how that all works it can be interesting trying to write it down.

One approach might be to try to describe the table relationships:

Binary Table
NewBinary1 stream in Notepad.exe data here

CustomAction Table
NewCustomAction1 3074 NewBinary1

InstallExecuteSequence Table
NewCustomAction1 1501

I might also try to express the relationships in .IDT format or perhaps MSI2XML ( which InstallShield uses ) but the end result is data that's hard to read and understand. After all, just what the heck is 3074 and 1501 without digging in to understand? Worse, it's not `code` that can be easily stolen ( umm, I mean copy and pasted hehehe ).

<Binary Id="Notepad.exe" SourceFile="notepad.exe"/>

<CustomAction Id="CustomAction1"
Return="check" HideTarget="no" Execute="deferred" Impersonate="no"
TerminalServerAware="no" ExeCommand="" BinaryKey="Notepad.exe"/>

<Custom Action="CustomAction1" After="InstallInitialize" />

Still, don't expect me to be reading/writing installs like Neo in the Matrix. IMO this is all great, but designers still rule in authoring the majority of my installation logic because of the productivity and reliability gains achieved in automating the authoring.

Friday, October 5, 2007

IEAK 7 - Another `Fake` MSI using WiX

MSI Expert Stefan Krueger recently blogged that Microsoft has released an updated IEAK 7 that now creates MSI files. I've had a chance to look at it and I can't help notice a few things. But first, let's go back in time a bit to Feb 2006 when Rob Mensching once blogged:

Google Toolbar Beta for Enterprise includes a Microsoft Windows Installer package that makes organization-wide distribution a snap.

Cool. So, I downloaded the .zip file and popped open the GoogleToolbarInstaller.msi and what should I find? Yep, you guessed it. The GoogleToolbarInstaller.msi file was created by the WiX toolset. Woohoo! How cool is that? Google uses the WiX toolset.

After calming down, I decided to look around and see how well the MSI was actually put together. Then my excitement dropped. The GoogleToolbarInstaller MSI package is a total fake. Their MSI file is nothing more than a wrapper around the old GoogleToolbarInstaller.exe. The Google Toolbar Beta for Enterprise does not use the Windows Installer to actually install the files (I'm not sure what install technology they are using). That means the Google Toolbar Beta for Enterprise does not get all of the transaction guarantees and other administrative/repair features that a true Windows Installer package would provide.

If you are an administrator looking to deploy this package, don't be surprised when you find that this MSI package doesn't behave exactly like real Windows Installer packages. The Google Toolbar Beta for Enterprise MSI package is really just a "Trojan horse" carrying their custom installation system. I really wish Google had used the Windows Installer technology more appropriately.

At the time I commented:

Rob- I'm usually nodding my head with you, but come on, Microsoft did the EXACT same thing with the Windows Media Player 9 Administratios Deployment kit that we talked about a couple blogs ago. Perhaps if AD GPO wasn't so restrictive in only understanding MSI people wouldn't feel the need to wrap legacy installer in a pseudo-msi package.

Well let's get back to the recent IEAK 7 release. Yes, you guessed it: Microsoft has once again done the exact same thing as Google. If you run the IEAK 7 wizard and build the MSI you'll notice that Microsoft ignored their very own setup expert and took a play straight out out of the Google playbook. They made a fake MSI package that doesn't publish the package and instead goes out of process to Setup.Exe to get the job done. All of this to get around the limitations of GPO without actually making the investment in MSI.

And of course the funniest thing is they used Windows Installer XML v2.0.3620.0 (candle/light) to get the job done. Just like Google.

Thursday, October 4, 2007

Deployment AntiPatterns

I recently came across a blog post from ScottGuthrie (MSFT) titled Tip/Trick: Automating Dev, QA, Staging, and Production Web.Config Settings with VS 2005. In his tip, Scott uses his build automation to produce multiple product configurations that stage different servers with different web.config files. He then gets dozens of ataboys comments from readers including one who wonders if this could be done for Winforms applications to which Scott replies
Yes - you should be able to use the same approach with winforms projects.

Now I'm sure Scott is a smart .NET developer, but this type of `xcopy deployment` that is tightly coupled to build automation is crazy. Furthermore, I know he's not alone in this thinking since if you pick up practically any .NET book you won't find deployment covered until the end of the book and even then it's a cursory look at VDPROJ as if deployment is that simple.

Build ( Core Code and Installer Packages ), Installation and Configuration are NOT the same thing. They are distinct steps in an overall process of deploying an application.

You may very well need to do all three of these steps within a single transaction ( for example automatically deploying an application to a Dev Integration Lab as part of a CI process ) but the steps are still separate.

Now some people disagree on whether an Install should actually configure a product or not. Regardless the build output should consist of a setup package. If you want to automate the deployment the build should then call staging automation to apply the package. If the package contains configuration logic, the staging automaton should pass those values to the package. If not, the staging automation should call an external utility and pass the values so that the product is ready to be used. In this way the staging automation could be invoked multiple times to stage Dev, QA, Production, whatever.

Scott's solution might be `OK` for an in house application that only gets `deployed` to a limited no of locations, but if you are working on a real `Product` that gets sold and given to customers all over the world you will really want to make a proper investment in automation.

Tuesday, October 2, 2007

Using TFS and PowerGen to build PowerBuilder

Over 10 years ago, I cut my OO teeth on a language called PowerBuilder. It had a really cool object called the DataWindow which was very similar to .NET's DataGridView class. This was back in the heyday of waterfall, CMM, big hunking fat clients and script based procedural installs as Windows Installer wasn't invented yet. At some point I became the Build/Install lead on a very large military client/server system and I was introduced to a wonderful tool called PowerGen. You see, natively PowerBuilder only had a `project object` for interactivly building your code. There was also an API called ORCA that you could use ( and later OrcaScript ) but that really sucks. PowerGen had a project file, GUI editor and command line interface that turns it all into child's play.

To make a long story short, I thought I was done with PowerBuilder back in 2003. Then I took a job about a year ago that involved Build/Install work for a TFS/.NET SOA system that was headed in the SaaS direction. After taking care of that I was asked to see what could be done with their legacy PowerBuilder system. I was somewhat shocked to see that they were checking PBL's ( PowerBuilder Libraries... large binary source files that consume tons of space, slow down the VSS client and can't be diff'd ). Worse, they had a completly manual build process.

Fortunately PowerGen once again came to the rescue. After a little custom wiring along the lines of going out of process to build a VDPROJ project, I was able to come up with a solution that incorporated TFS and TeamBuild as the source control repository and build platform. I've since contributed a set of sample scripts that should be able to help point other PowerBuilder/TFS users in the right direction.

Wednesday, September 26, 2007

Versioning MSI Packages: WiX vs InstallShield

I was reading a blog about using TFS to update the ProductVersion property in a WiX Source file before building an MSI package. I found the solution rather `interesting`: calling exec and going out of process to a PowerShell script to do a search and replace on the .wxs source during the AfterGet target.

I guess I shouldn't be too critical because God knows I've seen it done stranger ways in the past in InstallShield. I've seen using the automation interface, using the interface using reflection from .NET, using the Windows Installer automation when the package source .ISM is in Binary format, using MSDOM/XPath when the package source .ISM is in XML Format and calling VBS Postbuild steps to hit the build MSI. There are probably more strange ways out there but starting with InstallShield 2008 there really is a better way to do it.

IS2008 IsCmdBld and IsSaBld support a -y argument for passing ProductVersion into the build. For MSBuild support using the standard InstallShield targets file, you merely define $(InstallShieldProductVersion) and it's taken care of for you.

Yes, it really IS that easy.

BTW, if you really like how easy this is, you can thank me with a beer for requesting this particular feature.

Unfortunately as this other blog shows, WiX isn't as easy. You could always ask the WiX team to consider the feature request. Then again, you could always just use InstallShield instead since they actually listen to their customers.

Thursday, September 13, 2007

Setup Ethics

I noticed an interesting article linked on Slashdot alleging that Microsoft is now pushing down stealth updates to Windows clients even when users have not given consent by turning off automatic updates. This is of particular concern to corporate environments where change control and testing is very important.

It makes me think again about the power Deployment Engineers have and are sometimes asked to wield. It's almost a given that we will run with elevated privileges. With this great power comes great responsibility. I get really irritated thinking about some Setup Developer going along with management to push down software without consent, install root kits, install Spyware, put crap on the desktop, automatically start programs on login.... all without user consent. There really should be some code of conduct that takes into consideration ethical treatment of the customers machine and we should really push back on management asking us to do unethical things.

I recall back to 1997-1998 when I was asked to add a call to secedit.exe and apply the Compatible Workstation policy to resolve an application compatibility bug. First of all this was the wrong solution to the wrong problem... fix the damn application. What was worse was that the requirement came across to do it without notifying the user. Another time I was asked to change the regional date/time settings.

I was livid and I absolutely refused to implement either of these requirements. But I can't help wonder how many other developers would have gone along with it.

If the story about Microsoft is correct, it seems they have some Deployment Engineers that don't have any issues at all with doing what they are told.

Friday, September 7, 2007

Build InstallShield using TFS

contributed a `keep it simple` sample to Windows Installer MVP Stefan Krueger's InstallSite that demonstrates building a C# windows application and then package it using InstallShield 2008 via TFS Team Build. The example can be downloaded here:

The following is a step by step on how to wire it up:

Prepare To Build:
1) Extract and add the TeamBuildTypes and WindowsProduct folders to your TFS Project source control.

2) Update WorkspaceMapping.xml ServerItem attribute to reflect where you added the WindowsProduct folder in your source control tool.

3) Update TFSBuild.proj:

Set the BuildMachine ProjectExtension to reflect the name of your build machine. The build machine only needs to have .NET 2.0, TeamBuild and InstallShield 2008 or InstallShield 2008 Stand Alone Build Engine installed. Visual Studio 2005 is not required.

Update the TeamProject Property to reflect which TFS Project you added the files to. ($/PROJECT )

Update the DropLocation Property to reflect where you want the builds dropped/archived.

Commit your changes and run a build. When it's all done you should see a good build with an Install folder containing Setup1.msi and a Release folder containing WindowsApplication1.exe.

How It Works in the context of InstallShield:

This sample uses standard TFS TeamBuild solution based build concepts. I don't like to use Project Output references so instead I use an xcopy post build command in the C# project to drop the $(TargetPath) into a folder underneath the InstallShield project directory. I also use Project Dependencies to make sure the C# code compiles first.

InstallShield 2008 has built-in MSBuild/VSIP support. In addition to the standard XML .ISM project, there is an MSBuild file called Setup1.isproj. This document teaches MSBuild/TeamBuild/Visual Studio how to interact with and build the .ISM project. Basically it matches your solution configuration manager settings to the InstallShield Product Configuration/Release settings.

Finally I've instructed InstallShield to do a postbuild event and copy the MSI to ISProjectFolder\..\..Binaries\Install. This allows TFS to include the MSI as part of it's BinariesRoot Drop pattern.

What's Not Included:

This is a simple example and doesn't implement advanced patterns like versioning the ISM/MSI. In my day job I import a build_install.config project that overrides the BeforeCompile target and inserts a call to a custom build task called VersionInstallShield. This task uses COM Interop Reflection to invoke the InstallShield SAB automation interface and update the ProductVersion property of the ISM before building.

WS08 Certification Requirements: MSI Not Required

I love good tools, but I love great practices even more. I dislike it when people think tools are more important than practices. My friend Paul Duvall says it better then me:

However, having a tool synonymous with a practice can be bad thing because people can get carried away with the various bells and whistles different CI servers provide. Don’t get me wrong, I’m a big fan of CruiseControl and other CI servers, but let’s not get lulled into thinking that the tool is what provides the practice. Vendors may want us to think this, but we’re smarter than this, right?

So while I love MSI, I love it as a tool that implements sound practices... practices that can also be accomplished using other NON-MSI tools.

So with that in mind, a friend recently forwarded me this email stating that Windows Installer is being dropped from WS08 Logo requirements.

From: Meg Muran (Corestaff) [mailto:]
Sent: Thursday, September 06, 2007 4:34 PM
Subject: PLEASE READ: Change in WS08 Certification Requirements
Importance: High

MSI installation is now RECOMMENDED/OPTIONAL and no longer REQUIRED. This should make your development team very happy if, like many ISVs, the MSI installation requirement has been blocking your path to certification.

The following language (or something very similar) will replace the existing section of the certification requirements documents and tools available at As always, is the technical support alias you should use for all certification-related issues.

Installation requirements in detail
2.1 Installer related requirements
Use Windows Components for Installation.

Using the built in installation engines creates consistent, reversible, transacted installations. This ensures the quality of the user's application experience upon installation and throughout the software lifecycle.

Ø It is optional and recommended that application use use the Windows Installer (MSI) or ClickOnce for installation. When using Windows Installer, Installation packages must not receive any errors from the Internal Consistency Evaluators (ICEs) listed here:

1-24, 27-31, 33-36, 38-57, 59, 61-63, 65, 67-72, 74-84, 86-87, 89-94, 96-99

Warnings represent design guidance to the package author which should be studied for applicability. Any warnings that do not apply or will not be fixed must be documented.

If your applications setup is a non-MSI based setup it must be clearly documented as part of the Logo submission documentation. If any generic installation requirement outlined in this document applies to your installer, then they must be satisfied as well.

Additional Information

A variety of third-party tools are available that can be used to create Windows Installation packages. The ICEs can be run from the Orca application, which ships with the Windows SDK.

For information on ICE, see:

Ø Support command line installation

Applications must support command line install uninstall. This applies to applications regardless of the use of Windows Installer.

Applications using Windows Installer must successfully install in quiet mode via a command line with /qn switch.

All command line options for install uninstall must be clearly documented.

Meg Muran (Corestaff)
Windows Server Marketing - Logo Team

Thursday, September 6, 2007

Hatch Chile and Artichoke Dip

Being a Deployment Engineer ( just fancy way of saying Build/Install Automation Dude), I'm a real stickler on repeatability and process/procedure. After all, one day I might be working somewhere else and the show must go on. Those who have worked with me know I love to cook and my coworkers love to eat. So frequently I'll even check my recipes into source control just to make sure that everything will go on if/when I get hit by the next bus. With that said, here is a wonderful recipe from Central Market. I don't see a copyright on it and I'm tired of losing it around the house.

Hatch Chile and Artichoke Dip ( transform applied to original recipe )

2 T. Butter
2 Cloves Garlic, Minced

1 Can Artichoke Hearts, Drained and Chopped
1 pkg Frozen CHOPPED Spinach, thawed and drained
2 Hatch Chilies roasted, skinned and cleaned then pureed
8 oz Lite Sour Cream
8 oz Lite Cream Cheese

8 oz Hatch Shredded Monterrey Jack Cheese

Saute garlic for several minutes. Reduce heat to medium. Add next 5 items and mix well. Stir in cheese until well melted.

Now just rip open a bag of your favorite tortilla chips and announce that the build is ready. This dish is best served right away.

Continuous Integration

Paul Duvall has just finished his newest book Continuous Integration: Improving Software Quality and Reducing Risk. It's published by Addison Wesley and is part of the Martin Fowler Signature Book collection.

Paul and I are good friends and we spent many years in the trenches together back in the 1990's when I worked in Virgina. It would be accurate to say Paul was one of the few architects that I've worked with over the years that really understood the importance of creating a strong development infrastructure for supporting development and designing/constructing applications for deployment/production. Simply put, we learned how to integrate and deploy systems make easy. This was over 10 years ago when concepts like Agile, XP and CI were in their infancy.

So congratulations on the new book Paul and BTW, thanks for dropping my name in the preface. :-)

Wednesday, September 5, 2007

Stream Explorer

We all have our bag of tricks.... Regmon, FileMon, Depends to name a few... well today I have added a new one: Stream Explorer

This little utility comes in handy to identify streams added to files as recently discussed on Stefen Krueger's blog.

I really dislike security by obsecurity and I find it really annonying that downloading the same file in two different ways will generate a file that has the same MD5 hash but will be treated differently by Windows. However, that's the way the world works.

Wednesday, August 29, 2007

Learned Something New: CHM on UNC Behavior

Stefan Krueger emailed me asking if I had problems viewing the new MSI.chm. To be honest I hadn't even looked at it yet ( despite my moaning earlier this year about not having access to to it ) because I've been so swamped with recent changes at work and the struggle my wife is going through.

After finally downloading the file and testing it on a clean virtual machine, I stumbled onto the fact that the CHM wouldn't work from a UNC path but that it would work when I copied it locally.

So I did some searching and I found a KB article from Microsoft pointing in the direction of a change to CHM behavior in security bulletin MS05-026.

I had never noticed this behavior before. I love learning something new every day. Now off to read the MSI.CHM and learn a few more new things.

Monday, August 27, 2007

Who Had Some Fun This Weekend?

A recent post by Rob Mensching made me wonder a question:

What cool fun did you do this ( or a recent ) weekend?

You you know I'm what is called a Foodie. Fortunately or unfortunately, I love to eat. Since moving to Texas, I've really grown to appreciate peppers like I never did before.

Poblano, Green chili, Serrano, Jalapeno, Habenero and Scotch bonnet. While I do like the heat ( as anyone who has had my Jamaican Jerk Chicken can attest ) I really like to get past the heat and enjoy the flavor of the pepper.

So my fun for this weekend it was all about one word: Hatch

You see, as the summer winds down it's that time for the annual harvest in a small New Mexico town known worldwide for this yummy peppers. While I can't make it out there to the festival with my father in law ( who lives in ABQ, NM ) I can certainly stop by Central Market and load up. And load up I did! They sell the peppers preroasted but it's just not as fun as doing it yourself. So I spent hours roasting, steaming, skinning and cleaning peppers. Some I used right away for green chili hush puppies, green chili remoulade and green chili tarter sauce. The next day I made green chili guacamole for a seven layer dip. But most of it will be frozen to provide an endless supply until next year.

Of course I also picked up all kinds of goodies like green chili pork sausages. This ensures that when friends and family come to visit to help take care of Cheryl, we'll have plenty of fun foods to grill and eat together.

So don't forget, post a comment telling me about your fun weekend.

Tuesday, August 21, 2007

Time for Change Again

Well, it's been about a year since I changed employers so I guess it's time for my next move.

I'd like to say goodbye to my friends at Hart InterCivic and say hello to my new friends at Manatron.

Well, kinda.... It seems that my group has been purchased so I'm not really going anywhere other then on paper. Well, kinda... we will be moving to a new building.

For anyone who's curious, I've been trying to count how many jobs I've had over the years and I can't because I can't decide on how to count a job. The answer is somewhere between 7 and 11 though with the longest being 2.5 years and the shortest being 3 months.

Thursday, August 16, 2007

FormatMessage Bug?

A recent thread in the PlatformSDK.MSI newsgroup involved a question on why calling FormatMessage() for MSI errors above 1644 didn't return a message.

I had never noticed this before and I'm at a loss other then to wonder if it's a bug in Windows. I tried InstallScripts FormatMessage() wrapper and I wrote up a C# class that DllImports Kernel32.dll to call FormatMessage(). Neither work... I havn't tried on Vista yet.

Has anyone else ever seen this before?

Tuesday, August 14, 2007

BUGBUG: Yikes!

Black and Yellow Argiope
Argiope Aurantia

I couldn't help taking a picture of this scary looking, yet harmless spider this morning. It's the coolest thing I've seen in awhile so I'm going to let it live what's left of it's short life. Regardless, it's a fitting picture for my thoughts today.

I've been getting contacted by fellow developers thanking me for noticing the InstallShield COM Extraction bug. I did a dinner/movie with a former coworker who expressed relief that this was found.

But the truth is, I didn't catch it, I just finally noticed it. Others have been stung much worse and I'm suprised that given the severity of this issue, that Macrovision hasn't been more proactive in raising attention to this issue. The annoying Update Manager popped up on my screen today and it wasn't listed. There wasn't a DevLetter style email, or anything else.

I decided to do a search of Community and I found this interesting thread:

And just to prove history repeats itself, this has happened before:

BTW, I don't know about you, but when I encounter the same bug more then once, thats a clue to write a unit test. Perhaps my next blog will be an InstallScript ICE that checks for scary registry table entries. Until then, remember two things: Always use an integration test machine that you can virtualize or reimage and always test your uninstalls.

Friday, August 10, 2007

InstallShield COM Problems

In a recent blog I spoke about a nasty experience that I had and a hotfix that was available in IS2008.

I've been thinking about it more, and I realize that I actually experienced that problem using IS12! What this means is that while the hotfix is available for IS2008, IS12 users are actually at risk also. The KB article says that it applies to IS2008 but it should also say that it applies to other versions since the work around notes state:

For users who are not using InstallShield 2008, please use the following steps to work around this behavior:

Disable the 'COM Extract at Build' property for the component with the '*' character in the 'Name' column of the registry table
Locate the 'Advanced Settings' -> 'COM Registration' view of the component
Right click on 'COM Registration' in the middle pane, and select 'Extract COM Data for Key File'
In the Direct Editor, locate the offending entry with the '*' character in the 'Name' column of the registry table, and delete it.

A hotfix for IS12 would be good, but to be honest, I don't reccomend using COM Extract at build unless you always plan on doing Major Upgrades and you know your COM components don't have binary compatibility.

Thursday, August 9, 2007

InstallShield 2008 HOTFIX: COM Extraction Causes System Corruption during Uninstall

About a month ago I was working on an Installer for a North-Texas company when I did something I would normally never, ever do.... install/uninstall an untested prototype install on my dev box. The results were horrific... my entire network stack was trashed, all kinds of services weren't running and I actually got a message from Windows Vista saying something to the effect that a certain error that should never occur, occurred.

I looked at my package to see what could have happened and I noticed some TCP/IP settings had been picked up as part of a COM Extraction. I grabbed another laptop, transcribed the data and rebooted and all was well. Whew... bad setup developer!

I didn't think much more about this because at my day job we have almost no COM in our solution. The Server Installs ( Web Services and WebUI ) are pure .NET and the client only has some third party controls that we interop with. But all of those COM servers were authored in InstallShield 12 with the Right-Click Extract COM pattern. They never had a chance to be butchered by IS2008.

Then I came across a KB article today that described the exact situation that made me lose a few heartbeats.

I'll let you read the article, but basically it described a situation where the COM Extraction didn't filter well enough and that there is Hotfix available. I'd pick this one up for sure....

Sunday, August 5, 2007

.NET CA's are NOT (always) Evil

I recently came across this post on the WiX-Users mailing list:

Be very careful using C# within a Microsoft Installer based installation(like those generated using WiX). By doing so, you place an additional dependency on the .NET framework, and has been discussed many times this is a *bad thing*. Ideally you should choose something (e.g. C++) that can be built to have minimal (ideally no) external dependencies.

I couldn't disagree with this poster more. Adding the .NET framework as an install time dependency is not automatically and blanketly a "bad thing". It is increasingly becoming an "inevitable thing". After all, how else would you publish assemblies to the GAC? How else would you PreJIT assemblies?

I would agree that it's a bad thing to do things like use Installer Classes to use the framework to install services when MSI is natively capable of doing that, but not just because it's a MC CA, but because it's an unneeded CA in general.

The reality is we are now starting to see new API's that have no unmanaged counterpart. We are having developers write managed code and they are now business requirements for doing things that can only be done in .NET or are done in with 95% less effort in .NET.

We can bury our heads in the sand and repeat the '.NET is Evil' group think, or we can get with 2007 and start using .NET to our advantage and demand that the Windows Installer team do the same. Otherwise MSI's days are numbered.... remember after all that only about 50% of the setup space has switched to MSI. Other technologies are still out there.

Wednesday, July 25, 2007

Cancer Sucks

I'm having a hard time writing this blog, so let me just ask for your prayers again. My wife's cancer has returned and spread to her liver and lungs.

Tuesday, July 24, 2007

Beyond Tao of the Windows Installer

I was recently reading a blog posted by Andreas Hiltner where they made the complaint:

All of a sudden, InstallShield just died and rendered the whole binary project file useless. 6 hours of work down the drain. Of course we saved early and often, but I did not make backup copies of every single step.

It never fails to amaze me how setup development is treated as a second class development activity and relegated to second class processes. Coding without a version control system and build automation is frankly like jumping out of an airplane without a parachute. You might get away with it for awhile, but eventually you'll crash into the ground in a horrific way.

The Tao of the Windows Installer Rule # 7 only partially addresses this:

Rule 7: Work On a Copy
"My file server won't boot and I really need it up and running now!"
"Ok, let's re-install Windows and restore the data from backup."
"What backup ...?"

Been there? Done that? While losing a single MSI package might not be as disastrous as losing your file server, you really don't want to start from scratch because of some accidental corruption.

So, always make a copy of your package before you start work, then work on the copy. That way, it is easy to revert to a known good version if the working one becomes corrupt or has other problems you cannot easily correct.

Unfortunatly this rule assumes that you are editing your packages by hand via Orca ( you've got to be kidding me ) and that you don't have any type of project source, project files and build output ( package ). Editing built packages with ORCA would be something like making IL changes to a compiled .NET assembly and then making copies of the assembly as checkpoints. Again, you've got to be kidding me.

So what should Andreas have done? First, InstallShield can save it's project in XML format via a setting in the Product Information section. Second, the project should have been checked into a source control repository from the moment it was created. Third, build automation should have been wired up from the moment that the project was checked into source control. Now you have your parachute and it's safe to jump out of that perfectly good airplane.

Where I work I have a standard pattern that supports of all my installs. It literally doesn't take more then 10 minutes to get a first time build going for a new setup project. From there anyone on the team can use TFS Team Build to request an install build. Anyone with InstallShield can also check out the source, make changes, and if desired checkin a shelveset and ask for me to peer review it before committing it to the branch.

Thursday, July 5, 2007

Managed Code Rocks

Back in my EDS days I spent a couple years on the Continental Airlines account. They were mostly a VB6 shop with a few groups exploring C# on .NET 1.0 and 1.1. I didn't really know anything about managed code back then. I remember an excited yet sarcastic comment that my manager made about managed code `solving all of our problems`. I couldn't tell if he was being a fan boy or if he was being sarcastic. Maybe both? I think it was the former since he later mentioned during a team meeting that we should all learn C#. A coworker and I stared at each other and later each other `Why?`. You see, this was an IT group and out of the 20 some people in the room, I don't think more then 4 of us actually programmed in ANY language. Regardless we continued working in VB6/COM and didn't think a whole lot else about it. Times were different back then... we owned the entire enterprise so I could actually deliver a prereq package to provide our own framework for CA support. Then our InstallScript CA's simply had to call the COM interfaces to do our dirty work. Not something I'd do in an ISV environment, but it worked for us.

At my next job I saw exactly how ugly Installer Class custom actions were. For awhile I bought into the `managed code custom actions are evil` hype that is constantly repeated by the same three or four people. Then my new manager announced that I'd be spending a week learning C#/.NET 2.0. For the life of me I really couldn't understand why I was going to spend a week learning .NET. After all, what possible place could managed code have in Setup after the hell I had just witnessed? In my mind the future was unmanaged Type 1 CA's written in InstallScript since C++ is just pure hell. I even had an expert C++/C# developer validate that opinion for me.

So I went off and I learned C#/.NET 2.0. Wow, it rocks. Once I really understood it, I came to realize that it could be easily and safely used as a platform for custom actions in MSI. Frankly, C# makes horrific things in C++ look like childs' play. Take this little quote from the WiX-Users list that I recently read:

I realise that [not using managed code] leaves you with few options, since as far as I can see
the web service is the supported API for doing this. Normally for custom
actions we recommend using unmanaged C++, but web services aren't at all
easy to use from C++.

Last September I started another job ( I know... I move around a lot ) and I wanted to implement a pattern that took user input and connected to a server to validate the data. I quickly wrote a C# class in VS2003 that was exposed as ComVisible(true) and exposed an interface for passing data to a webservice and returning the result. Then I wired this up using InstallShields CoCreateObjectDotNet() function. This function basically allows invoking ComVisble .NET classes through reflection without actually having to register the COM for interop.

In the countless times this install has been run, I have never seen or heard of this custom action failing, period. Sure, now I have to deploy a .NET framework, but I did anyways because our software requires it.

Now I've also heard the argument that our CA could fail one day in the future on a newer version of the .NET framework. After all, in the COM->.NET story the latest version of the CLR is used. When I started this story our application was written in .NET 1.1 and later ported to .NET 2.0 and tested on Vista with .NET 3.0 ( CLR 2.0 ). My CA was built using .NET 1.1 and I've never rebuilt it for 2.0. It just works as is on 2.0.

The only advantage that I could give C++ in this story would be faster instantiation and less memory usage. I won't agree that C++ is any more reliable then C#. In fact I would say that unless you have a very experienced C++ developer who will make sure that all errors are handled and memory properly allocated, free'd and buffers protected from overruns, that C++ could actually be less reliable then C#. I'd also say that unless the forementioned person worked in some third world company for dirt cheap that writing the code in C++ would be more costly then writing it in C#.

So if you have similar needs, I encourage you to explore managed code and not buy into the `managed code is evil and doesn't belong in setup` myth.

Saturday, June 30, 2007

Toshiba A135-S2386 for $449.99

My wife's 3 1/2 year old Compaq X1050US ( Centrino ) finally bit the bullet. Well, the LCD display did anyways... it's now been transformed `desktop` thanks to a 19" CRT that we had sitting around. We paid about $1200 for it back in the day. Last fall I purchased a Gateway MX6920 ( Core Duo T2050 w/1GB ) for $800. I was getting ready to purchase a new Gateway MT6705 ( Core Duo T2080 w/1GB ) for $600 when I noticed the Toshiba A135-S2386 ( T2080 w/512MB ) at Bestbuy for $449.99. My sister in law also needed a new laptop so I needed two.

The problem was, they are all sold out. But wait, for some reason ( as of today ) BestBuy in Killeen and Waco have dozens of these puppies. So on my way back from Dallas I picked two of them up fo less then $1000 out the door with tax. 512MB isn't nearly enough so I've given up the 2 512MB modules from my Gateway and will be getting in 2 1GB modules from NewEgg in a couple days.

Man, hardware sure does get cheap..... Anyone in Central/North Texas who needs a good solid budget laptop should really give these two stores a call while you can.

Wednesday, June 27, 2007

Microsoft: Make WiX a priority

I've been following the WiX-Users list where Neil Sleightholm politely started a new thread titled `How do I submit code? Do you want my changes?`:

I have tried to submit code changes to WiX but no one seems to respond. Here is what I have done:

- Applied for a “assignment agreement”, heard nothing…
- Applied for a “assignment agreement”, heard nothing…
- Applied for a “assignment agreement”, heard from Microsoft asking me to help with a new system. I helped, submitted the “assignment agreement”, heard nothing…
- Ok I thought, you guys have better things to do than paperwork, so I worked on a code change to fix a bug in the NAnt task. I submitted a bug (1715295) and followed the advice given here to email the devs list. I did this on 9 May 07 so I don’t think I am being impatient but you guessed it, heard nothing…
- Not one to give up I tried again. This time I submitted a bug (1715298) with the code to fix it. Again, heard nothing…

So what do I have to do to get code accepted? WiX has made making installs much simpler for me and I have 2 clients using it on my recommendation. I would really like to contribute to the code but don’t want to spend the time doing it if there is no way of getting the code accepted (or rejected).

Bob Arnson (MSFT) replied:
It's all a matter of time and priority. At the moment, Rob's the only person who looks at external contributions so we can't load-balance. Your fixes look fine but they have workarounds so that's pushing them down the list too.

To which Neil replied:
Bob, Thanks for your reply but it doesn’t really answer my question. Submitting code and not hearing anything for 6 weeks is a bit demoralising. Virtually every day on this list someone writes a comment along the lines of “if you can fix this please do” but it sounds like you don’t have the capacity to accept code. It would be nice if there was a process for submitting code so at least we knew that our contributions had been received. On other open source projects I have worked on it was easier to submit code.

So my question still stands, do you really want my changes? I appreciate you all have day jobs and this is part time but the same is true for us and there is little point in submitting code if you don’t have time to look at it. The longer the delay is between submitting change and the code being reviewed the harder it is for you as our changes could be based on an old code base.

To me this is a symptom of FOSS. It's a symptom of giving a fine software engineer program management responsibilities and then giving him very little time to do it all. It's a symptom of not being responsible to concrete customers and budgets. It's a symptom of combining the control freak aspects of the `Benevolent Dictator` model with the control freak aspects of super-megacorp needing all the legal I's dotted and the T's crossed with `assignment agreements`. At the end of the day you have dozens of people wanting to help, either with design suggestions or actual code merges, but so few people in the inner circle that very little actually gets done. What should have been accomplished in months takes years.

The irony is that Rob Mensching once posted this rant against InstallAware:
Yet InstallAware the company is directly benefiting from the many, many volunteer hours people in the WiX community have put in creating, discussing, debugging, and releasing the WiX toolset. Nothing wrong with that, the license is written in such a way to enable that very thing. But I think that InstallAware is missing out on a huge opportunity by choosing not to participate in the WiX community (the very people who are most likely to want such a product) until the product proves "commercially viable". There has been absolutely no discussion about WiXAware on the wix-users mailing list.

Given how Rob says he is `100% not the target ( of a GUI designer )`, and that design suggestions and code submissions go completely unnoticed, how exactly can you be upset at InstallAware for not `participating`. ( Which really isn't true.... I've seen K-Ballo (InstallAware WiXAware lead) participating on the mailing list... he just doesn't announce who he works for. )

WiX has done great things, but there is clearly a log jam here. The solution is pretty simple to me and I've rambled on about it before:

But what if Microsoft just threw a bunch of money at InstallAware and bought them? What if Microsoft was to tell Rob Mensching that he had a staff of developers and that they wanted to transform WiX into a full fledged open source enterprise installation authoring tool capable of competing with InstallShield toe to toe?

And what if all of this was to be targeted for Visual Studio Orcas so that when you bought Visual Studio you'd be completely covered for deployment?

Monday, June 25, 2007

Smarter TFS Incremental Builds

Anyone who does a search for TFS Incremental Builds is bound to stumble across this MSDN page that describes controlling TFS's CoreGet with the following properites:


The problem that I notice with this though is that it fails when you are running the build for the first time and the workspace has never been initialized. This is normally not a huge problem except that I recently I needed to create a BuildType that involved performing a full nightly build and on demand incremental builds. I needed a way to conditionalize the behavior.

Then I realized that I could simply have my schedule task delete the build workspace if I could get my BuildType to be smart enough to prime the pump when the build didn't exist. The result is this simple change:

<PropertyGroup Condition="Exists($(SolutionRoot))">

If the directory is missing, the BuildType defaults to performing a Full Build and if it already exists, it defaults to performing an Incremental Build.

Sunday, June 24, 2007

MSI 4.5 and the `Better Together` Pattern

I once designed for a previous employer a bootstrapper that supported a very complex and seamless story for chaining together dozens of setup prerequisites in different combination to support dozens of different products. They were a Product Line Development shop ( with a whole lot of custom engineering efforts also ) that aimed to bring different assets together to create new solutions very quickly. My readers who still work at this blog know just how far we took that design.

So with Merge Modules and Concurrent Installs being officially dead and evil, and each new Microsoft product needing to integrate the experience of deploying more and more reusable components, it really comes as no sup rise to me that Microsoft is finally tackling this issue.

In the "Agility Trends in Packaged Software" white paper by Robert Flaming (MSFT Windows Installer Program Manager) one little section caught my interest:

Your tools vendor may be your first choice in your Better Together path and could even be your conduit to spectrum of software providers that want to provide you a Better Together experience on their software.

We are in a bold new world, and there is a lot to digest in the white paper, but I'm already wondering what kind of standards will be established ( ICE's, Logo Certifications ectera ) to help ISV's develop micropackages that can easily be composited into a Better Together solution. I also wonder if tools vendors like InstallShield are really the best candidates to establish these practices as it could cause problems when multiple ISV's try to integrate their packages and find out that they are somehow incompatible due to design reccomendations from their competing tools vendors.

I really don't know how this will go down yet.... there is alot of information that has been shared privatly with tools vendors yet deemed to secretive to share with actual front line setup developers. Maybe 4.5 will have a strong enough contract that this problem is mitigated and maybe it'll be too loosely defined as to have the innovation come from the tools vendors and lead to exactly this contract.

Either way, if you find yourself supporting installation stories like I described, or if you see yourself selling software that might be consumed by ISV's that support this story, you really owe it to yourself to start reading over MSI 4.5.

Google Coming to Austin, TX

I was lighting up the grill with some friends last night when my friend Ben mentioned something about Google coming to Austin, TX and that he knew that the new Engineering Director was looking for people. I recalled to him that I'd seen a job posting for an InstallShield integration position but that I had ignored it because it was in Mountain View, CA.

Later I google'd for news and I found this blog article.

<ShamelessPlug>I know from my http referer logs that Google sometimes comes by here. If so, I'd love to hear from you!</ShamelessPlug>

Friday, June 22, 2007

Bootstrapping your product with IExpress.exe

I've been following a thread over on WiX-Users entitled `msi to exe` where Afshin Sepehri ( MSFT according to his email address ) asks:

How can I convert an .msi file to .exe?

Now when I first read this I just kind of laughed to myself.... Here we go again... reinventing the wheel because WiX doesn't have a decent bootstrapper like InstallAware and InstallShield. But then the first round of answers poured in:

John Vottero:
Use IExpress.exe. You probably already have it (it’s part of IE).

Wow, my eyes popped open wide. IExpress is meant to be an administration kit for rolling out IE across an enterprise. Surely Microsoft didn't intend for it to be used as a bootstrapper by ISV's. So I had to go look at the EULA

Well again, IANAL... however this seems highly suspect. The license agreement clearly states that this product is for making customized installations of IE for internal distribution or external for companies like ISP. The concept that this would wrap up some other completely unrelated software seems to be flat out against the EULA.

So I asked the question to the group: Is this Legal? The answer surprised me.

John Vottero:
You don’t redistribute iexpress.exe, you redistribute the output of iexpress.exe. I still don’t know if that’s legal.

Wow... splitting hairs, acknowledging that the legality is uknown, yet recommending it's use for packaging an MSI. The conversation continued and it seems that IExpress.exe has leaked out of the IEAK and is now part of Windows itself.

It still seems strange, it's still not a good enough bootstrapper to support my needs, but I'm starting to feel safer about using IExpress.exe. Partly because of a TechNet article that described using IExpress.exe to compress some files and add to cmdlines.txt for a sysprep postinstall step.

I guess it's ok to use, but still a strange road to get here.

Interesting and Uninteresting Comments

I enable anonymous comments on my blog because I understand there are times that people have interesting things to add to the discussion and they either don’t want to be bothered to register an account or perhaps they just want to remain anonymous. Sadly this sometimes means I get rather uninteresting ( aka rude ) comments from anonymous users that must be moderated. Most of these negative comments seem to originate from a particularly hateful person a certain company in Bedford, MA ( remember, YOU are not really anonymous on the Internet ) but I digress. The real purpose today is to touch on an interesting question an anonymous reader asked:

Very interesting, Chris. Did the question of business ethics come up at all? InstallAware has had some really bad press recently...caught stealing other installer website designs, then using those situations to showboat, which seems a bit dirty. It would be interesting to hear what Sinan had to say about that in person that would convince you he was worth spending 5 hours with.

That's a very fair question. When Sinan first emailed me I have to admit I almost felt like turning down the invitation to get together. When I mentioned it to my wife she remembered the `oops they did it again` and `all’s fair in marketing and war` threads and got very concerned that I was meeting with Sinan and worse, was I considering working for them instead of Macrovision?

I did have a bad feeling in my stomach, after all it as InstallAware's Michael Nesmith who once accused me for being on the take with Macrovision because I've been published by Macrovision in the DevLetter series. I assure everyone, Macrovision has never given me a penny. I write for the benefit of fellow developers. I love meeting with anyone who has a love for setup. So I decided to accept the invitation and go there with two goals::

1) Keep an open mind on how InstallAware technology attempts to solve setup problems.
2) Attempt to communicate user stories that I feel today's authoring tools don’t do a very good job of supporting.

With that in mind, we had a very good back and forth technical discussion for about 5 hours. It was not until the last 20 minutes or so that we started discussing the `politics` associated with the small world of setup. I didn’t throw Sinan any softballs, but I also didn’t try to hold him to the fire. I listened to his perspective and I shared a few of my concerns. But I would not say any of this was framed as `ethics` questions or debates, but more just an exploration of the relationships between different people/groups and what could be done better to further the goals of all involved. After all we are all different. We are all trying to solve different problems with different methodologies. Some of us are trying to improve an install, some of us are trying to run a business, some of us are trying improve an installer tool, some of us are trying to improve an installer SDK for installer tools and users to use. Regardless of where we fit, we don’t always agree on how it should be done and sometimes the internet brings out the worst in us. Frankly I’d rather smooth the waters and get back to having good conversations with anyone who cares about setup.

I don’t know if that actually answers the question the anonymous commenter had so feel free to ask follow up questions. I may or not be able to answer as there were some aspects of the discussion that I'd like to keep confidential as to not stir up trouble with third parties that were mentioned.

Wednesday, June 20, 2007

Dealing with very large number of files

Allan Bommer recently asked on the WiX-Users list:

The one item I am worried about is managing a very large number of files. Our application’s Help directory contains about 1500 files (html, gif, etc). It seems the only way to get these files installed is to list them explicitly (with some help from Heat). It also appears that it is suggested to make each file a component.

Explicitly dealing with 1500 files and their component GUIDs seems likely to have a very low ROI for the programmer and company. I’m sure my clients would rather have me crank out a few useful features in the application than spend countless hours on all those individual entries. Perhaps if you have a million clients, then dealing with all those files individually makes sense, but with 100, 1000 or 10,000 clients, the cost-benefit ratio doesn’t look very good.

Allan hits on one of the weaknesses of the declarative design of Windows Installer. Rich metadata describing the behavior of the contents and behavior of the installer has the huge downside of having to author that metadata and keep it in sync with the ever changing world. The upgrade servicing patterns also require that you be absolutely perfect in how you do this. One component rule violation or primary key column change across dozens of builds will result in undesired servicing behavior.

Allan then asks ( in his own way ) about dynamically linking the files. Dynamically file linking will generally work but it has several downsides:

The most important downside is the possibility that a file should be in the package, but that it was not where it was supposed to be at build time. If the file was described declaratively this would be a build break. But with dynamic file linking, it simply isn't linked and now we have a potential runtime break.

The second downside is that it's very difficult to perform minor upgrades and patches due to the dynamic nature of the component authoring. Some tools like InstallShield have patterns for mitigating this, but it's still a crap shoot.

The third downside is that your build will take A LOT longer to perform since it's not only creating your package but that it's also authoring and validating your component definitions.

But I think there is a third way to go about this and I probably spent at least one of my five hours with Sinan Karaca touching on this subject: Use authoring tools with very rich component wizards. InstallShield has one, but it's not nearly good enough in my opinion. Here are a few attributes that would make it better:

`Deprecated Component` instead of Deleted Component. Minor upgrades can't remove a component and it's keyfile, so instead you take advantage of Transitive Components and NOOP conditional expressions along with a 0 Byte file in the media. This allows a developer to safely remove a component without worrying about which upgrade pattern will be used to service the installation.

Better definition and control over the concept of `Best Practices` when authoring the components. On MSDN you will find 2 very different definitions of best practices for componentizing files. The MSI team breaks things by directory and COM servers with all other files being allowed to share a component as a designated key file and companion files. The Visual Studio team takes a different approach that every file should be a key file. To be honest, I see ways in which they are both correct. A properly behaving component wizard shouldn't simply ask `do you want to follow best practices` as if it is a black and white decision. It should offer you a choice of those two best practices and a custom mode where you get to decide for yourself. The point is when I have some ASP.NET developer adding files I don't want him to have to understand the component rules. I don't want him to need to understand that default.ascx is the keyfile and background.png is the companionfile. He just needs to know that he can update either file and he can expect to see his changes on the server after the installation is executed.

Another feature that a good wizard should have is the ability to automatically detect changes between the currently authored components and the directory structure that it is syncronizing. We are talking easy button here: Rescan Components followed by "I see these 5 new files... would you like to add them?" or "These 5 files are missing, would you like me to deprecate them?"

MSI might be complex, maybe more then it needs to be, but there is value in it's patterns. It's just time that we have authoring tools that makes it a hell of a lot easier so that Allan doesn't have to be pointing out the obvious ROI problems associated with it.

Tuesday, June 19, 2007

Flashback: A trip down memory lane

I was reading over on Aaron Stenber's blog about Microsoft using Virtual disks to ship windows and applications and it reminded him of the old days when Microsoft would just ship preconfigured hard drives instead of installs.

I recall that at my last job that they really weren't that far removed from the practice. Going back further ( 1996 Windows 3.1 days ) I once invented a tool while I worked at Electronic Data Systems called `The Cookie Cutter`. This tool was a bootable ISO9660 ( not easily done back then.... you had to be comfortable reading the El Torrito spec and using a Hex editor ) that started up MSDOS and ran a compiled QBasic program that I wrote.

The program would present a series of configuration screens to select an image to load and needed TCP/IP settings. We could select from 18 different configurations ( Banyan, FTP PC-TCP, SmartTerm IP, Novell, MS-TCPIP ), then it would automatically fdisk / format / extract and configure all the needed INI settings to configure the machine. Funny, even back then I wasn't afraid of configuration data being a pain. The only real pain was when 10+ people lost their jobs because of the efficiency improvements in our work flow. I travelled a lot back then and this is what started me down the path of setup. It was sad that we choose to clone our workstations instead of install them because our installs were so bad back in those days.

The other funny thing is that Microsoft seems to think that virtualization is new. The fact is I used to be a rabbid Amiga addict. I actually learned how to install and configure MSDOS/Win 3.1 by using PC-Task to emulate an x86 PC. Sorry American Megatrends, please don't ask where I got a BIOS image from..... :)

Going way back, my first computer experience ever was actually quite embarrassing. My older brother had a friend who owned a Commodore Vic 20. He gave me a book to read and sent me on my way. When I returned he tested me with a simple question. You have a program in memory and you want to erase it, what do you do? The correct answer was to type NEW. I hadn't read the book so I simply reached for the power switch and toggled the power. Not too bad for a 7 year old I suppose.

Despite my less then stellar start, my parents decided to get a Commodore 64 and it all started with Microsoft Basic 2.0 & 6510 Assembler on a Commodore 64. Ahh the Commodore 64 Advanced Programmers reference manual.

It's funny to think that I've been coding for over 25 years and that Microsoft has always been there... whether I wanted them or not. How things change and yet stay the same.

Yes WiX, I really DO want to do that...

Consider this MSI fragment( created in Orca and transformed to XML by MSI2XML ):

<table name="InstallUISequence">
<col key="yes" def="s72">Action</col>
<col def="S255">Condition</col>
<col def="I2">Sequence</col>

It's not a real installer, it's a `fake` MSI that was created just for fun and just to show what Windows Installer is capable of doing once you free yourself from coloring between the lines.

Now MSI2XML can easily round trip the table data without passing a whole lot of judgement. Just for fun I thought I'd see what it's like in WiX to do this. I take the XML and reconstitute the MSI and then use Dark to create a wxs project. Now WiX takes lot's and lot's of issues with the source even though it is a perfectly formed MSI database that will actually do what it was intended to do. Let's ignore most of this for a moment and talk about the Sequence tables.

In my XML you'll notice that only the InstallUISequence table is defined and it's pretty sparse..... it only contains a single action, a call to a UI Interface Wizard called Dialog1 (yes, unique name I know...)

Now note the XML that dark creates to represent this:

<Show Dialog="Dialog1" Sequence="1" />

This snippet sounds like what I describe, right.... a single sequence with a single action. But that's not what candle/light does with it. It automatically goes and creates:

AdminExecuteSequence ( 8 actions )
AdminUISequence ( 4 actions )
AdvtExecuteSequence ( 7 actions )
InstallUISequence ( 6 actions instead of 1 )
InstallExecuteSequence( 13 actions )
In order to get a successfully round trip'd resultant MSI ( pedantic error checks for the time being ) the XML actually needs to look like:

<CostInitialize Suppress="yes"/>
<FileCost Suppress="yes"/>
<CostFinalize Suppress="yes"/>
<ExecuteAction Suppress="yes"/>
<AdminExecuteSequence >
<CostInitialize Suppress="yes"/>
<FileCost Suppress="yes"/>
<CostFinalize Suppress="yes"/>
<InstallValidate Suppress="yes"/>
<InstallInitialize Suppress="yes"/>
<InstallAdminPackage Suppress="yes"/>
<InstallFiles Suppress="yes"/>
<InstallFinalize Suppress="yes"/>
<CostInitialize Suppress="yes"/>
<CostFinalize Suppress="yes"/>
<InstallValidate Suppress="yes"/>
<InstallInitialize Suppress="yes"/>
<PublishFeatures Suppress="yes"/>
<PublishProduct Suppress="yes"/>
<InstallFinalize Suppress="yes"/>
<CostInitialize Suppress="yes"/>
<FileCost Suppress="yes"/>
<CostFinalize Suppress="yes"/>
<ValidateProductID Suppress="yes"/>
<ExecuteAction Suppress="yes"/>
<Show Dialog="Dialog1" Sequence="1"/>
<CostInitialize Suppress="yes"/>
<FileCost Suppress="yes"/>
<CostFinalize Suppress="yes"/>
<ValidateProductID Suppress="yes"/>
<InstallValidate Suppress="yes"/>
<InstallInitialize Suppress="yes"/>
<InstallFinalize Suppress="yes"/>
<PublishFeatures Suppress="yes"/>
<PublishProduct Suppress="yes"/>
<ProcessComponents Suppress="yes"/>
<UnpublishFeatures Suppress="yes"/>
<RegisterUser Suppress="yes"/>
<RegisterProduct Suppress="yes"/>

Now I can understand that for a real MSI would want all of those actions/sequences by default, and I also understand that some pople are going to want to quickly dismiss this use case as `fake` and `invalid`, but consider this prospective:

Shouldn't a successful decompiler/compiler story result in the creation of a binary that is identical ( or as close as possible ) to the original binary? To me it seems like Dark should respect ( and warn of course ) that this was the original configuration of the database and author XML to represent it. Instead dark seems to try to read between the tea leaves and say `well I know this is what you are, but I really think you should be this...`.

In the past I've worked on some pretty big, complex installer frameworks that delivered dozens of installers by consuming dozens of product assests in different configurations with different brandings. The frameworks are so big and so active that it's not practical to just dump it all at once and replace it with an entirely different system. You have to refactor individual layers and components while maintaining the existing contracts. While doing this refactoring I've attempted to incorporate WiX in my solutions, but unfortunatly it's been issues like what I just described that have forced me to use other tools like MSI2XML which are much more respectful of what I'm trying to accomplish.

Monday, June 18, 2007

Disagreeing with the Benevolent Dictator

I've been partially following the WiX-Users list recently when I noticed this question from Leo:

How do you define the InstallExecuteSequence table in WIX so that the standard actions PublishFeatures, PublishProduct, RegisterProduct and RegisterUsers won't show up? thx!

Oh my, I knew right away that this was stepping on a hornets nest. Anyone who has followed WiX / Rob Mensching / Aaron Stebner ectera for awhile knows that this group is pretty self confident that their way of doing this is the right way and everything else is wrong. However this is the WiX-Users list and I really don't want to troll for an argument. I decided to sit back and watch. Sure enough, Rob Mensching replied:

Why would you want to do that?

Ok, so maybe this is a case of email not conveying emotition, but I'm pretty sure what Rob was really saying that you have to somehow convince him that you have a valid reason for doing this. I've had several reasons in the past, but again, I don't want to go trolling... Then someone replies with an answer to the actual question of HOW you would do it, but continues to lecture about why you shouldn't do it. Then yet another person replies to lecture about how you shouldn't even use MSI if this is your need, go use NSIS. Ouch... yuck.

Now our original poster Leo comes back with a pretty good piece of logic... the MSI team specifically has a help topic on MSDN explaining how/why you might want to not register your product with these standard actions.

MSDN does not indicate any problems or recommand not doing this. As a matter of fact MSDN provided the instruction for omitting the registration of application at Exactly what kind issues I might get into if I do this. Please advise. Thx!

Now I've not waited long enough to see additional replies, but I already know from experience that this kind of questioning isn't going to go over well in the Wix-Users space because you have to keep in mind that what the Windows Installer team considers a `valid` MSI and what Rob considers a `valid` MSI are entirely different.

My opinion is as long as you understand what your doing and the related impact..... go do your thing. I follow most generally accepted best practices, but on certain issues I've had business requirements that require me to do something different. I personally won't listen to anyone try to dictate ( no matter how benevolent ) what my install should or should not do nor will I listen to complaints like `fake` or `trojan` MSI and most importantly I don't accept something as some immutable, undeniable best practice just because one person says so.

Mailbag: Have you seen this?

I guess thinly veiled ambigious references aren't enough because I keep getting emails from friends asking if I've seen the news about Macrovision. So yes, I know about the 7% RIF and I know about the director who picked up a nice $200,000 dumping 15,000 shares of MVSN stock. I also know about various people suggesting that a sale is in store for Macrovision. However, until people actually start flooding my mailbox with real inside scoop, I'm just an outsider looking in wondering what's going on. That said, here are some interesting quotes from a Yahoo! investment board:

From `candor2001us`

Why is this a good sign? you usually cut employees in bad times, when there is no work for them. This is not a sign of a growing company.

From `maxiumboostage`
exactly, with mvsn dropping safedisc , ripguard, hawkeye, the flex stuff not being developed any further i think its soon gonna be time that fred makes a move. he has been known to break companies apart and this is the first sign that vsn is being broken into nice purchasable chunks for any interested parties that want to buy the technology. i also heard on the grapevine that electronic "safediscs main customer" have dropped the product thus rendering it non profitable. well ill wait and see but i am standing by my predictions that its gonna be broken up and sold into chunks. bye bye macrovision.

From `josedelacruz150`
EA may or may not have dropped safedisc. That's an old product anyway in a market that's moved on.
Its never been a money maker, and its end of lifed already.
Macrovision doesn't have any real technology but it does have IP.
Wouldn't be surprised if he sacked them all and sold that.

From `candor2001us`

that's not necessarily true. You cut employees to strengthen the bottomline especially when the top line is remaining stable.....I think Fred just wanted to cut deadweight especially with a couple of Execs and Im pretty sure there will be another one cut soon once he proves his incompetency.....

you also start to slim down when getting ready to look for a buyer.....

It's been great working here though....

Sunday, June 17, 2007

An afternoon with InstallAware's Sinan Karaca

It was a really nice father's day today: My smiling girls, the sweet cards and presents, the bacon wrapped Fillet Mignon and best of all, being given a pass to go enjoy some free time without the responsibilities of parenthood.

So what better to do on an afternoon off then to sit at a Starbucks for 5 hours chit chatting with the founder of InstallAware, Sinan Karaca. We both went into extreme detail over practically every aspect of the installation space.... way too much to write about here. I think a lot of good information flowed and I've come to realize that the two of us actually disagree on very few topics. I'm looking forward to see if InstallAware decides to implement a few of my thoughts in WiXAware and I'm equally interested in seeing if I can fit WiXAware into my installation solutions.

Either way it was a very productive session and as always, I always enjoy meeting with people who have an interest in setup. If you find yourself in Austin, feel free to look me up.