2013-03-06 80 views
8

我正在使用命令行參數將一些配置傳遞給windows服務(這將是少數幾個具有不同命令行的實例)。如何在TopShelf中指定服務的命令行選項

我的代碼如下所示:

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啓動的服務的命令行?

回答

2

在此線程不能修改傳遞給服務的命令行。我通過將這些參數保存到exe旁邊的配置來解決這個問題。這樣用戶就可以做到這一點:

service.exe run /sqlserver:connectionstring 

和應用程序保存ConnectionString,以一個文件(使用有System.IO.File或使用ConfigurationManager中)

然後,如果用戶做這個的:

service.exe run 

或者如果服務作爲Windows服務運行,那麼應用程序只從配置中加載。

3

我有類似的要求,不幸的是將命令行參數存儲在文件中不是一個選項。

聲明:此方法僅適用於Windows

首先我增加了一個After Install Action

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

AddCommanLineParameterToStartupOptions我更新的服務的ImagePath Windows註冊表項以包括該命令行參數。

TopShelf在此步驟後添加它的參數,以避免重複的servicenameinstance我將它們過濾掉。你可能想過濾掉更多的東西,但在我的情況下,這已經足夠了。

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