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


119

У мене є служба Windows, яку я встановлюю за допомогою InstallUtil.exe. Незважаючи на те, що я встановив Метод запуску автоматичний, сервіс не запускається при встановленні, я повинен відкрити послуги вручну та натиснути кнопку "Пуск". Чи є спосіб її запустити або через командний рядок, або через код Сервісу?

Відповіді:


218

У вашому класі встановлення додайте обробник події 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 на своєму інсталяторі, він встановить, а потім запустить послугу автоматично.


40
(коментар із запропонованого редагування): Краще скористатися serviceInstaller.ServiceName, якщо ім'я служби буде змінено, воно буде використовувати правильне ім'я, не потребуючи змінити його в коді.
Марк Гравелл

1
Також не завадило б загорнути тест ServiceControllerу використовуваний оператор.
ChrisO

3
Як ви отримуєте serviceInstaller?
Філіп Рего

1
serviceInstaller повинен бути ServiceInstallerзмінною у вашому класі. Такий клас повинен реалізовуватися System.Configuration.Install.Installer. Для отримання додаткової інформації див. Цей посібник з MSdn .
Серхіо Базурко

4
@PhilipRego Імовірно serviceInstaller- це ServiceInstallerоб'єкт, про який йдеться senderв обробнику подій, який, як правило, використовується в ServiceInstaller()конструкторі. Тому ви можете додати ServiceInstaller serviceInstaller = (ServiceInstaller)sender;перед usingзаявою.
харгуш

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 був кинутий із таким повідомленням про помилку: Неможливо запустити службове ім'я на комп'ютері '.' .. Внутрішній виняток System.ComponentModel.Win32Exception був перекинутий із таким повідомленням про помилку: Виконувана програма, на яку налаштована ця служба Пробіг не реалізує послугу.
goamn

2
Помилки, виявлені після того, як я прокоментував рядок "InitializeComponent ()". Я вважаю, що цей рядок дублює всі інші рядки, оскільки в журналах відображаються дві однакові речі, що відбуваються разом перед помилкою: Встановлення служби serviceName ... Сервіс serviceName успішно встановлений. Створення джерела serviceLog джерела імені в журналі Застосування ... Встановлення служби serviceName ... Створення джерела serviceLame джерела EventLog в журналі Програма ... Виняток стався в обробнику подій OnAfterInstall системи System.ServiceProcess.ServiceInstaller.
goamn

Ви дійсно врятували мені день :) Дякую за цей корисний коментар. Після того, як я прокоментував дзвінок InitializeComponent (), моя служба також почала чудово
Костянтин

7

Як щодо наступних команд?

net start "<service name>"
net stop "<service name>"

Класно. Я написав це у своєму інсталяційному пакетному файлі одразу після того, як буде встановлено.
М. Фавад Сурош

5

Програмні варіанти контролю послуг:

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

4

Ви можете використовувати наступний командний рядок для запуску послуги:

net start *servicename*

2

Використовуйте ServiceController, щоб почати службу з коду.

Оновлення: І більш правильним способом запуску служби з командного рядка є використання команди "sc" ( Service Controller ) замість "net".


6
Чому "sc" - "правильніший" спосіб? Що не так з "чистим запуском" (і командлетом запуску PSH)?
Річард

1
Тому що sc можна викликати з віддаленої машини, тому він завжди працює.
MacGyver

1

Незважаючи на такі Прийнятий відповідь точно, я все ще не міг отримати послугу start-- я замість того, щоб було дано повідомленням про помилку під час установки про те , що послуга , яка була тільки що встановлена не може бути запущена, оскільки вона не існує, не дивлячись на використання 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

Вибачте, мій поганий, я пропустив момент, коли ви явно виключили можливість запуску його через панель управління.
Майкл Клемент

0

Ви можете використовувати GetServicesметод класу ServiceController, щоб отримати масив усіх служб. Потім знайдіть свою послугу, перевіривши ServiceNameвластивість кожної служби. Коли ви знайшли вашу послугу, зателефонуйте до Startспособу її запуску.

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


0

Ви зіпсували дизайнера. Повторно додайте компонент інсталятора. У ньому повинні бути сервісInstaller та serviceProcessInstaller. ServiceInstaller із властивістю методу запуску, встановленого на Автоматичне, запускатиметься після встановлення та після кожного перезавантаження.


0

Лише зауваження: Можливо, ви налаштували свою послугу по-іншому, використовуючи інтерфейс форм, щоб додати інсталятора служби та інсталятора проекту. У цьому випадку замініть там, де написано serviceInstaller.ServiceName, на "ім'я від дизайнера" ​​.ServiceName.

У цьому випадку вам також не потрібні приватні члени.

Дякую за допомогу.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.