简体   繁体   English

使用 InstallUtil 时可以将命令行参数传递给 Service 类吗?

[英]Can command line arguments be passed to Service class when using InstallUtil?

Problem问题

I am trying to pass arguments from the command line to my service class that inherits ServiceBase before the service installation.我正在尝试将参数从命令行传递到我的服务类,该服务类在服务安装之前继承了 ServiceBase。 I found a way to accept parameters when using InstallUtil to run my service installer.我找到了一种在使用 InstallUtil 运行我的服务安装程序时接受参数的方法。 However, the the main function running ServiceBase.Run(new Service());但是,运行 ServiceBase.Run(new Service()); 的主函数triggers before those parameters can be accessed.在可以访问这些参数之前触发。 Therefore, I don't know how to pass command line parameters into my Service() class before it is run.因此,我不知道如何在运行之前将命令行参数传递到我的 Service() 类中。

I am using ConfigStream as a static class to read and store parameters from a text config file.我使用 ConfigStream 作为静态类来读取和存储文本配置文件中的参数。 My goal is to import the settings from the config file and apply them to my Service class before the installer is run.我的目标是在安装程序运行之前从配置文件导入设置并将它们应用到我的服务类。 I'd like to be able to point to the location of that config file from an input in the command line.我希望能够从命令行中的输入指向该配置文件的位置。

Attempted Solutions尝试的解决方案

I've tried applying the parameters to the ConfigStream class within the OnBeforeInstall function of the Installer, but that still runs after the main function, so it doesn't apply the settings to my Service class.我已经尝试将参数应用于安装程序的 OnBeforeInstall 函数内的 ConfigStream 类,但它仍然在主函数之后运行,因此它不会将设置应用于我的服务类。

I also tried following a tutorial from microsoft, but also had no luck.我也尝试遵循微软的教程,但也没有运气。 The parameters were never passed to Main.参数从未传递给 Main。 Tutorial: Create Windows Service - Add Optional Params教程: 创建 Windows 服务 - 添加可选参数

Main Class主类


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

Installer Attempt 1安装程序尝试 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);
        }
    }

Installer Attempt 2安装程序尝试 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);
        }
    }

ConfigStream配置流


    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)
        {
        ...
        }
    ...
    }

You can try something like this:你可以尝试这样的事情:

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

You can use it like this:你可以这样使用它:

InstallUtil /u /name= /displayname=<\\"Display Name\\"> /description=<\\"Description of Service\\" InstallUtil /u /name= /displayname=<\\"Display Name\\"> /description=<\\"服务描述\\"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM