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

Thursday, July 31, 2008

InstallSite Swag Give Away

Windows Installer MVP Stefan Krueger recently announced that he's going to give away a 1 Yr Not-For-Resale MSDN Premium Subscription. He's accepting nominations from his readers.

Monday, July 28, 2008

Official Google Blog: We knew the web was big...

I noticed today that a new search engine was born. I tried it and didn't like it. It seems that everyone wants to try to be in the search business. Well, really they want to be in the advertisement business but that's another story.

I recently read an article where Steve Ballmer was mentioned:

"Earlier in the day Ballmer referred to the situation as a circular conundrum because advertisers don’t want to sell on Live Search unless there’s more people using the site, and people don’t want to search on the site unless there are more relevant ads."

Well, call me stupid but I don't get that reference. People don't visit search engines to see relevant ads, they visit it to see relevant search results which happen to have ads snuck into the result set.

Anyways Microsoft is pointlessly spending big money in this area IMO. Take a look at my StatCounter logs and you'll see that literally 92.27% of my search engine related pageloads come from Google. 6.87% come from Yahoo! and a mere .86% come from Windows Live.

I guess those were the idiots that didn't change the search provider once they upgraded to IE 7.

Anyways, here's a nice read from Google today:

Official Google Blog: We knew the web was big...: "up of one trillion intersections. So multiple times every day, we do the computational"

ack/nak: phillips medical: installation developer job opening

I noticed a help wanted post over on my friend Bob Corrigan's website. Anyone feel like looking into a new opportunity in sunny Boca Raton, FL and helping Bob get a ham for thanskgiving?

ack/nak: phillips medical: installation developer job opening

Wednesday, July 23, 2008

Entity Framework - No Confidence

In the .NET circles I always here comments regarding EF. I usually stay clear of them since I'm an Installation Developer not an Application Developer. Recently I was asked to write an install for a program that had a dependency on ADO.NET EF Beta3. I downloaded the EFB3SETUPX86.EXE package and tried to install it.

The keyword is TRIED.

The first error message informs met hat I must have .NET 3.5 installed. Funny, it is installed. Then I get a fatal crash. Ohwell, atleast the MSI is using the ubber-cool Red motif!

Either way I did some poking around and I found this launch condition to be the culprit:

Installed OR
(DP_NETFX35_INSTALLED_VERSION >= "3.5.20904.00") and (DP_NETFX35_INSTALLED_VERSION <= "3.5.21203.00")

I seem to have .NET 3.5 SP1 ( BETA ) 3.5.30428.01. Funny, EF BETA 3 package seems to be hardwired to not run against a beta version of the framework when it's a beta package itself. The part that really threw me off is the way the externalUI is used it looked like the LaunchCondition was information and something else blew up later.

Monday, July 21, 2008

Windows 98 on Hyper-V

I was goofing around the other day trying to get MSDOS 6.22 and Windows for Workgroups 3.11 working on Hyper-V. It's amazing how much I still remember about optimizing upper memory blocks. Either way, I did get WFW to go through setup but when I typed WIN it hung after the splash screen.

All fun aside, I was recently contacted by a potential client who needs an install created and tested on Windows 98! I don't know about you, but I haven't used Windows 98 in a good 6 or 7 years.

Now lately a lot has been made about Microsoft trying to kill of Windows XP, but has any one noticed how many operating systems have been killed over at MSDN Subscriber Dowloads? Windows 98 is *GONE* allegedly due to the Sun vs Microsoft Java war.

Then there is the problem that Hyper-V doesn't support Windows 98 integration components. Virtual Server 2005 is probably a better choice since it emulates an Intel 440BX/82371AB South Bridge with S3 Trio 64 video card. This is hardware that Windows 98 should be very comfortable with.

Well, here's hoping for the best. We'll see how far I get before I want to just go find an old computer off of Craigslist for this one time project.

However I'm going to give Hyper-V a try for now. I've hunted around and found a copy of Windows 98 so here's hoping for the best.

Thursday, July 17, 2008

Virtual Brownbag - Installation Testing with Hyper-V

I've been giving a lot of informal brown bag presentations at work lately so I thought why not try to do it online? The size and quality of the video isn't really what I'm going for so I'll probably try to find a better hosting service and then relink the video at a future date.

This video discusses how to use Windows Server 2008 Hyper-V on inexpensive white-box hardware to provide a robust installation test environment. Future videos will show how this system can also provide all of the other services needed in a stand alone development environment.

The video is merely a capture of my desktop with voice overlay. Let's face it, what's going on in the presentation is what is important, not what the author looks like.

Note: Be sure to check out other videos on Hyper-V that You Tube suggests by clicking the icon in the lower right hand corner. Also, the video uploaded is small so here is a detailed screenshot of what the snapshot tree looks like (I suggest opening it in a new tab and referring to it):

Friday, July 11, 2008

Multiple Language Resource Files - Quick & Dirty

Chris recently forwarded me a message from a reader asking for help installing language resource files via MSI and InstallShield. My response ended up being a lot more involved than I had originally planned so I thought I would blog about the topic.

First, a couple of notes:
  1. The information below is probably the easiest method for a few resource files with different names only. That does not mean it is a best practice. In fact, it isn't a best practice - if you have a lot of resource files or all the resource files have the same name, then you'll want to review MSDN topic Localizing a Windows Installer Package and the available Localization Example and author the MSI accordingly (to NOT use component conditions to control what files get installed).
  2. If you're using merge modules, you should review the MSDN topic Authoring Multiple Language Merge Modules AND review the InstallShield topics (because IS doesn't support authoring multi-language merge modules so if you need to exclude languages at MSI build time then you would need to create a different module for each language).
  3. If your MSI package has UI text streams that are localized, make sure the default code page property is set appropriately, that InstallShield is set up to generate multiple language transforms (1033.mst, 1036.mst, etc.) for each language you will support, and that the database summary information stream properties for the Template Summary and Codepage Summary are set correctly.

If you do need to only install one resource file depending on the OS language, then you need to add each resource file to the merge module as a separate component and then use a component condition to evaluate the SystemLanguageID property. Another advantage of this approach is that you can localize your shortcuts, registry entries, etc. because the records in those tables are tied to a particular component. So, if you had a shortcut with French text you would assign the shortcut table record to the component with resource-fr.xml as the key file and the shortcut would only be installed when the resource-fr.xml is installed.

If having multiple resource-??.xml files on your system is a problem, you need to do the following two things:

  1. Go smack the application developer upside the head. S/he should have coded the application to detect the language and load the approprate resource at run time.
  2. Make sure that the grouping of components is conditioned such that they are all mutually exclusive. IOW, only one of the components can possibly be installed at one time.

For example, to install only the French resource file, add a component with key file resource-fr.xml and set the component condition to:


The component will only be installed on systems where the System Locale Identifier Constant indicates French (0x040c hex - 1036 decimal).

If you need to install the French resource on other French locales (such as Belgium, Canada, Monaco, etc.) you would need to expand the condition to:

SystemLanguageID=1036 OR SystemLanguageID=2060 OR SystemLanguageID=3084 OR SystemLanaguageID=6156

Also, whatever your default language should be (English?) then you want the condition for the component that contains that resource file to evaluate so that it installs on all systems that don't match any of the conditions for the other resource components. So if you only had French (with the previously mentioned locales) and English and you wanted English to be the default then you would set the condition for the English component to:

SystemLanguageID<>1036 AND SystemLanguageID<>2060 AND SystemLanguageID<>3084 AND SystemLanguageID<>6156

...and NOT to:


...since the latter will only install on systems where the local is set to English-US (IOW, any other system not covered by the other component conditions would never get any resource file installed).

A couple of other issues to consider:

  1. If your MSI can be installed per-user, you will also want to consider conditioning the components using the UserLanguageID property as that can be different from the SystemLanguageID (a user can set their user locale to 'French' when the system locale is set English so they see French and other users of the same system see English).
  2. To cover the scenario where your user installs under one language, changes the language settings, and then run's 'repair'. Make sure you set the msidbComponentAttributesTransitive attribute flags for your components with conditional statements so the conditions get reevaluated during a maintenance mode installation. This would allow the originally installed language component to be removed and the new language component installed for this scenario.

Thursday, July 10, 2008

Horrible Patching (no)Strategy

Edit: Some blogs are now reporting that this KB consumes 1GB of disk space, crashes machines and reports your machine as `unsafe` if you defer it.

I was browsing tweets out of boredom when I came across this funny tweet:

okay the latest windows vista update 955020 is 56mb, to add 5 words to the windows dictionary

So I followed the link to KB955020 and sure enough Microsoft released today a patch that adds the words Friendster, Klum, Nazr, Obama and Racicot to the English dictionary in Vista and Server 2008. They have 5 separate downloads for the different platforms and the Vista x86 download ( Genuine Validation Required ) is 56.4 MB. x64 clocks in at 63MB!


It seems that the system stores all of it's keywords in dll's. There is a Custom.dic file for augmenting user provided words but there is no concept of extending the pattern with additional layers of keywords from Microsoft. So large dll's have to be sent over the wire to fix the problem.

Who wants to take a guess that the person who designed this system never didn't' really care about deployment?

And I thought the .NET Framework was getting huge...

Tuesday, July 8, 2008

Five Years of Windows Installer and Texas

It just occurred to me that 5 years ago ( yesterday ) was my first day on the Continental Airlines account in Houston, TX. Wow, time flies.

This also marks a second anniversary for me: 5 years of Windows Installer

I'd been writing InstallScript installs since 1997 for various beltway bandits in Northern Virginia but I had intentionally shunned Windows Installer due to my perception that it was slow, buggy, rigid and entirely over engineered. Frankly my installs WERE Bullet Proof and I didn't need Microsoft jumping into the setup space like they had with web browsers, 3D API's and office suits.

I recall doing a PVCS Version Manager deployment and watching how slow it installed on a Pentium 200. The endless repeating of the progress bar was not entirely unlike the scene from Office Space. In the summer of 1999 I had played with InstallShield for Windows Installer beta prior to Windows 2000 being released and I remember being completely unimpressed with Windows Installer.

Anyways, one day Cheryl wanted to move to Texas and before I knew it I was speaking to an IT Director who wanted to repackage his applications into MSI format and deploy them with SMS. Learning MSI suddenly became a priority.

Many, many hours would be spent reading everything that I could on the subject trying to get a firm understanding. A good six months would pass before I started to see light at the end of the tunnel and believe that Windows Installer was actually a better way to roll. A full 18 months of learning, doing and helping would pass before I decided that I was ready to blog on the subject.

As an aside, it's interesting that I was actually originally inspired to blog by Rob Mensching.

After my 6 month contract at Continental turned into 2+ years, we decided that it was time for a change again. ( Seriously, who in the world can work for one company for years and years these days? Developers need cross polination to keep it fresh. ) Before we knew it, we landed in Austin and we really love it here. For anyone who's never been here, it's a really great place to live and work as a .Net/MSI junkie.

Monday, July 7, 2008

Reasons DTF is Better

I've found myself repeatedly answering emails on this subject so I thought it would be a good idea to officially publish my reccomendation.

As much as I appreciate the work Acresso did on Managed CA's, DTF is clearly the better direction to go.

1) DTF solves the problem of tatooing the msi process with a fixed version of the CLR.
2) MakeSfxCa is more flexible and intuitive when dependencies.
3) The MSI interop object model is simply better from a C# coders perspective.
4) The hosting process has an easy debugging story.
5) Being open source it's easier to see problems and get resolutions to issues even if that means doing it yourself.
6) There is no vendor lockin. You can build and consume custom actions in a variety of ways including integration with InstallShield. (That's the way I roll.)

Dynamic Windows Installer UI

I was reading a discussion on Dynamic UI for Windows Installer recently and I came across a post where there was some confusion over what MSI can internally do without the help of an external UI handler. I know in the past I've written custom actions to dynamically generate content for ListBoxes so I thought, why not be able to do it for other UI controls?

Fortunately DTF makes this kind of coding really, really easy. Here is a quick example:

using System;
using Microsoft.Deployment.WindowsInstaller;
namespace dynamicui
    public class CustomActions
        public static ActionResult DynamicUI(Session session)
           InsertRecord(session, "CheckBox", new object[] { "DYNAMICPROPERTY", "1"});
           InsertRecord(session, "Control", new object[] { "CustomerInformation", "CheckBox1", "CheckBox",
                                                           144, 181, 198, 22, 3, "DYNAMICPROPERTY",
                                                           "Dynamic CheckBox", "", "" });
           return ActionResult.Success;
        private static void InsertRecord( Session session, string tableName, Object[] objects)
            Database db = session.Database;
            string sqlInsertSring = db.Tables[tableName].SqlInsertString + " TEMPORARY";
            View view = db.OpenView(sqlInsertSring );
            view.Execute(new Record(objects));

In this example we insert 2 temp records into the MSI tables prior to displaying the CustomerInformation dialog. One record defines a CheckBox control on the CustomerInformation and associates it to the public property DYNAMICPROPERTY. Another record says that when the CheckBox is checked, that the property should have the value of 1. Otherwise it has a value of not-set.

Now I should note that in real life this would be a little more complicated. I intentionally did not subscribe to a tab order because I would have to do additional queries to be able to know how to inject myself into the tab order. Caution would also be highly advised since my new table records haven't gone through ICE validation processing. The normal way of doing things here is to have a bunch of static/disabled controls that you dynamically enable at runtime using ControlConditions. However, I could see a scenario where more flexibility is required so this pattern could be of help one day.

For additional fun, here is a half baked - off the cuff thought: This example is like reflection emitting (.NET IL ) instad of CodeDom ( language aware ). It would be interesting if DTF had a pattern that was aware of WiX XSD schema and could dynamically generate temporary MSI records based on WiX source inputs.

Wednesday, July 2, 2008 Buzz

I'm not sure who I have to thank, but it seems that was nominated in's IT Blog Awards 08 in the Programming, development and technical blogs catagory.

Now we didn't make the `short list` but I think it's pretty cool that a blog about deployment topics would even make the list at all considering what little respect this space gets in the first place.

Pretty cool, thanks readers!

No Evidence Of Disease

I wanted to share some good news with everyone today. Over the past few days Cheryl has had various tests performed including a colonoscopy, CT scan and blood work. After countless medical treatments that would seem cruel and unusual punishment by almost any standard, I'm very happy to report that at this point she is currently considered `No Evidence of Disease`!

While we aren't out of the woods yet ( I don't want to dwell on that aspect), we certainly have enough reason to go out and celebrate tonight.

I sincerely thank everyone who has helped us with support and prayers. We are very grateful for all of the help and friendship that has been given.