How to specify command line options for service in TopShelf

前端 未结 3 1444
予麋鹿
予麋鹿 2021-01-11 22:59

I am using command line arguments to pass some configuration to the windows service (it will be few instances with different command lines).

My code looks like this:

相关标签:
3条回答
  • 2021-01-11 23:02

    I have a similar requirement and unfortunately storing the command line parameters in a file was not an option.

    Disclaimer: This approach is only valid for Windows

    First I added an After Install Action

    x.AfterInstall(
        installSettings =>
        {
             AddCommandLineParametersToStartupOptions(installSettings);
        });
    

    In AddCommanLineParameterToStartupOptions I update the ImagePath Windows Registry entry for the service to include the command line parameters.

    TopShelf adds it's parameters after this step so to avoid duplicates of servicename and instance I filter these out. You may want to filter out more than just those but in my case this was enough.

         private static void AddCommandLineParametersToStartupOptions(InstallHostSettings installSettings)
         {
                var serviceKey = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(
                    $"SYSTEM\\CurrentControlSet\\Services\\{installSettings.ServiceName}",
                    true);
    
                if (serviceKey == null)
                {
                    throw new Exception($"Could not locate Registry Key for service '{installSettings.ServiceName}'");
                }
    
                var arguments = Environment.GetCommandLineArgs();
    
                string programName = null;
                StringBuilder argumentsList = new StringBuilder();
    
                for (int i = 0; i < arguments.Length; i++)
                {
                    if (i == 0)
                    {
                        // program name is the first argument
                        programName = arguments[i];
                    }
                    else
                    {
                        // Remove these servicename and instance arguments as TopShelf adds them as well
                        // Remove install switch
                        if (arguments[i].StartsWith("-servicename", StringComparison.InvariantCultureIgnoreCase) |
                            arguments[i].StartsWith("-instance", StringComparison.InvariantCultureIgnoreCase) |
                            arguments[i].StartsWith("install", StringComparison.InvariantCultureIgnoreCase))
                        {
                            continue;
                        }
                        argumentsList.Append(" ");
                        argumentsList.Append(arguments[i]);
                    }
                }
    
                // Apply the arguments to the ImagePath value under the service Registry key
                var imageName = $"\"{Environment.CurrentDirectory}\\{programName}\" {argumentsList.ToString()}";
                serviceKey.SetValue("ImagePath", imageName, Microsoft.Win32.RegistryValueKind.String);
    }
    
    0 讨论(0)
  • 2021-01-11 23:19

    You can't modify the command line passed to the service. I get around this by saving those parameters to configuration next to the exe. So a user can do this:

    service.exe run /sqlserver:connectionstring
    

    and the app saves the connectionstring to a file (either using System.IO.File or using ConfigurationManager)

    Then, if the user does this:

    service.exe run
    

    Or if the service runs as a windows service, then the app just loads from config.

    0 讨论(0)
  • 2021-01-11 23:28

    You can't easily do it at this point. I would review this thread on the mailing list

    https://groups.google.com/d/msg/topshelf-discuss/Xu4XR6wGWxw/GFzmKdn_MeYJ

    0 讨论(0)
提交回复
热议问题