How can I use CommandLine Arguments that is not recognized by TopShelf?
Asked Answered
M

1

24

I want to pass some custom arguments to the console app when I install and start it as a Windows Service via TopShelf.

When I use:

MyService install start /fooBar: Test

Console application fails:

[Failure] Command Line An unknown command-line option was found: DEFINE: fooBar = Test

Question:

How can I make my arguments to be recognizable by TopShelf so that I can consume their values?

Moribund answered 21/2, 2013 at 14:4 Comment(0)
N
40

EDIT: This only works when running the .exe, not when running as a service. As an alternative you could add the option as a configuration value and read it at start-up (which is probably better practice anyway):

using System.Configuration;

// snip

string foobar = null;

HostFactory.Run(configurator =>
{
    foobar = ConfigurationManager.AppSettings["foobar"];

    // do something with fooBar

    configurator.Service<ServiceClass>(settings =>
    {
        settings.ConstructUsing(s => GetInstance<ServiceClass>());
        settings.WhenStarted(s => s.Start());
        settings.WhenStopped(s => s.Stop());
    });

    configurator.RunAsLocalService();
    configurator.SetServiceName("ServiceName");
    configurator.SetDisplayName("DisplayName");
    configurator.SetDescription("Description");
    configurator.StartAutomatically();
});

According to the documentation you need to specify the commands in this pattern:

-foobar:Test

You also need to add the definition in your service configuration:

string fooBar = null;

HostFactory.Run(configurator =>
{
    configurator.AddCommandLineDefinition("fooBar", f=> { fooBar = f; });
    configurator.ApplyCommandLine();

    // do something with fooBar

    configurator.Service<ServiceClass>(settings =>
    {
        settings.ConstructUsing(s => GetInstance<ServiceClass>());
        settings.WhenStarted(s => s.Start());
        settings.WhenStopped(s => s.Stop());
    });

    configurator.RunAsLocalService();
    configurator.SetServiceName("ServiceName");
    configurator.SetDisplayName("DisplayName");
    configurator.SetDescription("Description");
    configurator.StartAutomatically();
});
Nitro answered 18/6, 2013 at 17:27 Comment(9)
After AddCommandLineDefinition() and before // do something you need to add the following line: configurator.ApplyCommandLine();Sharpfreeze
Can you add a commandline argument to the ServiceClass? Im trying to do that, but it wont work when I start it as a service.Bronwynbronx
Yes. This is not working when installing/starting it as service. foobar is empty. @Bronwynbronx : Did you find an answer?Joshuajoshuah
Okey, thanks. I just dropped the argument and worked around it. Thanks.Bronwynbronx
Where did you find the documentation for AddCommandLineDefinition()? I don't see it in the docs I found.Carola
According to Topshelf's author, command-line arguments don't work when installed as a service. You can hack around it by modifying the registry yourself though: #29838096Supplicant
@Nick, and yes, TopShelf documentation is very spotty. Since you often pass lambdas within lambdas within lambdas, it's difficult to figure out how to set something up properly.Supplicant
... speaking of spotty documentation, I'm guessing that you shouldn't call ApplyCommandLine() explicitly. I noticed it was being called twice, so it must get called somewhere during app startup. In the above code, fooBar will be available by the time that the lambda that is passed to configurator.Service<ServiceClass> is evaluated.Supplicant
"Since you often pass lambdas within lambdas within lambdas, it's difficult to figure out how to set something up properly" - by that reasoning would could argue "Since you often pass parameters within methods calling other methods, it's difficult to figure out how to set something up properly". Nested lambdas are no more difficult to deal with than regular methods. My guess is you're just not familiar with them. That's not a complexity problem, it's an educational and familiarity problem.Contain

© 2022 - 2024 — McMap. All rights reserved.