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

Saturday, December 24, 2011

IsWiX 1.5 Released

Release 1.5.11358.1 of Industrial Strength Windows Installer is now available for download over at CodePlex.

This release completes the "Component Rules" radio buttons on the Files and Folders designer.  You can read about it in the release notes at CodePlex.

Monday, November 21, 2011

The Curious Case of the Corrupted Characters

Recently I was shown a machine where the PowerShell cmdlet Get-WmiObject was failing to query the Win32_Product class.  The strange thing was that  WMIC path Win32_Process was working.

I almost wanted to blow this off as yet another example of how Win32_Product is broken but there was a catch: I could fix and break the behavior at will by uninstalling and installing the MSI I was working on.

I started to wonder how this could be.  I could only assume that there was some bad data causing casting problems in PowerShell ( COM interop is a pain ) so I decided to run MSI validation to see if it warned me of anything.

Sure enough, it did.  A big ICE24 error alerted me to a problem in the ProductVersion property.  Well, at least it tried to.  2.0.1600 sure looked like a valid ProductVersion to me.  For the life of me I couldn't get it to stop complaining about that value so I decided to export the Property table to an IDT file.  Sure enough notepad showed me a special character and a Hex editor showed me that there were actually two special characters corrupting my property.

I kept digging and found the root of the problem in the build automation NAnt file.   A text file was being created and loaded into a NAnt property using the loadfile elemnt.   Those two extra characters were coming along for the ride.

Let's see all the ways this could have been caught:

1) NAnt could have trimmed the property automatically.
2) ISCmdBld could have trimmed the property.
3) MSI Validation could have been turned on in the build.
4) MsiPublishProduct could actually enforce the required datatype of the property
5) The MSI WMI provider could trim the property.
6) The Get-WmiObject could trip the property or report a better error.

And of course, this post wouldn't be complete without me mentioning that there is a much better alternative to Win32_Product called the ProductInstallation class as found in WiX DTF's Microsoft.Deployment.WindowsInstaller interop.  It's a very nice encapsulation of the unmanaged MsiEnumProducts function and doesn't have the horrible performance problems that Win32_Product has.

Friday, October 28, 2011

Beam Me Up: Using JSON to serialize CustomActionData

Data driven custom actions require two custom actions.  The first custom action queries custom tables and evaluates business rules and then passes CustomActionData to the second custom action which then performs the operations needed.   Windows Installer calls this script generation and script execution but I call it "brains" and "brawn".   That is the first action has access to all the information needed and can think about what needs to be done yet it doesn't have the access rights to do the work.   The second action has all the rights to do the work but doesn't have enough access to teh MSI handle to be able to decide what needs to be done.

So just how does the brain communicate with the muscle?  Through the CustomActionData property. 

Today I want to demonstrate a lightweight technique of transporting complex instructions through this property using JavaScript Object Notation aka JSON.

Let's say I wanted a custom action that could create local user groups and I wanted it to be data driven.  First I'd start off with defining custom tables that can express the

<CustomTable Id="Groups">
<Column Id="Group" Type="string" PrimaryKey="yes" Category="Identifier" Description="Unique Identifier of Group" />
<Column Id="Component_" Type="string" Width="72" Modularize="Column" KeyTable="Component" KeyColumn="1"/>
<Column Id="Name" Type="string" Description="Name of Group"/>
<Column Id="Description" Type="string" Width="255" Description="Description of Group" />
<Data Column="Group">groupRockers</Data>
<Data Column="Component_">SomeComponent</Data>
<Data Column="Name">Rockers</Data>
<Data Column="Description">People who rock!</Data>

This table basically says let's create a group called Rockers when SomeComponent is being installed.  Now let's write some code.   The brain needs to be able to communicate with the bronze so let's start with creating something they can both understand.  A POCO class ( Plain Old C# Object ) that describes a Group:

class Group
public string Name { get; set; }
public string Description { get; set; }

Now let's write the brains:

public static ActionResult CostGroups(Session session)
var cad = new CustomActionData();
var groups = new List<Group>();
using (View view = session.Database.OpenView("SELECT `Component_`, `Name`, `Description` FROM `Groups`"))
foreach (var record in view)
using (record)
if (session.Components[record.GetString(1)].RequestState.Equals(InstallState.Local))
groups.Add(new Group() { Name = record.GetString(2), Description = record.GetString(3) });
cad.Add("Groups", JsonConvert.SerializeObject(groups));
session["CreateGroups"] = cad.ToString();
return ActionResult.Success;

We query the Groups table and then iterate through the rows.  During this we evaluate if the component is being installed and if it is we generate a Group class and add it to the Groups list. Finally we serialize the List of Groups to JSON and put it in the CustomActionData collection as the Groups KeyValuePair.

So what does this CustomActionData string end up looking like?  Let's look at the Windows Installer log:

MSI (s) (70!E4) [09:47:15:735]: PROPERTY CHANGE:
Adding CreateGroups  property. Its value is:

Groups=[{"Name":"Rockers","Description":"People who rock!"}]

Now it's time for the brawn to flex some muscle:

public static ActionResult CreateGroups(Session session)
var groups = JsonConvert.DeserializeObject<List<Group>>(session.CustomActionData["Groups"]);
foreach (var group in groups)
var ad = new DirectoryEntry("WinNT://" + Environment.MachineName + ",computer");
DirectoryEntry newGroup = ad.Children.Add(group.Name, "group");
newGroup.Invoke("Put", new object[] { "Description", group.Description });
catch (Exception ex)
return ActionResult.Success;

We grab the value of the Groups KeyValuePair from the CustomActionData property and then deserialize it back into a List of Group.  Then we iterate through the list and call the API needed to create the group(s).

So there you have it.  Beam me up!  A simple contextual example of how to use JSON in your installer.  It turns out JSON isn't just for the web guys.

Disclaimer: This code was thrown together in about 30 minutes and has not been thoroughly tested. I'll be improving it over time and if you'd like a copy you can contact me via email.

Wednesday, September 28, 2011

AppX Just Might Fail

In my last post I talked about how AppX might work.   Today I'm going to be a contrarian and look at the other side of the coin:   AppX Just Might Fail

A long time ago, Rob Mensching had a blog post promoting a 100% declarative installation model and lamenting custom actions as an admission of failure.  He then went on to enumerate three general reasons or the need of custom actions.  One of them was:
The setup developer wrote a custom action to configure some platform because the platform technology didn't provide installation primitives for itself.  This one is just sad and, unfortunately, happens more often than not. 
100% declarative sounds great, but you back yourself into the "640K is enough for anyone" corner because one day a the "box" won't be big enough and the platform will be too slow to catch up.

Don't believe me?   Take a look at all the times Windows Installer as "failed" us by not providing us a declarative way of doing something?

Read/Write XML
Read INI other then the Windows Folder
Persisting properties across transactions ( "Remember Property" pattern )
Closing Windows and Killing Processes
Executing SQL Scripts
Configuring IIS
Configuring Reporting Services Reports
Recursively deleting directories
Configuring firewall rules
Configuring Visual Studio AddIns
Granting Users Logon as Service Right
Creating Users and Groups
Configuring COM Plus
Game Explorer
NativeImage Generation ( Ngen )
PowerShell Snapins

The list goes on and on.   Now I know,  "But Chris,  Metro Apps aren't intended to do those things."   OK,   but do you *REALLY* know what Metro apps need down the road for?  When the requirements change will AppX be updated fast enough to support the new  requirements?

I know Windows Installer has never been able to prove itself in this area.   So the purists can preach that custom actions are a failure and I'll admit in many cases ( reinventing the wheel and writing sloppy CA's ) they are but in many cases they are the only way to get the job done.

So will AppX work holding the line the way it is? I think Yoda answered it best:

Difficult to see. Always in motion is the future.

Thursday, September 22, 2011

AppX Just Might Work

Recently, Rob's been blogging about the new AppX installation technology.  My first initial reaction was to cringe and think "Oh yeah, Microsoft is promoting yet another alternative to MSI.  That's all we need!"

At first it seemed like AppX would be just another ClickOnce and suffer the same fate.

On the other hand it's not that I really love MSI or anything.  It's just that for all the complexity of the Windows platform it takes a really complex service to be able to deploy all the possible combinations.  I've always wished that the complexity could be reduced but every year new layers get built on top of old layers making this impossible.  I  guess that's why I disliked ClickOnce so much.   The world simply wasn't ready for ClickOnce.

Now let's talk about Windows 8,  Metro, the application store and AppX.  The world simply might be ready now.

I'll be honest, I love my iPhone and I'm not really a fan of the app store concept.  However Apple is making a boat load of money so obviously I'm in the minority hear.   Now to fit into the nice simple world of Metro apps and the app store  developers will have to develop within the lines of a box.  And AppX seems perfectly capable of deploying applications that fit that box.

Yes, we've heard the lectures in the past about setup development is a first class activity, design for the container and custom actions are an admission of failure.   That kind of talk always irritated me because I knew out in the real world people didn't listen and then dumped the problem on the install guy at the last second.   But now, the world might be ready to let that sink in.  It might be that Metro and AppX makes sense and if enough people want to get into the app store then critical mass can be achieved.

And if they don't, well there's still MSI and no pretending that AppX can replace it like was implied with ClickOnce and MSDeploy.

Also when I read about AppX the XML/XSD aspects had me thinking about writing an IsWiX designer that could author AppX manifests.  However, now that I've downloaded the developer preview I realize that Microsoft has already done this by making a visual designer built right into the project.   Not a seperate project like a WiX or InstallShield module but a manifest right inside the main project the developer is working on.   Now that's making deployment a first class activity in my book.

Appx huh? Hmmm.  They just might finally have something there.

Tuesday, September 20, 2011

Deployment Engineering has moved

Welcome to the new home of the former Deployment Engineering blog. I've decided to rebrand myself for a number of reasons. First was that my consulting has really been growing and it was time to form an LLC. The use of the word engineering was suddenly a complication due to Texas state law. The second reason is "" is really a pain in the rear to type. I wish I had thought of that many years ago when I picked it for a domain name. :-) The third reason is I want to consider branching out into both products and services. I really like what the ISWIX name represents in terms of both a tool and a philosophy and since I don't have a marketing budget to come up with something fancier like "Qwikster" ( shrug ), ISWIX it will be!

So welcome to the old new blog. All of the historical content can still be found at this new URL.

Tuesday, August 30, 2011

Tales of Setup Democratization

At my last job, the .NET developers and InstallShield developers embarked on a collaboration excercise that we called 'setup democratization'.  We used a blend of InstallShield and Windows Installer XML.   Most developers used Industrial Strength Windows Installer XML ( IsWiX ) to author their WiX code.

I've asked my former colleagues to post their observations.  Let's see what candid and anonymous comments they have to share.

Wednesday, August 10, 2011

Farewell Overwatch Systems

The last three years have really flown by.  Two really wonderful things happened:   First, my wife has continued to be cancer free and second, I climbed the Mt Everest of installation complexity and won!   None the less, it's time to move on.
I will miss all of my friends at Overwatch Systems. We really accomplished a lot together but alas it's time for new challenges. So after a week to decompress I'll be starting a new job.  Details to follow.

Saturday, June 18, 2011

Farewell Jedi Matt

Two and a half years ago I met an individual by the name of Matthew Tan who inspired me to post the article Come to the dark side.  I had sensed that the force was strong in this one so I gave him as much advice and training  as I could until a month later I left the company to accept the Install Lead position with a former employer.

Six months went by and we were swamped so we needed to hire another setup developer.  I reached out to Matt and asked if he'd be willing to apply.  He did and one day I went downstairs to the HR interview room to meet him.  I wanted to get a sense of how he had grown on his own.  After speaking with him for about 10 minutes it became very clear to me that he was 'getting it' and doing well.  At this moment I felt good that I had found my next minion not to mention a handsome referral bonus.

Matt and another developer named Ray joined us right after the time that I was created our Setup Democratization road map and sold it to executive leadership.  The three of us formed a small development team and started working on an internal tool code named `WiXShield`.  This tool would later be renamed `IsWiX` and released to the community as open source.

Matt did a great job working on this project and over time learned all of our patterns so that he could back me up in case I ever got hit by a bus.  That day came about a year later when I was pulled off the team to do a 3 month stint as a developer on one of our products.  Normally I would have given some notice that I was leaving the team except that the cat got our of the bag early.  I remember pulling Matt into a conference room and telling him that effective immediately he was the new team lead.   To say he was shocked would be an understatement.

Well he did just fine so when I returned to the team three months later I decided to have him remain as the team lead and I took on an unofficial elder statesman role.  The inside joke around the office is that I've done too good of a job indoctrinating him with my world view.  It's amazing how eye to eye we see things.

Anyways to get to the point, you can't (and you shouldn't) keep a guy like that forever.  He's found a new place for himself over at Charles Schwabb and while I'm really going to miss him,  I'm wishing him well.

Matt-  I wish you well and here's to seeing you again one day soon. Perhaps this time you'll get the referral bonus.

From Left to Right: Matthew Tan, Ray Dise and Christopher Painter
 celebrate the release of IsWiX (May 2010)

Friday, April 8, 2011

Lack of IIS Support in IS Automation Interface

In a previous blog entry I talked about how a couple of InstallScript UAC bugs went uncorrected for several years.  "Anonymous" left a comment saying "it wasn't a big deal".

So today I'd like to leave a little bread crumb for something that IS a really BIG deal.

InstallShield markets itself as having an Automation Interface and not just a big fat IDE.  That is correct and I make extensive use of it in my blending WiX with InstallShield designs.

InstallShield markets itself as having Native IIS 7 support.  That is correct and it's one of the big reasons I continue to use InstallShield.  WiX 3.5 is supposed to be up to that level but for now I've stuck with IS.

However, recently I discovered that InstallShield's automation interface has 0% coverage of the IIS functionality.  That is a huge omission as IIS changes represents a major component of the InstallShield tool.  

Now I wasn't in any of the meetings but it doesn't take a rocket scientist to figure out what probably happened.     Marketing and Engineering probably realized the need for a revamped IIS subsystem to deal with the latest versions of Windows / IIS.   They probably scoped it out and somewhere along the lines decided to drop automation support from the roadmap so they could keep their ship date and announce a new feature.

So there you go, sure they have automation and sure they have IIS but they don't have automation for IIS which in my book means they don't really have automation.  It simply is not feature complete.   This isn't the first, second or third time I noticed glaring holes in the automation interface but it's the most significant IMO.  I can kind of ( not really ) understand a property here or there missing but for an entirely new/rewritten feature to be omitted tells me that the automation interface isn't really a priority and that it's a false feature.   That it's only there for marketing purposes so that InstallTalk can blog it's usefulness.

Sure, I can "hack" around this problem as has been suggested to me  but I don't considering saving and closing the project object  then hitting it with a DTF SQL Query or  XML DOM to be "automation".  This is raw data layer access.

No doubt some at InstallShield will read this and say "he's spot on" and some will read this and say "oh Chris is off his rocker again... this is really no big deal.". 

So let's see how many years it takes for InstallShield to fix this one. 

Wednesday, April 6, 2011

Interesting Thoughts for Today

I just came across two interesting blog posts today that I thought I would share.  The first is from The Agile Warrior:

Wherever you are working, pretend you are going to be there for ever.

This is especially important if you are a contractor.

When you act like you are going to be somewhere forever (and that it’s YOU who is going to be maintaining this software) you behave differently.

You start to write more tests.
You don’t mind creating the occasional support document.
You clean up as you go.
And you are less likely to sweep things under the rug.
You are nicer to people (you are going to be here forever after all).
And you start to care.

Making this attitude a habit isn’t just good for the soul. It’s good for the bottom line.
Contractors who don’t care don’t get asked back.
And nowhere is the world more small than your local IT community.

So start caring. Pretend you are going to be there forever and you’ll naturally act accordingly.
The second is from Joe Homs

What works equally well is to pretend you are leaving tomorrow. It’s a great exercise if you really do think you’ll be at your company for a long time and will have to maintain the software you create. If you’re leaving tomorrow, what would you fix, document, clean up, or write tests for? Who would you be nice to? We used to call this the “Hit by a bus” effect, but some people liked to use “the lottery winner” effect as the name. It really helped people get that they had to maintain their systems better and not become bottlenecks and share information.

Joe then goes on to quote Carl Gustav Jacob Jacobi  with:

“Invert, always invert.”  - Carl Gustav Jacob Jacobi 
Continuing, Joe says:

If you haven’t heard of Jacobi, you should check him out. Anyway, basically, all you have to do is think of the opposite of whatever position you are in. Have lots of time? Now pretend you have little. Have lots of people? What if you only had a few? Have only a little money? What if you had a lot? Stretching the constraints in your projects can really help you see new solutions. It’s helped me solve problems countless times for myself and my clients.

Fascinating thoughts if you ask me.

Monday, April 4, 2011

InstallShield Bug Backlog

I was reading through the InstallShield 2011 release notes from August 2010 when I noticed the following:

InstallScript Functions ServiceExistsService and ServiceGetServiceState No Longer Require Elevated Privileges

The InstallScript functions ServiceExistsService and ServiceGetServiceState no longer require elevated privileges. Therefore, installations can now call these functions when end users have limited privileges, such as in the Install UI sequence of a Basic MSI installation. This enhancement resolves issue IOC-000059857.

I then remebered blogging about that problem back in May of 2007. ( See: Vista UAC implications of ServiceControlManager API calls )

As I recall, this fix couldn't have been more then one or two lines of code.  Basically you just had to open the SCM API requesting less privs when you were only checking the status of a service.  I remember this because I had posted a workaround on the forums myself.

This bug was found in IS12. 

Was it fixed in IS2008?  Nope.
Was it fixed in IS2009?  Nope.
Was it fixed in IS2010?  Nope.

It was finally fixed in IS2011 which was released in August of 2010.  That's 39 months to fix a simple defect.  Surely all of those maintenance dollars from support contracts could have sped that up a tad.  Instead InstallShield continues to live up to their reputation of shipping new features but not fixing existing issues.

I'm going to be keeping that fact in my mind when I think about how long it takes WiX to ship a new release and how InstallShield now loves to throw the "Agile" word around in their marketing.

Monday, March 14, 2011

Guess What Else InstallShield Can Do!

Flexera's InstallTalk blog recently posted a blog articled titled `I Didn't Know InstallShield Could Do That?` I mainly reference the article not for the content but to use it as a hook for a more interesting albeit darker version:

InstallShield can be used a bootstrapper for a WiX MSI.

...evil laugh...

It's simple.  InstallShield 2011 Premiere has some new features that allow you to inject custom commands at various stages of the build process.  One of these steps is the Precompression Event.  This event occurs right after the MSI has been built but not yet digitally signed.   This allows you to do custom post build processing of the MSI without breaking it's digital signature. 

InstallShield's handling of Setup Prerequisites ( the kind that run before you MSI ) it's fairly loosely coupled from the MSI.  Feature prerequisites are a bit more complicated but not impossible to reproduce.   Let's look at the work flow.

1) Create a Basic MSI project ( call it anything you want ) and then give it a feature and a component.

2) Add the .NET 3.5 SP1 setup prerequisite using the redistributables view.   Right click and select properties and type in a release flag of DOTNETFRAME35SP1.

3) Create use the Release Wizard to generate a new Product Configuration and Release.  Pick a compressed network image with setup.exe.

4) Set ProductName, ProductVersion, PackageCode, ProductCode and UpgradeCode to the same values as in your WiX msi.  Set the Generate Package Code value to false and set the MSI Package File Name field to be the same as your WiX msi ( without the .msi part ).

5) Copy your WiX MSI to the location specified as under Path Variables.

6) On the Build Events tab of the release paste in the following precompression command

cmd /c copy "<ISPROJECTDIR>\WiX35.msi" "<ISPROJECTDIR>\WiX35\Release 1\DiskImages\DISK1"

Saturday, March 12, 2011

Redemption of Visual Studio Deployment Projects

For years I've spoken of the horrors of Visual Studio Deployment Projects:

  • Every file and every registry key is always a key file of it's own component
  • ShortCuts are always advertised
  • Dependency Scanning is next to impossible to disable
  • Custom Action support is horrible  ( deferred only )
  • No support for MSI concepts such as ServiceInstall encourages Custom Action anti-patterns
  • Many more ( Rob Mesnching has an blog post out there somewhere with 100 comments of people's compaints about VDPROJ and support of Windows Installer XML.
The loathing of VDPROJ was so great that Microsoft is replacing it with InstallShield 2010 Limited Edition.  Now I'm going to say something that shook my world view to it's foundation:


Visual Studio Deployment projects, used in a very specific way, is....


pretty useful.


Wow, there, I said it.   Go ahead, get your laughs of disbelieve out.   I know, I know, Chris has finally fallen off of his rocker.   OK, you ready for my defense?  Here goes:

I came to realize with  my 'all component data goes in merge modules' using IsWiX and WiX that essentially every single complaint that I had about VDPROJ stemmed from how it authored component data and exposed custom actions.    By abstracting all of this into WiX merge modules and leaving next to nothing in the VDPROJ installer project  I am able to build an installer that passes ICE validation and presents no garbage that causes concern for me.

 Sure, it's a fairly limited solution but for a great many projects it's probably actually is good enough.   I get a UI that can be somewhat customized without diving too deep into the details, a bootstrapper that can handle basic prereqs like .NET 3.5/4.0, SQL Compact, C++ runtimes,  the ability to define System Searches and Launch Conditions and support for Major Upgrades.

As long as I use a discriminating eye and void using VDPROJ to do anything else like define files and folders, shortcuts, registry and so on, it's really no that bad.

Instead I use the merge module for everything.   Need to author 1,000 files?  No problem, just drag and drop in IsWiX and it's done.    Need to give a few of those files shortcuts in the start menu?   No problem, write a few Directory, ShortCut and Icon elements and that's done.   Need a Windows Service?  No problem, ServiceInstall and ServiceControl elements.   Create a Service Account?  Configure the Firewall?  Find the Visual Studio ItemsTemplates directory?  Check, Check, Check.

Sure, I'm going to be limited to one feature ( which makes variation points difficult and resiliency repairs intensive ) and I won't be able to do quiet a bit of customization but some people probably don't really need this anyways.

It's like going to one of those 120+ item buffets at the beach when you are on vacation.  If you ignore those 100+ items that junk and stick to the 10-20 items that are good and then bring a few of your favorite adult beverages from home, you'll probably have a pretty good time on the cheap.    I know, bad analogy but I hope it gets the point across.

So there you have it.  A somewhat cautious yet positive endorsement for the use of VDPROJ.  Who would have thought it?

Thursday, March 10, 2011

Installation Collaboration Workflows using Free Tools

Recently I was asked to explain the workflow for Industrial Strenth Windows Installer XML (IsWiX).  In a nutshell IsWiX is all about enabling collaboration by enlisting the help of various contributors in defining the contents of the installer.  This is done through the use of Microsoft Merge Modules.   We use MSM's rather then fragments and libraries because the intent is to interop with other tools such as InstallShield 2011.

At my day job,  Visual Studio is included in the standard developer image which pretty much everyone in Engineering gets.  Recently I was doing some work for a client when it became clear that the person who could best contribute to the project wasn't a developer and didn't have Visual Studio.    While VS is not strictly required by IsWiX it really does help.   So I started looking for a solution to the problem of a non-developer persona contributing to Setup and I came across the following:

Microsoft offers a free, redistributable download: Microsoft Visual Studio 2010 Shell (Integrated) Redistributable Package ( Installs .NET 4.0 )

 This installer basically gives you a stripped down Visual Studio IDE with most tools and languages missing.  It just happens that Windows Installer XML 3.5 supports this shell.  ( As an aside, WiX 3.0 supports the 2008 version of the shell. )  Finally, IsWiX (Requires .NET 3.5 SP1) also supports this shell.   So after downloading these three/four packages on an XP SP3 image we suddenly have a fully functioning IDE for authoring merge modules.

Now let's go through the workflow.

1) Start Visual Studio 2010
2) Select  File | New Project

3) Select Merge Module Project and pick a location and project name followed by OK. 

4) After the project is created and shown in solution explorer, rename the MergeModule.wxs to the "[project].wxs". (It'll work if you don't know this but it really gets annoying having dozens of wxs files with the same name. 

5) Remove the TODO Create Component comments and save the WXS file.

At this point we are really just doing standard WiX stuff. Now let's go play with IsWiX.

6)  Select Tools | IsWiXAddIn ( The one with the cheesy looking smiley face. )

The first screen to come up in IsWiX is the General Information designer.  This is where we can view and edit information related to the ModuleSignature and ModuleDependency tables. ( Wix, Package and Dependency elements in WiX speak. )

7) Click on the Files and Folders Designer

The files and folders designer is where you can define the say which source files get installed where.  In WiX this will be your Directory, Component and File Elements.   If you look closely you'll see it's only letting you pick files from where the wixproj and wxs files are.  This is because by default the designer orientates itself to the current directory.  Let's change it to C:\

8) Click on the Code View Tab

Notice that IsWiX has authored a special preprocessor variable called SourceDir and assigned it a value of '.'.   Let's change that line to read  .... SourceDir="..\..\.." ( the number of ..'s will depend on where you put your wxs file or you can just point it to some other directory if you'd like. )  Now let's go watch the effect:

9) Click on the Designer View tab

Note the source files view now points to C:\.   Let's author some files and folders into our merge module.

10)  Drag a folder from the Source Files directory tree to the MergeRedirectFolder node on the destination folders tree.

Now we can see the directories / subdirectories and files shown in the destination.  Let's send these changes back to visual studio.

11)  Click the save button and close IsWiX.

At this point Visual Studio will notice that the contents of our wxs file has changed and ask if you want to reload it.

12) Click Yes

From here we can see the XML that IsWiX authored for us.  We can now rebuild the project to verify that the module builds.

13) Right click the merge module project in the solution view and select Rebuild.

By now it should be obvious that IsWiX can allow non-developers to author merge modules.  But WiX developers can also edit the raw XML by hand and add in additional elements such as ServiceInstall, ServiceControl, ShortCut,  ProgId and so on.   Most edits by hand will have no effect on IsWiX.  Eventually it's hoped to write additional designers that can automate all of these elements.

The other point I'd like to make is the workflow that I use this with

1) Meet with subject area experts ( Dev, Web, Docs, DBAs et al ) and have a dialog where we provide them a basic understanding of Installers and they provide us a basic understanding of the design of their solutions.

2) Come to an agreement on how their solution breaks down into Feature and Merge Modules.   Implement the feature tree in the installation tool of your choice ( InstallShield 2011 for me )  and do the initial setup of the merge module solution.

3) Inform the developers that it's now their job to keep the modules up to date and that we are available to assist / answer question and do additional meta markup such as services and COM.

So there it is in a nutshell.  How I do collaboration using IsWiX / WiX and InstallShield.   If your needs are limited you could use WiX or InstallShield 2010 Limited Edition and have a complete system with nothing but free tools.

Any questions?

PS-  Just for fun I decided to try to install InstallShield 2010LE on the Visual Studio 2010 Shell.  It kind of worked.   It did install and I could open an existing ISL project but the ability to create a new LE project from the File menu was missing.   This isn't important to the Collaboration discussion I mentioned above because I would expect the Setup developer supporting all of this would either have WiX, InstallShield Profesional or Visual Studio and InstallShield LE.

Sunday, March 6, 2011

.NET Reflector is Priceless

Recently, thanks to the Big Swinging Developer, I was given a license of .NET Reflector.

I just wanted to say that Reflector really is priceless!

Just today I was working on a new install for a remote customer and wouldn't you know it, the application threw a null object reference exception when I tried to start it!

I didn't have any sources or symbols so I could have thrown in the towel right there.

Instead I used Reflector to export the assembly to a CSPROJ and rebuilt it so I could have my own symbols and source code. Before I could say "Big Swinging (Install) Developer" I was stepping through the code and found the source of the problem.

So instead of having the usual "works on my machine"discussion that so often accompanys integration I had the remote developer fixing the problem.

Priceless!  Thanks redgate, Red-Gate or Red Gate. ( Not sure how it should be spelled! )

Friday, March 4, 2011

InstallShield Setup Prereq for Microsoft SQL CE 3.5 SP2 Bug Alert

I was recently working on an InstallShield 2011 ( Hotfix A ) Basic MSI project and I needed to add the Microsoft SQL CE 3.5 SP2 prereqs to my project.  In doing so I've noticed a big problem:

1) InstallShield only provides a PRQ for the x86 redist not the x64 redist.
2) The PRQ provided for the x86 redist incorrectly filters out 64bit Windows Server 2003, Windows Vista and Server 2008 while correctly installing on 64bit Windows 7.

Per Microsoft, the following operating systems should be supported:

Supported Operating Systems:Windows 7;Windows Server 2003 R2 (32-Bit x86);Windows Server 2003 R2 x64 editions;Windows Server 2003 Service Pack 2;Windows Server 2003 Service Pack 2 x64 Edition;Windows Server 2008 R2;Windows Server 2008 Service Pack 2;Windows Vista Service Pack 2;Windows XP Service Pack 3

Also of note is that you must install both the x86 and x64 configurations on a 64bit edition of Windows:
On a 64-bit Computer, install both the 32-bit and the 64-bit version of the SQL Server Compact 3.5 SP2 MSI files. Existing SQL Server Compact 3.5 applications may fail if only the 32-bit version of the MSI file is installed on the 64-bit computer. Developers should chain both the 32-bit and the 64-bit MSI files with their applications and install both of them on the 64-bit Computer. Refer to the KB article or to the Install.txt file that is extracted with the MSI files for more information.

My guess is that is an allusion to yet more Bitness pain that I previously covered.  Depending on whether your .NET EXE is compiled for x86, x64 or AnyCPU and what version of Windows you are running on it may need one version of the redist or the other version therefore both must be installed.

Thursday, February 17, 2011

InstallAware Blog

Sinan at InstallAware has just posted an interesting read:

Viresh: Did He Make or Break InstallAware?

While some of it is questionable, if you have an interest in the behind the scenes opinions of this industry it's really worth reading the entire article.   He goes into such topics as the war between Rob and InstallAware, the copying of the ZeroG website (along with an attack on Stefan Krueger ), what he really thinks about WiX and his own product WiXAware and behind the scenes poaching of InstallShield employees and alleged poor quality code they delivered to him

Interestingly he also claims that only he and Rob Mensching have innovated in the last year and leaves me out of his rant. 

He also mentions not liking a strategy of having a very thin IDE on top of WiX.  Funny, this is exactly where I'm trying to go with IsWiX.  I think with the right investment and development staff I could make a really good go at it but I'm not crazy enough to try.   This market is too saturated and mature in my opinion.

Austin Networking

Sometimes I think it would be nice to have some sort of get together in the Austin area.  I'm not sure what that would look like so I'm open to suggestions.   I don't have corporate sponsors so there wouldn't be super cool swag although a few pizzas and/or Rudy's BBQ could probably happen.

So leave a comment or send me an email if you are interested.  I'd be up for everything from a simple happy hour / social get together to a more traditional special interest group meeting.   And of course if you ever just want to bend my ear privately for whatever reason I'm usually available for lunch.  

Either way I'm very interested in getting to know more people in the Austin area. 

Monday, February 14, 2011

Software Entropy

Recently, someone suggested to me ( putting it mildly ) that our build automation should ignore failed unit tests in order to get further down the process.  I instinctively bristled at this notion.   Later I decided to google the subject to see if anyone else in the world was actually entertaining such non-sense.  There was an answer on StackOverflow that referenced a story from the Pragmatic Programmer called Software Entropy.  It's an interesting story about the effects of Broken Windows on a building and what it means for software rot. (See Active Rot )

There's a few expressions I like to use:    (Fair warning, these are cynical and/or sarcastic)
  • Entropy is a bitch
  • Once is an exception, twice is a pattern
  • Death but a thousand cuts
  • What's the problem with a little poo in the installer.
  • Garbage In, Garbage Out
  • Fix the installer and not the application.  That's a great idea.
The point of this is it's really hard to maintain high quality installers when forces are constantly acting to bring chaos.   This is why I bristle at comments made about how Agile Installation means everyone can contribute and you don't need specialists.   I've seen developers contribute to installs... contribute chaos.   This is what happens when you bring people to the table who don't understand MSI.    They understand things like Regsvr32, Regasm, SC.EXE, InstallUtil and OSQL.exe and then try to wedge them into the installer.  

Every one of those things is a broken window and frankly, I don't allow broken windows.   Unfortunately, that doesn't always make me a very popular person because developers are often quite self-convinced that their solution is acceptable. 

So back to my initial comment about unit tests failing builds.  For installs this is Windows Installer validation and I suggest custom ICE's to enforce quality standards.   I suggest writing tests that enforce  your coding standards.   Don't allow selfReg?  Write an ICE that checks the SelfReg table.   Don't allow InstallUtil CA's?  Write an ICE that scans for those.  Allow only sanctioned DTF custom actions?   Write a unit test that reads in a white list file and make sure only those custom actions exist.

Enforcing standards through automation is the best way to fight entropy that I know.

Saturday, February 12, 2011

the Build Maestro

In my last blog post I encouraged Nick Skitch to start blogging and today I noticed he now has the blog:

the Build Maestro

I'm not sure if my public dare worked or not ( it could be pure coincidence ) but let's welcome Nick none the less.  Also, I've put him on my Daily Rounds.

Speaking of my "Daily Rounds", they are just that.  There is absolutely nothing political or ideological about it.  If there is a blog that contains subjects that are interesting to me, it will make my list.   This is true regardless of whether or not I typically agree with the source.  

Finally, there are no favorites when it comes to who gets listed first.  It's really simple to stay on the top of my reading list:  Post Often.

Friday, February 11, 2011

Motivational Feedback

Recently I've received some comments and emails ( reposted with permission ) from readers that I wanted to share.
The first comment is from Jerra who I first met on InstallShield Community.  He had started a thread trying to come up with, well - interesting,  ways via custom actions to get InstallShield 2010 LE to create services. This thread was actually in the inspiration for the article  Augmenting InstallShield using Windows Installer XML - Windows Services in which Jerra left the following comment:

Absolutely fantastic! I just got the installation to work on my development machine (XP, VS2010 Professional, Wix 3.5, InstallShield 2011 Express). ... This is just great! I have read the articles you linked and checked a few more and have still more to read later. A new world is opening itself..

OK so I understand now that using custom actions (CA) makes you go outside the "safe"/controlled environment of MSI and any changes to the system will not be included in the automatic

transactional/rollback sequences otherwise generated by the installer (if I got it right)? Apparently there are cases where CA's are legit but its best to really look for ways to do things inside within the installer.
 I can't tell you how much it warms my heart to help someone come to this place.  If Jerra could just get 5 people there and they get 5 people there, well just maybe the setup world would be a much better place.

The next feedback came in an unsolicited email from Nick titled Shout out to Deployment Engineering Blog:

You don't exactly know me, but I sure as heck know you.  I've been following your blog and read everything back to the beginning.  I just want to personally thank you for everything you do for the field.  From your informational and entertaining blog posts to your nearly countless replies in the Installshield forum.  It seems like every problem I search on, Chris Painter has a solution or can point you in the right direction.
I appreciate your innovative stance on embarrassing DTF in its infancy. You supported this technology rather than the inferior attempt at managed custom actions implemented by Installshield... at a time when senior engineers were 'pooing' on managed code for installers. Very brave and your reputation goes to show.
You are the rock star of this niche field ;)
I'm basically just writing you to express my gratitude and encouragement for you to continue what you're doing. It's a minefield out there. Man, is it crazy. I have so many stories that I think I'm going to start blogging about.
Aw shucks, thanks Nick.  I was a little embarrassed re posting this but I think that I've taken so much grief over the years from people who try to discredit me in order to silence the dissent that it's important to take a moment and know that my reputation in fact remains intact.

I hope Nick does in fact blogging.  The setup world always has room for one more leader.

Update: Nick is now blogging.

Thursday, February 10, 2011

Opinion: InstallShield and Agile??

I few months back InstallShield posted the following:

Collaborate during installation development – Installation development today is becoming more of a team sport where all developers can participate. There isn’t as much of a need for specialist in Agile development. You may have people that are more experienced in certain areas than others, of course, but in Agile everybody rolls up their sleeves and implements features. It also means all developers often participate in developing parts of the installer.

I had a reaction the moment I read this but I wanted to pause a bit before I shared my thoughts.  First a little background on my world view.   From 1996 to 2005, I experienced that most developers don't want to touch installs with a 10' pole.  Back in 2005-2006, I participated in an attempt to make developers responsible for setup development. It ended very, very, very poorly.  It was so bad that I quit the company and moved on.   For the next couple of years I would read blog posts from the likes of various MSFT employees talking about Agile in context of Setup Democratization and I would just bristle at the thought as I remember just how bad it had ended.
After a couple of years I returned to that company in 2008 and after 6 months or so I started down the path of attempting democratization again.   This time around we had better tools, better strategies and slightly better attitudes from developers.   You can read more about this attempt here.  Things went well, very well.
Ok, back to InstallShield's assertion from above.    First, I question how common it is for installation development to be a team sport.  I'm guessing they have market research that I don't because in my experience very few people do this.    Second, I really disagree that specialists aren't needed.  Deployment engineering and MSI / InstallShield are domains that can really bite you if you don't have extensive training and experience.  A specialist  is required on small projects to ensure quality and on very large projects an architect with deployment experience is desirable.  Someone has to be responsible for defining and enforcing the strategy while delegating the work.
Now InstallShield no doubt sees the Agile buzzword has an opportunity to, well, sell more licenses.
There are several problems with this in my opinion.   First is the cost of InstallShield.  $2000 a seat is one thing when you are talking about a specialized tool for a handful of developers but when you start scaling that out to include all kinds of things such as stand alone build licenses, floating licenses, collaboration and so on it's no unusual for a mid sized team to get quotes of nearly $100,000.   That's crazy.
Second is DRM.  It's crazy to drop that kind of money and then be treated like a criminal.  Maybe I'm a little extra jaded on this one because our development networks aren't connected to the internet and activation is a really big pain for us.
Third is InstallShield's DTD XML project format does not support branching and merging in a meaningful way.    When I designed IsWiX a lot of attention was paid to creating XML could easily be developed on multiple branches and then merged back together without conflict.   We use multi site base Clear Case and this is a very big deal to us.    A little while back I looked at the version tree of a .wxs file and I was part horrified as to just how many branches there were and part elated in the knowledge that through all this it had magically worked without any developers ever reporting any issues.
Finally InstallShield has too much of a learning curve.  An ideal tool provides an easy button abstraction while allowing for under the cover tweaking off all the buttons and switches.  With IsWiX and WiX I get this.  With InstallShield and InstallShield Collaboration I don't.
Now this isn't to say that InstallShield doesn't have a part to play.  Frankly, I couldn't easily do what I do today without at least a few licenses of InstallShield.   Perhaps in very large shops like Microsoft you can justify creating extensive external UI's, bootstrappers and chainers such as seen in Microsoft Office and Visual Studio but that just isn't an option for many companies.   Conversly, I couldn't easily do massively scaled Agile development without WiX and IsWiX either.

Dealing with Slow Starting Windows Services

Every once in a while a question pops up about Windows Installer trying to start a service and if fails but that if the user starts it manually it works.   The solution usually turns out to be related to solving some race condition either in terms of dependency or timing.  I won't attempt to enumerate all of these today but I did want to draw attention to something I recently observed.

The Windows (NT) Service Control Manager ( SCM ) waits up to 30 seconds by default for a service to report that a pending operation is successful.   There is a registry value called ServicesPipeTimeout that can be used to change this behavior to a longer time.  In doing so though one must keep the following in mind:

  • As with many things ServiceControlManager related, the ServicesPipeTimeout setting requires a reboot to become effective.   It’ll offer no help if you are trying to start a service during the install.
  • Even if it was effective right away, I’ve observed that when the MSI SDK says “max 30 seconds” it means 30 seconds max.  Changing the ServicesPipeTimeout setting has no effect on the behavior of the StartServices standard action.  ( A bug in my opinion. MSI should track with SCM in my opinion. )
Now personally, I think it would be a mistake for an installer to set ServicesPipeTimeout.  This is the sort of system wide setting that I usually shy away from out of fear of causing unforeseen side effects.  However, I am interested in knowing if any of my readers have experience with this setting and how things turned out for them.

So in conclusion, a setting exists but it won't help with the installer much unless all you need to do is set the service to automatic and ask for a reboot.

For C#/.NET junkies using the ServiceBase class, I'll offer an additional observation that thread.Sleep() calls in the OnStart() method exceeding the ServicesPipeTimeout threshold didn't seem to cause any problems.  However placing the delay in the constructor or instance members in the class did cause a problem.

Monday, January 31, 2011

Comments on Setting INSTALLDIR During an Install

Blair Symes recently posted "Building 32-Bit and 64-Bit Installations from the Same InstallShield Project" on the Flexera's InstallTalk  blog. In it he describes how to build two MSI's targetting opposite platform bitness using one InstallShield project.  His example leverages a Type 51 custom action to assign INSTALLDIR at runtime based on the value of the ISReleaseFlags set during the build of each MSI.

Here's a screen shot:

I wanted to take a moment to respectfully point out that this implementation is flawed, a better way to accomplish the task and finally an opportunity for InstallShield to improve their product with a new feature.

The problem comes from the condition and execution scheduling choices.   First, let's talk about the condition ISReleaseFlags (contains) X64.   This condition should also be checking that INSTALLDIR doesn't already have a value.  Second the execution scheduling of Always Execute should really be Execute Only Once.

Why?  Because failing to do some causes two defects in the resultant installer.   First, attempting to pass INSTALLDIR at the command line will fail.    The installer will continue to default the [ProgramFilesxx]MyCompanyName\MyAppName.   Second,  because the custom action is being called again in the InstallExecuteSequence  the Browse capability in the CustomSetup dialog is effectively overridden.   There are also other concerns such as trying to set a directory property in subsequent installer transactions such as repairs and upgrades/patches.

This goes to show how careful one must be with custom actions.  Even seemingly innocent Type 51 custom actions can cause undesired behavior.    If you don't understand this, I really suggest reading Stefan Krueger's immensely helpful  Installation Phases and In-Script Execution Options for Custom Actions in Windows Installer article.    ( The irony is this article was originally published by InstallShield back in 2001 so you'd think they already get it. )

My entire architecture at my day job is built around Build Automation and ProductConfigurations.   All of our installers bring together reusable components with unique branding which includes the value of INSTALLDIR.  I've long known the complications of using custom actions so instead I use the ISWiProduct object's INSTALLDIR property to build up the directory table before I build the project.  This works really nicely ( including better looking Administrative Installation Extracts and Uncompressed Media  ) and eliminates the need for the custom action.   I find it ironic that InstallShield just posted six articles on how to use the automation interface in various obscure languages but missed this excellent opportunity to show how it can really be useful in a practical way.

Finally, there is a situation today where I'd have to use the Type 51 custom action:  Multiple Instance Installers.  InstallShield currently has the ability to define the ProductCode  for each instance transform but it would be really cool if it also had the ability to define the INSTALLDIR at the ProductConfiguration level and the Instance level.   The idea would be able to do something like:

ProductConfig A (default instance)   INSTALLDIR [ProgramFiles]Company\ProductA
ProductConfig A (instance 1 )   INSTALLDIR [ProgramFiles]Company\ProductA-1
ProductConfig A (instance 2 )   INSTALLDIR [ProgramFiles]Company\ProductA-2

ProductConfig B (default instance)   INSTALLDIR [ProgramFiles]Company\ProductB
ProductConfig B (instance 1 )   INSTALLDIR [ProgramFiles]Company\ProductB-1
ProductConfig B (instance 2 )   INSTALLDIR [ProgramFiles]Company\ProductB-2

Finally, for my WiX brothers, here is the equivilant code in WiX:

<SetProperty Id="INSTALLDIR"

WiX v3.5 Released

Rob has announced the release of Windows Installer XML 3.5.  I'd like to congratulate the WiX team for their achievement.

As I previously noted, I probably won't be able to explore this release at my day job due to our immutable requirement to support multiple versions of tools.  I've raised this issues many times over the past couple of years and it looks like Rob has now taken notice of the problem:

Also, it is important to note that Votive in WiX v3.5 does not install side by side with WiX v3.0. This is an unfortunate design issue that we hope is fixed for WiX v3.5 upgrades to WiX v3.6.

I'm really looking forward to v3.6 ( because of Burn ) and  hope to see this improvement in v3.6 so that I can actually use it in my environment.   Until then, I will be using v3.5 in my own personal environment and I suggest that anyone who can move forward do so. 

Saturday, January 22, 2011

Upgrade vs No Upgrade and Windows Installer XML

A lot is side in the MSI SDK about servicing strategies.  Much of it is confusing and has to do with the intricate details of  Major vs Minor vs Small Upgrades and Upgrades shipped as MSI's or as Patches.  The UpgradeCode property itself is defined as a "GUID representing a related set of products".

If you do this all correctly you get a nice user experience.   For example I might install one version of a text editor and then later upgrade to the latest version of the text editor.   

But what really isn't mentioned in the SDK is  what to do when you have a related product but you don't want to do an upgrade.   Perhaps what you really want is a side by side installation of a new version of a product.

For example,  how you feel if you installed Visual Studio 2008 and then when you installed Visual Studio 2010 it remove Visual Studio 2008?   What if you insalled InstallShield 12 and when you installed InstallShield 2011 it removed InstallShield 12?

Would you really be ok with that?   I wouldn't.  I couldn't possibly move all of my software baselines to a newer tool or have 2 machines on my desktop for the two different sets of tools.

These are times when you must design both your application and your installer to be able to support side by side installations of different versions of the software. 

Sadly, the WiX team has made this choice for me.  Rather then support  Votive 3.0 and Votive 3.5 side by side installations with Visual Studio 2008 and Votive 3.5 with Visual Studio 2010 they have chosen to do a Major Upgrade and support only Votive 3.5 on Visual Studio 2008 and Visual Studio 2010.

To make it even more interesting they have broken backwards compatibly by changing the name of the MSBuild Targets file that the .wixproj points to.

Basically the software was designed that if you want to use Votive 3.5, you gotta be all in.

Well, perhaps some people will be ok with that.  If you are new to WiX without a huge previous investment or you don't use Votive perhaps you will be ok also.  However, for the massive environment that keeps me busy at my day job I say:


I make this call because WiX 3.5 only brings marginal benefit to my situation while requiring me to make a substantial commitment with a lot of associated risk. 

It's obviously too late to fix this for 3.5 as this would be the sort of high risk last minute activity that any setup developer hates.  However I hope to see a different story for 3.6.  I'd like to be able to have the latest 3.5 installed on my personal machine at home while also installing the latest 3.6 weekly release.  When 3.6 goes RTM one day I hope to have 3.5 and 3.6 installed side by side.

As an aside, Industrial Strength Windows Installer XML will work with any combination of Visual Studio 2008, 2010 or None and Windows Installer XML 3.0, 3.5, 3.6 or none.   IsWiX technically just authors XML files so it has no physical dependencies on either VS or WiX other then a shared understanding of the wix.xsd file.

Wednesday, January 19, 2011

Augmenting InstallShield using Windows Installer XML - Windows Services

In my last blog I explained how you could use a WiX module to extend InstallShield to accomplish installing certificates.  I also mentioned that you could use WiX to inject  Windows Services into InstallShield 2010 Limited Edition even though the tool wasn't designed to support this.

Below is an example of what said WiX source code would look like.   I post this not as some attempt to 'hack' InstallShield LE but more a spirit of  I really don't want to see former VDPROJ developers continuing the horrible practice of writing InstallUtil custom actions to install services.

As an aside, 14 of the 16 lines of XML were authored by IsWiX.  I only had to add the ServiceInstall and ServiceControl elements.  One of these days I'll get around to finishing the Services Designer so IsWiX can do all the authoring.

<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="">
<?define SourceDir="."?>
<Module Id="WindowsService" Language="1033" Version="">
<Package Id="f4e004d1-4fc1-4dab-855d-c46fc2ec3702" Manufacturer="WindowsService" InstallerVersion="200" />
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="MergeRedirectFolder">
<Component Id="owcB7461B87B05DCA45F57E1CB0917F32A7" Guid="380bbddd-daa7-0744-517b-37da768f5570">
<File Id="owfB7461B87B05DCA45F57E1CB0917F32A7" Source="$(var.SourceDir)\WindowsService.exe" KeyPath="yes" />
<ServiceInstall Id="installWS" Name="WindowsService" DisplayName="Windows Service" Description="Windows Service" Start="auto" Type ="ownProcess" ErrorControl ="normal"/>
<ServiceControl Id="controlWS" Name="WindowsService" Remove="both" Stop ="both" Start="install" Wait ="no"/>

Augmenting InstallShield using Windows Installer XML - Certificates

I've blogged in the past how I like to blend WiX with InstallShield and today I'd like to post another example of the usefulness of these two tools together.

Recently I was creating an installer that need to install a trusted root certificate.  I looked at InstallShield 2010 and the only certificate support I could find was for creating IIS websites and assigning server certificates.  ( As an aside, I never quite understood the usefulness of that outside of a controlled corporate environment where you are setting up many servers to belong to the same farm or to an application where you will register a hostname in DNS and all customers know the server by the same name.  Also let's not mention distributing private keys in MSI's along with the passphrases needed to deploy them.  Really?? )

So I looked at WiX's documentation and found the Certificate Element in the IIS Extension.    Sure enough it has much broader support and can easily get the job.   So I decide to create a WiX Merge Module with a snippet of code similar to:

<?xml version="1.0" encoding="UTF-8"?>
<?define SourceDir="."?>
<Wix xmlns="" xmlns:iis="">
<Module Id="InstallCertificate" Language="1033" Version="">
<Package Id="00000000-0000-0000-0000-000000000000" Manufacturer="YourCompanyHere" InstallerVersion="200" />
<Binary Id="cert" SourceFile="$(var.SourceDir)\mycert.pfx"/>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="MergeRedirectFolder">
<Component Id="certs" Guid="00000000-0000-0000-0000-000000000000">
<iis:Certificate Id="cert" BinaryKey="cert" Name="cert" Overwrite="yes" SoureLocation="localMachine" StoreName="root"/>

I now end up with a nice encapsulation ( InstallCertificate.msm ) that I can add to my InstallShield project via the Redistributables tab. Build the MSI and test on a VM proves that it works.

This pattern can also be used with InstallShield 2010 Limited Edition and with a little bit of creative thinking you can quickly get IS2010LE to do all kinds of things that it was crippled to not be able to do. The best part is you are following very good practices while doing it and not trying to hack a solution together like you would be with Visual Studio Deployment Projects and InstallUtil Custom Actions.

Monday, January 10, 2011

DC Universe Online Uninstaller Issues

I was searching twitter for InstallShield when a couple of links led me to this great thread:

DC Universe Online Uninstaller Issues ( Google Cache of Sony Online Entertainment )

It seems customer service was announcing some bugs in their uninstall.  Now I'm not sure what will actually happen if the user clicks "Yes" but I do know I don't ever, ever want to see this dialog in my uninstall:

But the real kicker came when Customer Service  "TSR-AndyD" posted:

I'm sure you all realize that the focus of the development staff is currently going to be bmaking [sic] the game as awesome as possible for the retail release. The broken uninstaller is a forgivable and understandable over-sight.

Whiskey - Tango - Foxtrot????

It's now 2010 and with all this talk of Agile and CI, developers still don't have a clue why it's so important to make a proper install ( and uninstall ). 

Course this is Sony we are talking about.  Less we forget about their rootkit incident.
The bright side is some bright folks discussing the issue over this thread actually seem to get it.

Wednesday, January 5, 2011

Resuming Course

A few months ago I mentioned that I was going to take a break from installers and do .NET development. It was a very enlightening experience as I was able to gain a new perspective while improving my skills and helping a project that was in crunch mode. Alas things have slowed down a bit and I'm resuming my duties on the Install Services team.

One thing I did realize about myself is that I'm a High Functioning Windows Installer Addict. It's just so in my blood that it's sometimes hard to think about any thing else. Sorry, I'm just a freak of nature or something. So I'm back... ready to get my fix.