How to make a Windows service with parameters?

后端 未结 5 923
庸人自扰
庸人自扰 2020-12-31 07:33

I have written a Windows service, of which I want to have 1 instance running per customer. This is because the customers each have their own DB with identical schemas; the

5条回答
  •  再見小時候
    2020-12-31 08:00

    You can pass parameters to your installer using installutil, for example ServiceName and DisplayName.

    ProjectInstaller.cs

    public partial class ProjectInstaller : Installer
    {
        protected override void OnBeforeInstall(IDictionary savedState)
        {
            SetServiceName();
            base.OnBeforeInstall(savedState);
        }
    
        protected override void OnBeforeUninstall(IDictionary savedState)
        {
            SetServiceName();
            base.OnBeforeUninstall(savedState);
        }
    
        private string AppendParameter(string path, char parameter, string value)
        {
            if (!path.StartsWith("\""))
                path = $"\"{path}\"";
    
            if (value.Contains(" "))
                value = $"\"{value}\"";
    
            return $"{path} -{parameter}{value}";
        }
    
        private void SetServiceName()
        {
            if (Context.Parameters.ContainsKey("ServiceName"))
                serviceInstaller.ServiceName = Context.Parameters["ServiceName"];
    
            if (Context.Parameters.ContainsKey("DisplayName"))
                serviceInstaller.DisplayName = Context.Parameters["DisplayName"];
    
            Context.Parameters["assemblypath"] = AppendParameter(Context.Parameters["assemblypath"], 's', serviceInstaller.ServiceName);
        }
    }
    

    This will append a parameter to the path stored with the service, for example:

    Before: "C:\Service.exe"

    After: "C:\Service.exe" -s"Instance 1"

    You can then read this parameter when you start the service and pass to your services constructor.

    Program.cs

    static void Main(string[] args)
    {
        string serviceName = args.Single(x => x.StartsWith("-s")).Substring("-s".Length);
    
        ServiceBase service = new Service(serviceName);
        ServiceBase.Run(service);
    }
    

    Service.cs

    public partial class Service : ServiceBase
    {
        public Service(string serviceName)
        {
            InitializeComponent();
    
            ServiceName = serviceName;
        }
    }
    

    Usage

    installutil /ServiceName="Instance 1" /DisplayName="Instance 1 Service" "C:\Service.exe"
    installutil /ServiceName="Instance 2" /DisplayName="Instance 2 Service" "C:\Service.exe"
    

提交回复
热议问题