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

Wednesday, June 7, 2006

InstallScript, meet CustomActionData

I've made a small contribution to InstallSite entitled:


"Decode the CustomActionData Property in InstallScript"


Now that InstallScript CA's running in Deferred/Commit/Rollback execution don't have access to the MSI handle via IDriver we must follow the same rules that other CA's must follow. One of these rules is that we only have access to a limited number of MSI Properties.

This contribution is designed to illustrate how to use an immediate Type51 Property Custom Action to assign an array of properties to the CustomActionData property (such as /PROPA=1 /PROPB=2 /PROPC=3) and then from within InstallScript decode the value of PROPA, PROPB or PROPC.

I hope this helps people making the transition to the new InstallScript runtime environment.

Friday, April 28, 2006

InstallShield 12 Beta2

In previous postings I've rambled on about the search for the Holy Grail of Custom Actions. I do believe that I've found it. Buried in the "what's new" for IS12 (Beta) is this little blurb:

`InstallScript design enhancements`

Ok, I know, you might be saying 'Yuck, InstallScript' or 'Yuck, Script!' But give me a second here to explain. I think you'll like it enough to pass it along to other developers who have lost faith in InstallShield.

The 2 biggest problems with InstallScript have been:

1) The need to bootstrap a scripting runtime. setup.exe != pure .msi
2) The ISScript engine had so many bugs in it that it spawned a support website of its own.

I am pleased to report that both of these problems are HISTORY! InstallScript CustomActions now compile to Type 1 Custom Actions. These means the only real difference between a C++ custom action created in VS6.0 and an InstallScript Custom Action is how much time and effort to took to write it.

Imagine all of the glory of InstallScript.... a Domain Specific C-like scripting language ( I'm not sure why they call it script anymore, it doesn't really have a scripting engine! ) that gives you an integrated IDE, Compiler, Linker, Debugger, a host of functions, simplistic datatypes, and the ability to easily invoke Native Win32API, COM and Managed Code all in one package with easy access to the MSIHANDLE.

A couple versions back InstallScript added the CoCreateDotNet() function. It basically works like this: Your write a class in VB.NET/C# and declarate it with [assembly: ComVisible(true) ]. After building the assembly you simply drop this assembly in your SUPPORTDIR view ( No COM Registration Required! ) And call it from our InstallScript:

export prototype ExampleCA( HWND );

function ExampleCA( handleInstaller )
STRING supportDir;
NUMBER bufferSize;
OBJECT myClass;
begin
MsiGetProperty( handleInstaller, "CustomActionData", supportDir, bufferSize );
set myClass = CoCreateObjectDotNet( supportDir ^ "myassembly.dll", "myNameSpace.myClass" );
myClass.myMethod();
set myClass = NOTHING;

return 0;
end;

More detailed examples can be found here

How easy could that be? No ActiveScript to blow 1720 error messages at you. No C++ to write, no CLR to invoke, no configuration of the system such as COM registration or putting assemblies in the GAC needed to call your managed code.

Now that's what I call Hard Core Setup Engineering.

Congratulations InstallShield. I only hope that Setup Developers will give InstallScript a second chance.

Wednesday, March 8, 2006

A New Approach to Managed Custom Actions

Well I finally got around to diving into C#. Last week I spent a week with Richard Hale Shaw and 19 other coworkers going through a 5 day Visual Studio 2005 and .Net Framework 2.0 Bootcamp.

I won't rehash the usual arguments against managed custom actions. I'll assume your application already needs the .Net 2.0 Framework so that it really isn't a big deal to have to either bootstrap this and/or include in your LaunchCondition to require that it be installed.

So consider the following design pattern:

Server Side ( MSI context ):

Mixed Mode MC++ DLL that contains a standard call function and a .Net remotable object . We schedule the CA at the beginning of the InstallUISequence and InstallExecuteSequence. We will run the CA in Immediate Execution and msidbCustomActionTypeFirstSequence
and a that gets call at the beginning of the install. The SAO Singleton Remotable Object has wrapper methods for all of the MSI API functions that we want to call. When the Type 1 CA is invoked it starts up the CLR and hosts the remotable object. Next the custom action activates the object by passing the MSIHANDLE to a public property set accessor. Finally the custom action goes into a while loop checking once a second to see if a public property has been set to Exit indicating it's time to dispose and quit. Later in the install we will set the property to the exit setting.


Client Side:

The client side can be any managed code including run in any context. The managed code connects to the URI of the remotable object calling the MSI API wrapper method desired. The object is actually activated in the context of the server side which means it has access to the Installer Context.

The result is IPC using .Net Remoting and now you can write simple, powerful and robust Managed Code CA's with minimal plumbing to talk to the Installer.

Thursday, March 31, 2005

Custom Actions

I've been giving thoughts on Custom Actions lately and Nates feedback has prompted me to start publishing them. I'll probably keep updating this entry as my thoughts change.

First of all, I'm sure we all try to avoid custom actions in the first place! It is often best to handle a problem using native MSI standard actions for several reasons which I won't name here. But we all probably also know by now sometimes CA's are needed. So what is my list of requirements when choosing a solution for a CA?

1) Capable: The CA must be able to get the job done. It needs to be able to call Win32 API and COM. Possibly it needs to be able to call .NET services also, although at this point I havn't needed to. Some on the web have argued that alot of the .NET services are just wrappers of existing COM and Win32 interfaces, but I really don't know yet. It also must be able to access the MSI handle for doing things like getting/setting properties and posting messages back to MSI logs and subscribers.

2) Reliable: The implementation needs to have as few points of failure as possible. The less moving parts and dependencies the better.

3) Debugable: When things aren't working you MUST be able to step through line by line and get meaningful data to aid in troubleshooting. You'll pull your hair out if you can't.

4) Ease of Development: This is a subjective requirement. The language used by the CA should be easy to program in. We shouldn't be loads of time developing CAs. This is one reason I love InstallScript over C++. Unfortunatly InstallScript is failing requirement #2 and hence C++ is beggining to trump InstallScript in my mind.

5) Supportable: You won't always be working at Acme Software House. What languages are well understood by your fellow developers who will be stuck with your project when you leave?

6) Compiled: What goes in a CA, stays in a CA! This is important in terms of protecting source. It also aids in requirement #2 since a truely compiled language doesn't require a runtime intepreter.

7) Integrated: Ideally the CA's source would be integrated into the MSI development IDE. This is one thing I really like about InstallScript. It's very easy to author, compile, build and debug the CA from one IDE. Unfortunatly refer to rule #2.


Obviously runtime requirements (gets the job done reliably ) are more important then design time requirements ( easy for the developer) . So where does this leave me? Seriously considering dumping InstallScript and going to a language that can compile to a Native Win32 DLL ( not COM ). Unfortunatly where I work there aren't many C++ programmers and a whole lot of VB programmers. So I'm also considering using the DLL as a wrapper to register and invoke a VB COM object where the real work gets done. But this creates more moving parts and starts to violate rule #2. There are some programs that claim to be able to create true DLL's out of VB6 projects. This also looks very tempting to me. VBAdvance, VBExport and VisualDLL seem promising, but in truth all of this is a hack to get around doing C++ CA's.

Wednesday, March 23, 2005

My new addition, Emma

Today I have great news! After 9 long months, Baby Girl 2.0 RTM ( code named Emma ) was released at 9:48AM on 3/23/2005. This release includes 21" of 7lb 3oz of joy!


Emma and Daddy Posted by Hello
Edit Jan 18, 2007: A couple years have gone by and here Emma is with her big sister Ashley. They sure do grow quickly! :)


Thursday, March 10, 2005

In search of perfection

As I sit here I'm watching an SMS 2003 push of an application to 1306 machines. 25 clients never evaluated policy leaving 1281 machines that did.Out of the 1281, 1206 have finished and 26 have failed with error 1603.That leaves me with a push that is 93% successful. If weed out SMS problems and focus on only the ones that ran I'm looking at a success rate of 98% with a 2% error rate of 1603.So is the glass half empty or half full? What kinds of error rates do you guys see? I'd really like to be able to crank up my reliabilty a notch or two because it costs alot of labor to have to track down these machines either physically or remotely and perform a manual installation.

My problems seem to be centering around corrupted MSI runtimes that setup.exe isn't smart enough to fix on startup and DCOM problems starting the ISScript engine. I used to have lots and lots of problems with ISScript until I started tweaking the redist MSI to set both DCOM instances to Launching User instead of Interactive User. That seems to have solved the problem for most of my clients yet a few return. I'm starting to agree more and more with some other leading setup developers that I need to dump the InstallScript and move toward C++ DLL custom actions. Also if I replace setup.exe with my own bootstrap EXE then I can probably cut down on almost all of my errors and get near 100%! Now that would be hard core setup engineering.

Friday, March 4, 2005

What does the future hold?

SKD over on the Wixs-Dev list recently asked a question of how long WiX will be around.
Anytime you include third party technology into a solution you have the issue of what is the expected life cycle of that technology. That technology could be an O/S, a language, an SDK or an application. So without getting caught up into open src / closed src there is the question of how long with WiX and MSI be supported. Robmen had a blog entry where he notes how long microsoft supports products once they are released and it's conclusion to me is that MSI will be around for a very long time. After all you have tons of applications dependant on it for setup. Now the better question to me is why release WiX now? Darwin has been out in the wild for close to 6 years now and Microsoft had until now stayed out of the setup tool game and played in the setup sdk game only. On one hand the fact that Microsoft is now releasing a setup development tool only reenforces to me how long MSI will be around.&n bsp; But then again I wonder what technologies will come with LongHorn and the DSI inititative that might become more appealing to me rather then investing more time in MSI/WiX. Sometimes I really wish there were more hours in the day for me to do more research in this area.