Tag Archive for Installer

Custom ConfigurationSectionHandlers in InstallerClasses

I’m writing an installer class for an MSI Setup Project, and find myself needing to manipulate my web.config containing a custom ConfigurationSection. This should be trivial seeing as my SectionHandler code is bundled with the rest of the application, but fails miserably on my GetSection() call, because the DLL containing it is unavailable to MSIEXEC, which runs from C:WindowsSystem32. What to do, what to do?

Several options:

1) Rather than using the custom ConfigurationSection, I can open my web.config as a standard XmlDocument and do the changes manually.

Pro: No depenencies.
Con: More complicated, untyped, more error-prone.

2) Copy my section handler DLL to %SystemRoot%System32 during installation.

Pro: Simple.
Con: Ugly, goes against the “Don’t touch System32” philosophy that serves us well.

3) Launch a new AppDomain whose BaseDirectory points to my bin path, and do all my config-mangling there.

Pro: Clean, strongly typed, etc.
Con: More work. Causes my relatively simple installer class to grow in size and complexity.

 

Right now, I’m leaning towards #2. Keeping it simple, even if ugly. After all, no-one really looks in System32, and uninstalling the application will uninstall those files as well. No harm done.

Anyone got any other approaches, mitigating factors or other suggestions?

InstallerClasses and little-known gems.

I’m writing an Installer class for an MSI installer project, and passing a checkbox’s value from the MSI UI. I noticed that when I pass the checkbox’s linked variable into my code, it’s received as a string, and not only a string – the possible values are “1” and “0”.

This is where I started cursing softly, because as well know, the bool.Parse method can only accept the strings “True” and “False” to parse, and not the commonly-found “1” and “0”. Sure, I can put in a line such as this:

bool useSetting = Context.Parameters[“MyParam”] == “1”;

but you’ll have to agree that it’s much uglier than:

bool useSetting = bool.Parse(Context.Parameters[“MyParam”]);

At least as far as I’m concerned. C/C++ veterans probably have no issue with the first one, but I take offense at this weakly typed pain.

Luckily, it would seem, the .NET class developers felt my pain, and decided that while this icky string comparison is necessary, there’s no reason for me to see it. The InstallContext class contains a method called IsParameterTrue which does exactly this sort of string comparison, only a bit more robust than I would have bothered to write. So now I can just use this:

bool useSetting = Context.IsParameterTrue(“MyParam”);

and feel good about myself.

Windows Services, services.msc and the “This Service is marked for deletion” error.

In my current project, we have a windows service that we are developing and debugging, which involves a lot of installing/uninstalling the service. One common problem when uninstalling a service is that while the uninstallation is successful, you still see the service listed in the Services console(services.msc). If you try to start it, stop it or uninstall it again (using installutil.exe or sc delete) you get an uninformative “This service has been marked for deletion”.

The KB article about this problem suggests you restart the computer, which is pretty much overkill. Sure, it’ll work, but you’ll never find out what caused it in the first place. Turns out it’s a pretty simple affair: just make sure you close the Services console, which apparently holds a handle of some sort to it. You don’t have to do it before you uninstall. The minute you close the console, all services marked for deletion will be deleted, and all will be well.

When doing it on a server, it’s important to make sure you’ve closed all Services consoles on all active sessions. I’ve seen this error happen when no console was open, and it was fixed by running Task Manager and killing all instances of mmc.exe. I could have logged on to the other sessions and closed it gracefully, but I was lazy. Did the trick.