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

16,707

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();
});
Share:
16,707

Related videos on Youtube

vel
Author by

vel

Updated on September 17, 2022

Comments

  • vel
    vel over 1 year

    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?

  • Todd
    Todd about 10 years
    After AddCommandLineDefinition() and before // do something you need to add the following line: configurator.ApplyCommandLine();
  • fuLLMetaLMan
    fuLLMetaLMan over 9 years
    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.
  • char m
    char m over 9 years
    Yes. This is not working when installing/starting it as service. foobar is empty. @fuLLMetaLMan : Did you find an answer?
  • fuLLMetaLMan
    fuLLMetaLMan over 9 years
    Okey, thanks. I just dropped the argument and worked around it. Thanks.
  • Nick Spreitzer
    Nick Spreitzer over 8 years
    Where did you find the documentation for AddCommandLineDefinition()? I don't see it in the docs I found.
  • mikebridge
    mikebridge over 8 years
    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: stackoverflow.com/questions/29837596/…
  • mikebridge
    mikebridge over 8 years
    @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.
  • mikebridge
    mikebridge over 8 years
    ... 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.
  • AaronHS
    AaronHS about 8 years
    "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.