[英]Can command line arguments be passed to Service class when using InstallUtil?
问题
我正在尝试将参数从命令行传递到我的服务类,该服务类在服务安装之前继承了 ServiceBase。 我找到了一种在使用 InstallUtil 运行我的服务安装程序时接受参数的方法。 但是,运行 ServiceBase.Run(new Service()); 的主函数在可以访问这些参数之前触发。 因此,我不知道如何在运行之前将命令行参数传递到我的 Service() 类中。
我使用 ConfigStream 作为静态类来读取和存储文本配置文件中的参数。 我的目标是在安装程序运行之前从配置文件导入设置并将它们应用到我的服务类。 我希望能够从命令行中的输入指向该配置文件的位置。
尝试的解决方案
我已经尝试将参数应用于安装程序的 OnBeforeInstall 函数内的 ConfigStream 类,但它仍然在主函数之后运行,因此它不会将设置应用于我的服务类。
我也尝试遵循微软的教程,但也没有运气。 参数从未传递给 Main。 教程: 创建 Windows 服务 - 添加可选参数
主类
public static class MainClass
{
///Function: Main
///File: ServiceWrapperV2.cs
///Author: Luke Maple
///Purpose: Main function of program, start up the service portion of program.
static void Main(String[] args)
{
// Test if input arguments were supplied
Console.WriteLine("Args: ");
Console.WriteLine(args);
if (args.Length > 0)
{
// set config location if provided
// otherwise assume in working directory
ConfigStream.setConfigstream(args[0]);
}
// run service
ServiceBase.Run(new Service());
}
}
安装程序尝试 1
[RunInstaller(true)]
public class ServiceWrapperInstaller : Installer
{
private ServiceProcessInstaller processInstaller;
private ServiceInstaller serviceInstaller;
public ServiceWrapperInstaller()
{
//inilizing installer objects
processInstaller = new ServiceProcessInstaller();
serviceInstaller = new ServiceInstaller();
//Service will use the windows local system acount. Service will be run as admin
processInstaller.Account = ServiceAccount.LocalSystem;
//sets service start mode to automatic. service will auto boot on restarts
serviceInstaller.StartType = ServiceStartMode.Automatic;
// set service parameters
// Console.WriteLine(ConfigStream.getSetting("Service Name"));
serviceInstaller.ServiceName = ConfigStream.getSetting("Service Name");
// Console.WriteLine("\nService Name: " + serviceInstaller.ServiceName + "\n");
serviceInstaller.Description = ConfigStream.getSetting("Service Description");
//passing object to be installed
Installers.Add(serviceInstaller);
Installers.Add(processInstaller);
}
private void _setConfigLocation()
{
if (Context.Parameters.ContainsKey("config"))
{
ConfigStream.setConfigstream(Context.Parameters["config"]);
}
}
protected override void OnBeforeInstall(IDictionary savedState)
{
_setConfigLocation();
base.OnBeforeInstall(savedState);
}
}
安装程序尝试 2
[RunInstaller(true)]
public class ServiceWrapperInstaller : Installer
{
private ServiceProcessInstaller processInstaller;
private ServiceInstaller serviceInstaller;
public ServiceWrapperInstaller()
{
//inilizing installer objects
processInstaller = new ServiceProcessInstaller();
serviceInstaller = new ServiceInstaller();
//Service will use the windows local system acount. Service will be run as admin
processInstaller.Account = ServiceAccount.LocalSystem;
//sets service start mode to automatic. service will auto boot on restarts
serviceInstaller.StartType = ServiceStartMode.Automatic;
// set service parameters
// Console.WriteLine(ConfigStream.getSetting("Service Name"));
serviceInstaller.ServiceName = ConfigStream.getSetting("Service Name");
// Console.WriteLine("\nService Name: " + serviceInstaller.ServiceName + "\n");
serviceInstaller.Description = ConfigStream.getSetting("Service Description");
//passing object to be installed
Installers.Add(serviceInstaller);
Installers.Add(processInstaller);
}
protected override void OnBeforeInstall(IDictionary savedState)
{
string parameter = "Config";
Context.Parameters["assemblypath"] = "\"" + Context.Parameters["assemblypath"] + "\" \"" + parameter + "\"";
base.OnBeforeInstall(savedState);
}
}
配置流
public static class ConfigStream
{
// set class properties of ConfigStream
public static string config { get; private set; } = GlobalVariables.cwd + "\\" + GlobalVariables.configFileName;
// constructor with config as an argument
public static void setConfigstream(string config_location)
{
string config = config_location;
}
///Function: (static) getSetting
///Purpose: get requested value form formatted config file
public static string getSetting(string setting)
{
...
}
...
}
你可以尝试这样的事情:
[RunInstaller(true)]
public partial class ServiceWrapperInstaller : Installer
{
private const string nameKey = "name";
private const string displayNameKey = "displayname";
private const string descriptionKey = "description";
protected override void OnBeforeInstall(IDictionary savedState)
{
// Set installer parameters
SetParameters();
base.OnBeforeInstall(savedState);
}
private void SetParameters()
{
// Set service name
_serviceInstaller.ServiceName = this.Context.Parameters[nameKey];
// Set the display name (if provided)
if (Context.Parameters.ContainsKey(displayNameKey))
{
_serviceInstaller.DisplayName = this.Context.Parameters[displayNameKey];
}
// Set the description (if provided)
if (Context.Parameters.ContainsKey(descriptionKey))
{
_serviceInstaller.Description = this.Context.Parameters[descriptionKey];
}
_serviceInstaller.StartType = ServiceStartMode.Automatic;
_serviceInstaller.DelayedAutoStart = true;
}
}
你可以这样使用它:
InstallUtil /u /name= /displayname=<\\"Display Name\\"> /description=<\\"服务描述\\"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.