Служба Windows - как сделать имя настраиваемым - PullRequest
8 голосов
/ 18 мая 2011

Я написал службу Windows на C #.Сначала требовалось, чтобы я запускал только один экземпляр этой службы, но это изменилось, и теперь мне нужно несколько экземпляров.Вот почему мне нужно изменить имя службы в соответствии с файлом конфигурации.

Как лучше всего зарегистрировать его с правильным именем?Должен ли я написать другой инструмент для этого?Могу ли я просто прочитать имя из файла App.config и установить его в классах service и installer соответственно?

PS> Я не очень понимаю, как работает эта вещь с именами - нужно устанавливать имена в service и installerклассы, но затем при установке с помощью installutil.exe или даже новой службы powershell имя также должно быть указано.Это должно быть то же самое?Или одно переопределяет другое?

Ответы [ 3 ]

5 голосов
/ 18 мая 2011

Вы можете просто прочитать его из app.config и установить его в классах установщика.
Обычно класс, который наследуется от Installer, создается автоматически.Он содержит член типа System.ServiceProcess.ServiceInstaller, наиболее вероятно с именем serviceProcessInstaller1.Это свойство ServiceName, которое вы можете установить.Кроме того, необходимо установить для свойства ServiceName производного класса ServiceBase то же значение.
В реализации по умолчанию для них установлены постоянные значения в соответствующих методах InitializeComponent, но нет причин придерживаться этого.Это можно сделать динамически без проблем.

2 голосов
/ 07 октября 2015

Я хотел бы добавить свои 2 цента, так как столкнулся с этим. У меня есть файл с именем «ProjectInstaller.cs» с дизайнером и ресурсами под ним. Если открыть его в дизайне, MyServiceInstaller и MyProjectInstaller будут отображаться как элементы в области дизайна. Мне удалось изменить имена в конструкторе ProjectInstaller() и вручную загрузить файл конфигурации из каталога модуля:

public ProjectInstaller()
{
    InitializeComponent();

    var config = ConfigurationManager.OpenExeConfiguration(this.GetType().Assembly.Location);

    if (config.AppSettings.Settings["ServiceName"] != null)
    {
        this.MyServiceInstaller.ServiceName = config.AppSettings.Settings["ServiceName"].Value;
    }
    if (config.AppSettings.Settings["DisplayName"] != null)
    {
        this.MyServiceInstaller.DisplayName = config.AppSettings.Settings["DisplayName"].Value;
    }
}
0 голосов
/ 19 октября 2016

В том же духе, что и ответ Джейсона Гомаата, именно так вы будете проходить по всем доступным установщикам в вашем проекте, что экономит ваше время, когда вы добавляете каждый новый сервис в этот класс. В моем проекте у меня в общей сложности 12 служб (и мы добавляем новую здесь и там), и мы хотели, чтобы они были сгруппированы по имени экземпляра, поэтому службы SVC (экземпляр 1) XX и служба SVC (экземпляр 1) YY находились рядом друг с другом при просмотре в консоли оснастки служб.

    public ProjectInstaller()
    {
        InitializeComponent();

        var config = ConfigurationManager.OpenExeConfiguration(this.GetType().Assembly.Location);

        string instanceName = config.AppSettings.Settings["Installer_NamedInstanceName"].Value;
        string instanceID = config.AppSettings.Settings["Installer_NamedInstanceID"].Value;
        bool usesNamedInstance = !string.IsNullOrWhiteSpace(instanceName) && !string.IsNullOrWhiteSpace(instanceID);

        if (usesNamedInstance)
        {
            foreach (var installer in this.Installers)
            {
                if (installer is ServiceInstaller)
                {
                    var ins = (ServiceInstaller)installer;
                    ins.ServiceName = ins.ServiceName + "-" + instanceID;
                    // Want the service to be named SVC (Instance Name) Audit Log Blah Blah Service
                    ins.DisplayName = ins.DisplayName.Replace("SVC ", "SVC (" + instanceName + ") ");
                }
            }
        }

    }

ОДНАКО , есть еще кое-что, что вам нужно сделать - при инициализации службы вы также должны изменить имя службы, в противном случае вы получите сообщение об ошибке «Исполняемый файл не делает» т реализовать услугу ". Я сделал это, реализовав следующий код в Program.cs:

    internal static void HandleCustomServiceName(ServiceBase sbase)
    {
        if (!string.IsNullOrWhiteSpace(customInstanceName))
        {
            sbase.ServiceName = sbase.ServiceName + "-" + customInstanceName;
        }
    }

Тогда в конструкторе каждого сервиса:

    public SystemEventWatcher()
    {
        InitializeComponent();
        Program.HandleCustomServiceName(this);
    }

Я одобрил ответ Джейсона за то, что он проложил путь к реализации этого в моем собственном проекте. Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...