views:

142

answers:

2

I am building a reusable framework for building scheduling services using the .NET Framework. My code is distributed as a library, which is then referenced by the user in a console application. In the main entry point of the application, the user is asked to transfer control to a static method in the library, which will commence job scheduling if running in non-interactive mode, alternatively read command arguments and perform maintenance tasks such as installation.

In order to install the application as a Windows service using the System.Configuration.Install namespace, the user will have to add a class descendant of Installer to the application assembly, telling the framework how to install the service. I really would prefer to do this once and for all in the library, but unfortunately the installer class has to be in the application assembly.

The solution that I am looking at right now, involves defining the an installer class in the library, and requiring the user to inherit this in a public class, without adding any additional code. While this works, it requires the user to write annoying boiler plate code.

What are the alternatives to extending Installer? Can I access the managed installation framework in more direct way?

+3  A: 

I use SC.exe to register the service binary.

Doing so leaves only this stub in the service installer class:

[RunInstaller(true)]
public partial class SoapSenderInstaller : Installer
{
    public SoapSenderInstaller()
    {
        InitializeComponent();
    }
}

Calling SC.exe is a simple as this:

sc create MyService binpath= "C:\Path\to\my\MyService.exe" DisplayName= "My Service Display Name" depend= MSMQ start= auto

The only pitfall is the way sc.exe expects its commmand line arguments:

binpath=[BLANK]"MyService.exe"

EDIT

Of course this solution falls short to the requirement that user should not have to create any code that makes his binary a windows service because if he just references your library he would still need to inherit from ServiceBase and implement OnStart() and OnStop().

Filburt
The installer class would still have to reside to in the entry assembly, not in a referenced library, right?
Jørn Schou-Rode
Yes, the installer class resides in the entry assembly but is practically empty. I did not yet try to complete omit the installer but maybe it would even be possible to so since it's only needed by InstallUtil.
Filburt
Note that "sc.exe" is not available in Win2000 (not in default instalation, but may be installed with some tool-kit from MS)
kibab
After doing a bit of research and experiments, it appears to me that `sc` does not require an `Installer` to be present *at all*. As I understand it, `sc` does not even know/care if my binary is .NET or not. I guess this solves my problem.
Jørn Schou-Rode
+1. As a follow-up to kibab, how is SC.exe distributed? With what OS is it distributed? Filburt's link references some kind of resource kit, but I'm not sure which one.
flipdoubt
@flipdoubt - SC.exe is available from XP and Windows 2003 upward as an "onboard tool". As kibab points out it is not available on Win2000 and downward - in this case you can obtain it from the respective platform resource kit.
Filburt
A: 

I know that you can add some custom fields to installer and require user's input during installation if you compile it using Installer.CodeEffects.com. May be, by requiring a namespace or type name as a string input from the end user, you could load or invoke things that you need on the fly at run time?

I can't think of anything else in your situation.

Jane