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

August 14, 2007

BUGBUG: Yikes!

Black and Yellow Argiope
Argiope Aurantia

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

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

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

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


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



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

August 10, 2007

InstallShield COM Problems

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

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

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

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


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

August 09, 2007

InstallShield 2008 HOTFIX: COM Extraction Causes System Corruption during Uninstall

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

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

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

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

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

August 05, 2007

.NET CA's are NOT (always) Evil

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

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


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

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

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

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

July 25, 2007

Cancer Sucks

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

July 24, 2007

Beyond Tao of the Windows Installer

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

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


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

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

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

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

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


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

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

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

July 05, 2007

Managed Code Rocks

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

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

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

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


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

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

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

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

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