9

コマンドライン引数を使用して、いくつかの構成をWindowsサービスに渡します(コマンドラインが異なるいくつかのインスタンスになります)。

私のコードは次のようになります:

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);
}); 

私が使用するサービスをインストールするとき:

myhost.exe install -sqlserver:someinstance

残念ながら、sqlserverコマンドラインオプションはインストールフェーズでのみ使用可能であり、サービスのパラメーターには移動しません。そのため、サービスを実行すると、必要なパラメーター値が取得されません。

TopShelfによって開始されたサービスのコマンドラインを変更する方法はありますか?

4

3 に答える 3

4

同様の要件がありますが、残念ながらコマンド ライン パラメータをファイルに保存することはできませんでした。

免責事項: このアプローチは Windows でのみ有効です。

まず、インストール後のアクションを追加しました

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

サービスの ImagePath Windowsレジストリ エントリAddCommanLineParameterToStartupOptionsを更新して、コマンド ライン パラメータを含めます。

TopShelf は、このステップの後にパラメーターを追加するので、重複を避けるため、servicenameこれらinstanceを除外します。それら以外のものを除外したいかもしれませんが、私の場合はこれで十分でした.

     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);
}
于 2016-03-16T18:29:11.980 に答える
2

この時点で簡単にはできません。メーリングリストでこのスレッドを確認します

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

于 2013-03-07T01:06:12.963 に答える
2

サービスに渡されたコマンド ラインを変更することはできません。これらのパラメーターをexeの横の構成に保存することで、これを回避します。したがって、ユーザーはこれを行うことができます:

service.exe run /sqlserver:connectionstring

アプリは接続文字列をファイルに保存します (System.IO.File または ConfigurationManager を使用)。

次に、ユーザーがこれを行う場合:

service.exe run

または、サービスが Windows サービスとして実行されている場合、アプリは構成から読み込まれます。

于 2015-02-26T17:17:48.900 に答える