Aaron Stebner's WebLog

Thoughts about setup and deployment issues, WiX, XNA, the .NET Framework and Visual Studio

Don't use managed code to write your custom actions!

Don't use managed code to write your custom actions!

  • Comments 17

After posting a brief article about my opinions regarding script-based custom actions, I started thinking more about what I consider an even bigger personal pet peeve of mine - managed code custom actions.

I want to caveat everything I am about to say by explaining that in general, I think managed code is great and not just because I work at Microsoft :-)  It offers developers the power of modern object-oriented languages while allowing for rapid development for small and large scale projects.  In fact, I have basically spent my entire career trying to make it as easy as possible for everyone to deploy the .NET Framework as part of OEM-manufactured machines or managed applications - and yes I know there is still a lot of work for us to do in this space.

But I also believe that managed code is not the best choice for certain types of development, and setup is one of those places.  The biggest concern I have with managed code being used in custom action code is the additional dependency that it introduces to setup.  If the underlying .NET Framework runtime is damaged it can lead to unpredictable results in a setup that would not occur if the custom actions were written as a native code DLL (or better yet, were eliminated in favor of standard Windows Installer actions). 

I have also seen setup issues related to .NET Framework runtime migration policy.  The policy of migrating managed apps to use the latest version of the .NET Framework on the machine (which is on by default in .NET 1.1 and 2.0) can cause your custom actions to run on top of a different version of the .NET Framework than you originally tested and shipped with. 

We used some managed executables during setup in previous versions of the .NET Framework.  Then in future versions of the .NET Framework we decided to set the default runtime migration policy so that any managed code running on the system would use the most recent version of the .NET Framework by default.  In general, the .NET Framework is side-by-side compatible and apps written against one version will continue to run correctly against future versions.  However, for specific functionality such as parsing configuration files or calling APIs that have had breaking changes introduced for security reasons, this may not hold true.  It is possible to include a config file with a managed app to lock it in so it will require a specific version of the .NET Framework to run correctly.  However, if you neglect to include a config file (like we have done in the past) that can potentially cause issues if/when your managed code is migrated to run on top of a later version of the runtime.  Also, if you author a managed DLL custom action you leave your fate in the hands of Windows Installer, because it will use the latest version of the .NET Framework on the machine in all cases (as opposed to a custom action that calls an installed EXE which can also have a config file installed next to it).

As a side note here, if you install the .NET Framework 1.1 you will notice a couple of files installed to the v1.0.3705 folder instead of the v1.1.4322 folder.  A couple of those files are intended to fix policy migration issues like the ones I just described.  You will also see the .NET Framework 2.0 setup install a few files to the v1.0.3705 and the v1.1.4322 folder for the same reason.

So, in summary, I strongly encourage you to not use managed code in your product setup.  I realize that some teams do this here at Microsoft, but please don't use our bad (in my opinion) examples to justify doing so in your own setup....

 

  • Ehh.... so I write an application in C# and I take 5 minutes to add a custom action by deriving from Installer.

    You are saying I shouldn't do that, even though it works just fine 99.999% of the time. You are saying if the .NET framework is corrupted somehow (I've never seen that) then application should install fine anyway (!) even though its going to blow up when the user tries to run it.

    You are saying that instead, I should learn a new unmanaged language, acquiring all necessary training, books, etc., create a new unmanaged project and have it fiddle with customizing my app.config file (a typical use for custom actions) even though it probably doesn't have XML support built-in and I'll have to go find and learn a 3rd party XML library.

    Cool!! I didn't have anything to do for the next 6 months anyway!!
  • This is all very valid pushback, thank you for posting it. I'll go through your points one by one and explain my thinking:

    1. 99.999% of the time - hopefully you're right and your app really does successfully install that often. Even if it does, depending on the size of your user base the overall number of failure cases can be large like I have seen it be for the .NET Framework setup itself, which is a redistributable with a huge install base.

    2. .NET Framework is corrupted somehow - if you are installing a managed code app then it will probably have problems running but if you have a non-managed app and introduce a setup-time dependency on managed code for a custom action then you will be more susceptible to failures that would not otherwise harm your app if you had no custom actions or only native code custom actions. Those are the cases I'm most worried about here (and I have seen setups that fall into that bucket).

    3. Learn a new unmanaged language - there are several types of "standard" custom actions (actions that commonly need to be done by a setup but are not supported natively by Windows Installer). The WiX toolset (http://sourceforge.net/projects/wix/) includes support for several different types of these actions, so I encourage you to look into leveraging WiX in your setup/build development process to reduce the ramp-up time and training required. Note that there are lots of good reasons to use WiX other than the custom action support it offers, but that particular feature fits in with this blog topic.

  • Sorry, I was having a bad morning. Thanks for your helpful reply.
  • Aaron,

    I'm a big fan of your blog, however this is an entry that I don't agree with.

    If the .NET Framework is corrupted, then my application is not going to work anyway, so its better for it fail during installation then during the running of the application.

    I understand that using managed custom actions when installing an unmanaged product is a bad idea, do Microsoft teams actually do that?

    Although the Wix toolset may be great (I have plans to start using it for new products), there are custom actions that are specific to a product that it won't be able to cover. As G. Man stated, I can whip up a custom action in C# in under a hour, as compared to many hours (and possibly days) spent developing it using unmanaged code. This may be fine for a company such as Microsoft, where the setup guys are not developers of the product, however in small ISVs where the developers are also the setup guys (as well as the tech writers and testers) this is not a possibility.

    I feel that perhaps Microsoft should improve the .NET support in Windows Installer, although 2.0 did handle .NET, it felt like it was a last minute thing that was tacked on at the end of a project (Like the use of a single AppDomain, during a the upgrade of a product).

    I haven't used 3.0 so this may have been improved.
  • On a scale of "Setup Goodness(tm)":

    No custom actions > native-code DLL custom actions > managed-code custom actions > VBScript/JScript custom actions (inherently evil)

    The biggest problem with managed-code custom actions isn't (IMO) a corrupt .NET Framework but the mixed commit models of MSI and Fusion. Your managed code can't rely on assemblies that are being installed into the GAC.

    And don't forget rollback!

    Until MSI supports managed code custom actions, they're a hack.
  • A while back, I wrote a post with my opinion about managed code custom actions - http://blogs.msdn.com/astebner/archive/2005/03/10/392280.aspx

  • Rob Mensching, father of Windows Installer XML (WiX), blogs about why managed custom actions are a bad

  • PingBack from http://www.itwriting.com/blog/?p=197

  • Rob Mensching, father of Windows Installer XML (WiX), blogs about why managed custom actions are a bad

  • First made available to the public in WiX weekly release 3.0.4116.0 (http://wix.sourceforge.net/releases/3.0.4116.0/ ), DTF provides a framework for easily and reliably writing managed code custom actions for the Windows Installer. In a nutshell, it provides a robust set of interop classes to simplify communicating with MSI and a hosting model to abstract the CLR code from the MSI process. At runtime, MSI thinks it’s calling a Win32 DLL in it’s own sandbox but in reality the CLR is being fired up out of process and communicated with through a named pipe. From your managed codes perspective, you are simply communicating with MSI through the interop classes with no need (generally) to be concerned with all of the nightmares of unmanaged code.

  • Why does the post have to be worded like it's a "bad" thing to write managed custom actions? If my requirements are not affected by the issues documented well here, managed custom action I will write. For that matter, if the .NET framework is corrupt, there's a good chance my application isn't going to run anyway. The customer is STILL going to pick up the phone and call the developer. Or, maybe the application WILL run? I've seen different parts of the .NET framework get "corrupt" (ASP.NET, for example), while other areas function normally. For the same reason, the Wix team shouldn't thrive to prevent us from writing custom actions.

    But, honestly, what do I know? I've never even used WiX or written a custom action!

    I should just shut my mouth and go to sleep. :)

  • Gosh, I didn't realize this was written so long ago. See, I told you I need to go to sleep. :)

  • Hi Alexdresko - There are some architectural issues related to the way that Windows Installer hosts the CLR to run managed code custom actions that can lead to problems.  Rob Mensching described them in a bit of detail at http://robmensching.com/blog/archive/2007/04/19/Managed-Code-CustomActions-no-support-on-the-way-and-heres.aspx.

    Since then, a solution has been developed to host managed code custom actions out of process to avoid these issues.  The WiX v3.0 toolset now ships a set of managed libraries for Windows Installer APIs called the Deployment Tools Framework that contains this functionality.  There is some more information introducing DTF at http://robmensching.com/blog/archive/2008/05/16/Deployment-Tools-Foundation-joins-the-WiX-toolset.aspx.

  • There is a problem with this Windows Installer package: A program run as part of the setup did not finish as expected.

    I get this message when i try to install itunes..what should i do it feels like i been trying to do everything that people have been saying on google..

  • Hi Mike Lew - It might help to look in the setup log file if there is one created during this failed installation.  If there is one, it will probably be in your %temp% directory, and if you'd like, I can try to take a look.  To do that, I'll need you to upload your log file to a file server (such as http://skydrive.live.com) and then reply here and post a link that I can use to download your log file.

    It might also help to search on the Apple iTunes web site to see if there are any known issues or workarounds that they suggest for this type of error.

Page 1 of 2 (17 items) 12
Leave a Comment
  • Please add 1 and 1 and type the answer here:
  • Post