Friday, May 30, 2008

WiX: Patching something you didnt build with WiX using WiX

Many times people want to take advantage of the Wix v3 patch building features but didnt build their original product using Wix. for example, they may have used Install Shield, WiX v2 or one of the other tools out there. I ran into this when I needed to create a patch for a product we shipped from Visual Studio before the Visual Studio build moved to WiX v3.
 
 WiX v3 has a feature I added a while back to support this scenario. It allows you to point at an admin image of your msi based install package. This will be very familiar to some of you who have used patchwiz and pcp's in the past. The difference here is that your patch authoring can be done using the WiX v3 Patch element and it follows the same workflow as patching a WiX v3 based msi after the first stage of creating the diffs.

Something I found really easy, and I could see this being used by smaller products who dont have a lot of infrastructure, is the ability to hand edit your admin image to product the patch. For example, I wanted to update a single file in my product:

1. I created an admin image
2. I made a copy of the admin image
3. I updated the loose file in my copy of the admin image

After running it through the series of command lines, I got a patch that updated the file. Pretty simple...

The command lines you need to run are all the same as the ones in my sample: Building a Patch using the new Patch Building System - Part 3. The only difference is that you need to pass the -ax command to torch with a path to extract embedded binaries to instead of the -xi switch and add the -xo to specify to create a wixmst instead of an mst. This tells torch that the input is admin image instead of xml. Also, specify the path to the msi in the admin images instead of the wixpdb as the target and upgrade. Everything after that should follow the same process.

Let me know how it works! :)

Bonus feature: One of the most useful things in the WiX v3 patching system is the ability to filter whats in your patch using patch families to only ship your customers the updates they need. This allows you to grab changes per Fragment from your wix source. When patching from admin images, there is no source so you would think that the filtering isn't suppoted. Not so! This was one of the more fun parts of this implementation. We "auto-fragment" the msi into what we consider to be the optimal chunks to give you the ability to filter if you choose to do so.

This was originally posted here and may have additional comments.

Monday, May 26, 2008

WiX: Introducing the WixPdb

I should have made this post about 6 months ago as I was implementing the WixPdb feature in WiX but better late than never :).  The wixpdb was conceived as a solution for a limitation in the original patch building system. Originally, WiX v3 patching only supported creating transforms between two wixout files. This was flawed in that many things modify the output after the wixout is generated by light which weren't being reflected in patches. I knew I needed the patch build system to be able to create transforms from something closer to the final output. Thats what the WixPdb is. It is all the data in the output right before creating the final msi. With that data, we can now create more accurate transforms to what people expect when diffing two products. I updated my blog with samples on how to build patches to show that I now recommend using the wixpdb instead of the wixout.
 
Down the road, I look forward to seeing what other features we can get out of the wixpdb. It provides a ton of information an allows you to potentially connect install time errors all the way back to the wix source and line number. Static analysis is another benefit. I updated smoke to be able to take the wixpdb so it will give you source and line number information for ICE errors. Statis analysis on the wixpdb itself may also be interesting because it contains more data than in the msi. It is the one place where the wix source data and the msi data connect. Let me know if you have any ideas of how to use the wixpdb in some cool ways...

Friday, May 23, 2008

Design your Application to Fit Your Shipping Container

Let me start by saying I'd love to get people's feedback on the content of this post...
When Toyota designs a car they would never ignore the fact that no matter how great a car they build, they have to be able to get it to their customers. Additionally, they have to be able to get it to them at a reasonable cost. Imagine that Toyota decided that it would be cool to create a car that is 4 seats wide. Assume they ignored that the world's infrastructure is built to handle cars two seats wide. Can you imagine what would happen if they did that? Cars wouldn't fit on boats, on trucks, in garages, etc. In short, the cars would sit at the factory. Assuming the world wants the car people would scramble to create the infrastructure to get the cars to the users. In the end all of this would drive up the cost of shipping the cars and cause customers to pay more money to get it.

Software is no different
Unfortunately, software is often designed without considering its ship vehicle. What usually matters to developers is that it runs on their machine. It is designed and built until it works and is tested. Only then is deployment thought about. At that point, the application usually does tons of things that make software deployment a nightmare and costs way more that it would have if it were considered up front.

There's a way out
The standard for deployment on Windows is the Windows Installer (MSI). Luckily, for the applications that think about deployment last, Windows Installer is very extensible. If you want to run a bunch of custom code during install, you can. Having to do this is usually a sign that your application was not designed to make your deployment simple. You have to build a bunch of infrastructure as a band-aid for something that could have likely been avoided. Your custom code inevitably wont behave properly in some scenarios causing your entire deployment to become fragile. Whenever you see this, consider an upstream design change. This is more likely feasible if you aren't just about to ship your product and you aren't scrambling to build an installer package.

Make it simple
Setup can be really simple. Everything on a machine boils down to very simple things: Files, registry keys, and shortcuts. Windows Installer happens to handle Files, registry keys, and shortcuts very well. It's actually really easy to use if all you need to do to deploy your application is copy files, write registry keys, and add shortcuts to the system.

Its often not your application's fault
IIS did not make it easy to copy files to a location to install a web site. .NET didn't make it easy to GAC an assembly or NGEN it by copying it to a location. Both of these are things I like to call custom stores. Applications that expect other applications to extend them or use them as a platform need to be even more conscious of the deployment problems they cause. When platforms don't consider what it will take to deploy on top of them they make every one of their customers building solutions has to modify their shipping container to handle their custom store. Although we cant get rid of the custom stores that have already shipped, we can hopefully prevent more and more custom stores from being produced. I think people building on top of platforms should push back more when their platforms create more and more custom stores.

Start development with deployment
When building your applications, think about deployment as you design your app. Think, "Can I put this on my customers machine by only copying files"? If it starts to get hard, don't just write custom code to solve it. Think, "Could my application make itself easier to deploy?" Ideally, you could build your application to a folder and just run it without any configuration steps. You should create an empty installer package at the beginning of your project and build it up as you ad functionality to your product.

Application virtualization is on the horizon
If you make your application deployment completely declarative where no custom code has to run on your customers machine, your application will fit into the virtualized application world much better. It will also allow scenarios like drag and drop deployment, running from USB key.

Disclaimer
Many of the things I've said as far as guidance are optimistic. The world isn't as clean as I wish it were. But in the end, I dont think we'll ever be in a better situation unless people start thinking about the problems and stop making things worse for the Windows eco system by creating custom stores in platforms that are not installer friendly.

This was originally posted here and may have additional comments.

Wednesday, May 21, 2008

WiX: BinderExtensions and the BinderFileManager

As of a few weeks ago, the BinderExtension class in the wix extensibility model has taken on a new meaning. If you currently have a BinderExtension, you will need to rename it to BinderFileManager. Over the past year or so, numerous requests came in to give WixExtensions access to data and bind time to pull disperate data together or get access to data only available at bind time.

For example, if I have a custom table where I need to know the exports of all my native dll's and I want this table to be populated dynamically by wix, I would need to have access to populate my table after files are resolved. With the new BinderExtension class, this is now possible.

Key Changes:

What used to be called BinderExtension was renamed to BinderFileManager. The BinderFileManager handles things specific to a files, mainly file resolution and comparison. Only one instance of a BinderFileManager can be present in the WixExtensions passed to the wix tools and is commonly used in an extension specific to a build environment.

It is now possible to have a BinderExtension defined in each WixExtension passed to the command line tools. This allows you to:

1. Link disperate data associated with compile time language extensions. It essentially enables extensions to make additional decisions that the WiX linker cant do for you because it doesnt natively support your language extension. Once the linker has pulled all the data together, it may be neccessary for you to read that data and populate additional tables.

2. Populate tables with bind time data such as information from files which are resolved during bind.
 In my series abut writing WixExtensions, I plan to show an example of this functionality. I plan to pick that series back up soon.