如何在TopShelf中指定服务的命令行选项 [英] How to specify command line options for service in TopShelf
问题描述
我正在使用命令行参数将某些配置传递给Windows服务(它将是少数几个具有不同命令行的实例)。
I am using command line arguments to pass some configuration to the windows service (it will be few instances with different command lines).
我的代码如下所示:
HostFactory.Run(x =>
{
x.Service<MyHost>(s =>
{
s.ConstructUsing(name => new MyHost());
s.WhenStarted(tc => tc.Start());
s.WhenStopped(tc => tc.Stop());
});
x.AddCommandLineDefinition("sqlserver", v => sqlInstance = v);
});
在安装服务时,我使用:
When I install service I use:
myhost.exe install -sqlserver:someinstance
不幸的是, sqlserver
命令行选项仅在安装阶段可用,而不能转到服务的参数。因此,当我运行服务时,没有得到所需的参数值。
Unfortunately, sqlserver
command line options is available only on install phase, and do not go to the parameters of the service. So when I run service, I do not get parameter value I need.
有什么方法可以修改TopShelf启动的服务的命令行吗?
Is there any way to modify command line of the service started by TopShelf?
推荐答案
我也有类似的要求,但是不幸的是,不能将命令行参数存储在文件中。
I have a similar requirement and unfortunately storing the command line parameters in a file was not an option.
免责声明:此方法仅对Windows有效
首先我添加了安装后操作
x.AfterInstall(
installSettings =>
{
AddCommandLineParametersToStartupOptions(installSettings);
});
在 AddCommanLineParameterToStartupOptions
中,我更新了该服务的ImagePath Windows注册表项包括命令行参数。
In AddCommanLineParameterToStartupOptions
I update the ImagePath Windows Registry entry for the service to include the command line parameters.
TopShelf在此步骤之后添加其参数,以避免重复 servicename
和 instance
我将它们过滤掉了。您可能需要过滤的内容不止这些,但就我而言,这已经足够。
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);
}
这篇关于如何在TopShelf中指定服务的命令行选项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!