Автоматически запускать службу Windows при установке

У меня есть служба Windows, которую я устанавливаю с помощью InstallUtil.exe. Несмотря на то, что я установил для параметра «Метод запуска» значение «Автоматический», служба не запускается при установке, мне приходится вручную открывать службы и нажимать кнопку «Пуск». Есть ли способ запустить его через командную строку или через код Сервиса?


person mickyjtwin    schedule 24.06.2009    source источник


Ответы (13)


В своем классе установщика добавьте обработчик для события AfterInstall. Затем вы можете вызвать ServiceController в обработчике событий, чтобы запустить службу.

using System.ServiceProcess;
public ServiceInstaller()
{
    //... Installer code here
    this.AfterInstall += new InstallEventHandler(ServiceInstaller_AfterInstall);
}

void ServiceInstaller_AfterInstall(object sender, InstallEventArgs e)
{
    ServiceInstaller serviceInstaller = (ServiceInstaller)sender;

    using (ServiceController sc = new ServiceController(serviceInstaller.ServiceName))
    {
             sc.Start();
    }
}

Теперь, когда вы запустите InstallUtil в своем установщике, он установит, а затем автоматически запустит службу.

person codemonkey    schedule 25.06.2009
comment
(комментарий из предложенного редактирования): лучше использовать serviceInstaller.ServiceName, если имя службы будет изменено, оно будет использовать правильное имя без необходимости изменять его в коде. - person Marc Gravell; 01.02.2011
comment
Также не помешало бы заключить ServiceController в оператор using. - person ChrisO; 21.10.2013
comment
Мне нужно было указать идентификатор установщика службы в OnBeforeInstall. Что-то вроде serviceInstaller = serviceInstaller1; где serviceInstaller1 - это идентификатор от дизайнера. Выполнение этого в OnBeforeInstall сделало все вышеописанное для меня безупречным. Я не пробовал, но вы также можете сделать это в вызове ServiceInstaller (). - person Micah Montoya; 05.09.2016
comment
Вы также можете использовать Отображаемое имя службы вместо serviceInstaller.ServiceName. - person SurenSaluka; 21.10.2016
comment
Как вы получаете serviceInstaller? - person Philip Rego; 01.12.2016
comment
serviceInstaller должен быть переменной ServiceInstaller в вашем классе. Такой класс должен реализовывать System.Configuration.Install.Installer. Дополнительную информацию см. В этом руководстве по msdn. . - person Sergio Basurco; 17.01.2017
comment
@PhilipRego Предположительно serviceInstaller - это объект ServiceInstaller, на который указывает sender в обработчике событий, который обычно создается в конструкторе ServiceInstaller(). Поэтому вы можете добавить ServiceInstaller serviceInstaller = (ServiceInstaller)sender; перед оператором using. - person khargoosh; 10.02.2017
comment
Это еще одна из тех малоизвестных вещей, которые Microsoft вряд ли объясняет, не создает свойство в своей среде IDE и не имеет возможности сделать это в своем бесплатном расширении Visual Studio Installer Projects. Я надеюсь, что кто-то также понимает, что если они используют проекты установщика Visual Studio для установки, они добавляют настраиваемое действие с этими дополнительными шагами: Используйте скомпилированный проект установки для установки службы Windows. - person Volomike; 08.10.2017
comment
Это спасло меня ... изменилось только одно ... Я использовал .. this.serviceInstaller.ServiceName - person Ziggler; 20.12.2018

После небольшого рефакторинга это пример полного установщика службы Windows с автоматическим запуском:

using System.ComponentModel;
using System.Configuration.Install;
using System.ServiceProcess;

namespace Example.of.name.space
{
[RunInstaller(true)]
public partial class ServiceInstaller : Installer
{
    private readonly ServiceProcessInstaller processInstaller;
    private readonly System.ServiceProcess.ServiceInstaller serviceInstaller;

    public ServiceInstaller()
    {
        InitializeComponent();
        processInstaller = new ServiceProcessInstaller();
        serviceInstaller = new System.ServiceProcess.ServiceInstaller();

        // Service will run under system account
        processInstaller.Account = ServiceAccount.LocalSystem;

        // Service will have Automatic Start Type
        serviceInstaller.StartType = ServiceStartMode.Automatic;

        serviceInstaller.ServiceName = "Windows Automatic Start Service";

        Installers.Add(serviceInstaller);
        Installers.Add(processInstaller);
        serviceInstaller.AfterInstall += ServiceInstaller_AfterInstall;            
    }
    private void ServiceInstaller_AfterInstall(object sender, InstallEventArgs e)
    {
        ServiceController sc = new ServiceController("Windows Automatic Start Service");
        sc.Start();
    }
}
}
person Pedro Pereira    schedule 13.07.2011
comment
Этот код дал мне следующую ошибку: исключение на этапе установки. System.InvalidOperationException: исключение произошло в обработчике событий OnAfterInstall System.ServiceProcess.ServiceInstaller. Возникло внутреннее исключение System.InvalidOperationException со следующим сообщением об ошибке: Невозможно запустить службу serviceName на компьютере '.' .. Вызвано внутреннее исключение System.ComponentModel.Win32Exception со следующим сообщением об ошибке: Исполняемая программа, на которую настроена эта служба run in не реализует службу. - person goamn; 01.05.2014
comment
Ошибки зафиксированы после того, как я закомментировал строку InitializeComponent (). Я считаю, что эта строка дублирует все другие строки, поскольку журналы, кажется, показывают две идентичные вещи, происходящие вместе до ошибки: Установка service serviceName ... Service serviceName была успешно установлена. Создание журнала событий с именем службы в журнале Приложение ... Установка службы имя службы ... Создание журнала событий с именем службы в журнале Приложение ... Возникло исключение в обработчике событий OnAfterInstall System.ServiceProcess.ServiceInstaller. - person goamn; 01.05.2014
comment
Вы действительно спасли мне день :) Спасибо за полезный комментарий. После того, как я закомментировал вызов InitializeComponent (), моя служба также отлично запустилась - person Konstantin; 28.02.2018

Как насчет следующих команд?

net start "<service name>"
net stop "<service name>"
person Hemant    schedule 24.06.2009
comment
Прохладный. Я написал это в своем командном файле установки сразу после завершения установки. - person M. Fawad Surosh; 16.01.2020

Программные варианты управления услугами:

  • Можно использовать собственный код, «Запуск службы» . Максимальный контроль с минимумом зависимостей, но большая часть работы.
  • WMI: Win32_Service имеет StartService метод. Это хорошо для случаев, когда вам нужно иметь возможность выполнять другую обработку (например, чтобы выбрать, какую услугу).
  • PowerShell: выполнить Start-Service через _3 _ или создав свой собственный Runspace и используя его _ 5_ метод для выполнения. Это хорошо для случаев, когда вам нужно иметь возможность выполнять другую обработку (например, чтобы выбрать, какую службу) с гораздо более простой моделью кодирования, чем WMI, но зависит от установленного PSH.
  • Приложение .NET может использовать ServiceController
person Richard    schedule 24.06.2009

Вы можете использовать следующую командную строку для запуска службы:

net start *servicename*
person AlexDrenea    schedule 24.06.2009

Используйте ServiceController, чтобы запустить службу из кода. .

Обновление: И более правильный способ запустить службу из командной строки - использовать "sc" (Service Controller) вместо net.

person arbiter    schedule 24.06.2009
comment
Почему sc более правильный способ? Что не так с net start (и командлетом PSH start-service)? - person Richard; 24.06.2009
comment
Поскольку sc можно вызывать с удаленной машины, он всегда работает. - person MacGyver; 04.12.2015

Несмотря на то, что я точно следовал принятому ответу, мне все равно не удалось запустить службу - вместо этого во время установки мне было выдано сообщение об ошибке, в котором говорилось, что только что установленная служба не может быть запущена, поскольку она не существует, несмотря на использование this.serviceInstaller.ServiceName а не буквально ...

В конце концов я нашел альтернативное решение, использующее командную строку:

private void serviceInstaller_AfterInstall(object sender, InstallEventArgs e) {
        ProcessStartInfo startInfo = new ProcessStartInfo();
        startInfo.WindowStyle = ProcessWindowStyle.Hidden;
        startInfo.FileName = "cmd.exe";
        startInfo.Arguments = "/C sc start " + this.serviceInstaller.ServiceName;

        Process process = new Process();
        process.StartInfo = startInfo;
        process.Start();
    }
person Matsu Q.    schedule 04.01.2013

Вот процедура и код, использующий сгенерированный ProjectInstaller в Visual Studio:

  1. Создать проект Служба Windows в Visual Studio
  2. Создать установщики для службы
  3. Откройте ProjectInstaller в редакторе дизайна (он должен открываться автоматически при создании установщика) и установите свойства созданных serviceProcessInstaller1 (например, Account: LocalSystem) и serviceInstaller1 (например, StartType: Automatic)
  4. Откройте ProjectInstaller в редакторе кода (нажмите F7 в редакторе дизайна) и добавьте обработчик событий в ServiceInstaller.AfterInstall - см. Следующий код. Он запустит службу после ее установки.

ProjectInstaller класс:

using System.ServiceProcess;


[RunInstaller(true)]
public partial class ProjectInstaller : System.Configuration.Install.Installer
{
    public ProjectInstaller()
    {
        InitializeComponent(); //generated code including property settings from previous steps
        this.serviceInstaller1.AfterInstall += Autorun_AfterServiceInstall; //use your ServiceInstaller name if changed from serviceInstaller1
    }

    void Autorun_AfterServiceInstall(object sender, InstallEventArgs e)
    {
        ServiceInstaller serviceInstaller = (ServiceInstaller)sender;
        using (ServiceController sc = new ServiceController(serviceInstaller.ServiceName))
        {
            sc.Start();
        }
    }
}
person Fenix    schedule 13.08.2020

Автоматический запуск означает, что служба запускается автоматически при запуске Windows. Как уже упоминалось, чтобы запустить его из консоли, вы должны использовать ServiceController.

person Michael Klement    schedule 24.06.2009
comment
Я не хочу этого делать. Я хочу сделать это за один раз из командной строки или из классов службы Windows. - person mickyjtwin; 24.06.2009
comment
Извините, моя беда, я упустил момент, когда вы явно исключили возможность запуска через панель управления. - person Michael Klement; 24.06.2009

Для получить массив всех услуг. Затем найдите свою службу, проверив свойство ServiceName каждой службы. Когда вы найдете свою службу, вызовите метод Start, чтобы запустить ее.

Вы также должны проверить свойство Status, чтобы увидеть, в каком состоянии оно уже находится перед вызовом start (оно может быть запущено, приостановлено, остановлено и т. Д.).

person adrianbanks    schedule 24.06.2009

Вы испортили своего дизайнера. Повторно добавьте компонент установщика. У него должны быть установщик служб и установщик процессов. ServiceInstaller со свойством Startup Method, установленным на Automatic, будет запускаться при установке и после каждой перезагрузки.

person Guillaume Massé    schedule 14.07.2011

Просто примечание: вы могли настроить свою службу по-другому, используя интерфейс форм, чтобы добавить установщик службы и установщик проекта. В этом случае замените место, где написано serviceInstaller.ServiceName, на «имя от дизайнера» .ServiceName.

В этом случае вам также не нужны частные члены.

Спасибо за помощь.

person IanUniacke    schedule 29.05.2014

Для меня это нормально. В сервисный проект добавить в Installer.cs

[RunInstaller(true)]
public partial class ProjectInstaller : System.Configuration.Install.Installer
{
    public ProjectInstaller()
    {
        InitializeComponent();
    }
 
    protected override void OnAfterInstall(IDictionary savedState)
    {
        base.OnAfterInstall(savedState);
 
        //The following code starts the services after it is installed.
        using (System.ServiceProcess.ServiceController serviceController = new System.ServiceProcess.ServiceController(serviceInstaller1.ServiceName))
        {
            serviceController.Start();
        }
    }
}
person ismail uzunok    schedule 18.09.2020