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

October 24, 2007

InstallScript Custom Actions are GOOD

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

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

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

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

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

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

InstallScript is:

Not based on ActiveScript / Windows Scripting Host.

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

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

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

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

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

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

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


Anonymous said...

is it possible to extract the original InstallScript out of a compiled InstallScript CA?

Christopher Painter said...

In the old days there used to be an InstallScript decompiler but as far as I know, there isn't these days.

Some people like obfusacated code and some people like transparent code. InstallShield ( and C++ ) leans towards the first while scripting languages and .NET lean towards the latter.

If you make your CA data driven, you can somewhat expose the behavior via the table data, but the implementation is still private inside the CA.

Anonymous said...

Right. I only do C++ custom actions as they are easy. I was wondering if your CA logic is out in the open with Installscript. Probably just a mater of time before Installshield or someone else releases a decompiler.

ShadowWolf said...

Don't forget that it's easier to debug (Build -> Debug versus set environment variable, launch installer, attach debugger, debug installation, forget to remove environment variable, cancel installation, delete environment variable, need it later, blah blah blah) and the language has patterns for almost any imaginable situation including leveraging .NET Custom code.

That said, it's been nearly impossible to decompile the bytecode for quite a long time.

mr.mike said...

Hmmm, I always thought InstallScript resembled Pascal...

Some interesting points were raised, however, remember that even InstallScript has 'UseDLL()'. If you have to interact with the system, then there are many parts of the Windows API that IS cannot properly deal with (callback functions?).

Christopher Painter said...

InstallScript mostly looks like C to me, although you are right there are aspects that look like Pascal and later VB and C#. I guess it all looks the same to me after awhile. ( I've done C,VB/Script,Powerbuilder,Deplhi,C#/VB.NET over the years... )

Being a Domain Specific Language, InstallScript does lack certain capabilities. For example, there is no concept of function pointers and as you point out callback patterns ( although the LaunchAppAndWait does have a callback mechanism for calling EXE's ).

I've never actually had the need for this, but I suppose if you did, you could write a Type 1 CA in C++ and invoke it passing the MSI Handle. Once inside your C++ you could do the callback and pump messages back to the UI via the installer handle.

Do you have a use case for this or was it just an observation?