I was creating a Visual Studio solution with a Setup project, and needed to add a set of custom installation steps to the setup. The process for this (Custom Actions) is easy to find in Microsoft’s online documentation, and in many forums.

Yet one thing is common: the level of failure and frustration expressed in the forums is widespread. A lot of folks had problems getting the custom class to work.. and so did I. My initial test for the custom install was just to create a log file persisting the “savedState” contents to a file on the root of C:, so I could examine its contents. The custom installation section never ran.

No matter what I did, something was missing. A few people on the forums strongly advocated abandoning the custom installation, and just go to a batch file with scripts. I wasn’t ready to go down that path. I just sensed that something simple was missing.

The answer for this comes from my colleague, Patrick Thompson, who answered a seemingly off the wall question while we chatted in the hallway outside of the office. He evidently spent a lot of hours figuring this out sometime ago, and saved me a lot of grief. And it is simple…

I was able to create my Class library for the custom installation, and include it in the application folder in the setup project. In the custom actions panel, I added the custom project to the Install and Rollback folders: the two methods my code was overriding with custom code.

The original configuration

The code for the class is here. Note that the class does not use a namespace, so that it resides in the default namespace.

But, in order for the custom code to actually work properly… All of the folders (methods) in the custom action panel must be populated with the same assembly, even if the assembly isn’t doing any real overrides to the base method. So, the proper way this should be setup is…

The proper configuration

Sure enough after making the change, the next compile and execution of the MSI package generated my test file on the C: drive, just as it should have. So there you have the missing piece to custom actions, when it looks like all hope is lost.

And here is the output written to the log file, in case you wonder what savedState settings are available by default:

_reserved_nestedSavedStates = "System.Collections.IDictionary[]"
_reserved_lastInstallerAttempted = "-1"
Committed (Context.Parameters...
action = "commit"
installtype = "notransaction"
assemblypath = "C:\Program Files\Bits of Genius\Folder Manifest\FolderManifestCustomInstallation.dll"
logfile = ""

FolderManifest is a utility application tied to Windows Explorer context, which I will be posting shortly.