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

119

У меня есть служба Windows, которую я устанавливаю с помощью InstallUtil.exe. Несмотря на то, что я установил для параметра Startup Method значение Automatic, служба не запускается при установке, мне приходится вручную открывать службы и нажимать Start. Есть ли способ запустить его через командную строку или через код Сервиса?

mickyjtwin
источник

Ответы:

219

В своем классе установщика добавьте обработчик для события 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 в своем установщике, он установит, а затем автоматически запустит службу.

codemonkey
источник
40
(комментарий из предложенного редактирования): лучше использовать serviceInstaller.ServiceName, если имя службы будет изменено, оно будет использовать правильное имя без необходимости изменять его в коде.
Марк Грейвелл
1
Также не помешало бы обернуть ServiceControllerоператор using.
ChrisO
3
Как у вас работает serviceInstaller?
Филип Рего
1
serviceInstaller должен быть ServiceInstallerпеременной в вашем классе. Такой класс должен реализовать System.Configuration.Install.Installer. См. Это руководство msdn для получения дополнительной информации.
Серхио Басурко
4
@PhilipRego Предположительно serviceInstallerэто ServiceInstallerобъект, на который ссылается senderобработчик событий, который обычно создается в ServiceInstaller()конструкторе. Поэтому вы можете добавить ServiceInstaller serviceInstaller = (ServiceInstaller)sender;перед usingзаявлением.
khargoosh
28

После небольшого рефакторинга это пример полного установщика службы 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 Start Type of Manual
        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();
    }
}
}
Педро Перейра
источник
2
Этот код дал мне следующую ошибку: исключение на этапе установки. System.InvalidOperationException: исключение произошло в обработчике событий OnAfterInstall для System.ServiceProcess.ServiceInstaller. Возникло внутреннее исключение System.InvalidOperationException со следующим сообщением об ошибке: Невозможно запустить службу serviceName на компьютере '.' .. Вызвано внутреннее исключение System.ComponentModel.Win32Exception со следующим сообщением об ошибке: Исполняемая программа, на которую настроена эта служба run in не реализует службу.
goamn
2
Ошибки зафиксированы после того, как я закомментировал строку «InitializeComponent ()». Я считаю, что эта строка дублирует все другие строки, поскольку журналы, кажется, показывают две идентичные вещи, происходящие вместе до ошибки: Установка service serviceName ... Service serviceName была успешно установлена. Создание журнала событий с именем службы в журнале Приложение ... Установка службы имя службы ... Создание журнала событий с именем службы источника в журнале Приложение ... Возникло исключение в обработчике событий OnAfterInstall System.ServiceProcess.ServiceInstaller.
goamn
Вы действительно спасли мне день :) Спасибо за полезный комментарий. После того, как я закомментировал вызов InitializeComponent (), мой сервис также заработал отлично
Константин
7

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

net start "<service name>"
net stop "<service name>"
Hemant
источник
Прохладно. Я написал это в своем командном файле установки сразу после завершения установки.
М. Фавад Сурош
5

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

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

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

net start *servicename*
AlexDrenea
источник
2

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

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

арбитр
источник
6
Почему «sc» «более правильный» способ? Что не так с "net start" (и командлетом PSH start-service)?
Ричард
1
Поскольку sc можно вызывать с удаленной машины, он всегда работает.
MacGyver,
1

Несмотря на то, что я точно следовал принятому ответу, мне все равно не удалось запустить службу - вместо этого во время установки мне было выдано сообщение об ошибке, в котором говорилось, что только что установленная служба не может быть запущена, так как она не существует, несмотря на то 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();
    }
Мацу К.
источник
0

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

Майкл Клемент
источник
Я не хочу этого делать. Я хочу сделать это за один раз из командной строки или из классов службы Windows.
mickyjtwin
Извините, моя беда, я упустил момент, когда вы явно исключили возможность запуска через панель управления.
Michael Klement,
0

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

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

adrianbanks
источник
0

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

Гийом Массе
источник
0

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

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

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

IanUniacke
источник