2009-06-24 3 views
103

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

ответ

180

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

using System.ServiceProcess; 

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

void ServiceInstaller_AfterInstall(object sender, InstallEventArgs e) 
{ 
    using (ServiceController sc = new ServiceController(serviceInstaller.ServiceName)) 
    { 
     sc.Start(); 
    } 
} 

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

+39

(комментарий от предлагаемого редактирования): лучше использовать serviceInstaller.ServiceName, если имя servicename будет изменено, оно будет использовать правильное имя без необходимости его изменения в коде. –

+1

Также не помешает обернуть «ServiceController» в операторе using. – ChrisO

+0

Мне нужно было указать идентификатор сервисного установщика в OnBeforeInstall. Что-то вроде serviceInstaller = serviceInstaller1; где serviceInstaller1 является идентификатором от дизайнера. Выполнение этого в OnBeforeInstall сделало вышеприведенную работу безупречно для меня. Я не пробовал, но вы можете сделать это и в вызове ServiceInstaller(). –

0

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

+0

Я не хочу этого делать. Я хочу сделать это за один раз из командной строки или из классов Windows Service. – mickyjtwin

+0

Извините, мой плохой, я пропустил тот момент, когда вы явно исключили возможность запуска его через панель управления. –

5

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

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

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

net start *servicename* 
2

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

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

+6

Почему «sc» является «более правильным» способом? Что случилось с «net start» (и командным командлетом стартового сервиса PSH)? – Richard

+1

Потому что sc можно вызвать с удаленной машины, поэтому он всегда работает. – MacGyver

0

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

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

4

алгоритмической опции для управления услугами:

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

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

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(); 
    } 
} 
} 
+1

Этот код дал мне следующие ошибки: Исключение произошло на этапе установки. System.InvalidOperationException: Исключение произошло в обработчике событий OnAfterInstall System.ServiceProcess.ServiceInstaller. Внутреннее исключение. Исключение System.InvalidOperationException было вызвано следующим сообщением об ошибке: Не удается запустить service serviceName на компьютере. '.. Внутреннее исключение. Исключение System.ComponentModel.Win32Exception было отправлено со следующим сообщением об ошибке: исполняемая программа, настроенный для запуска, не реализует службу. – goamn

+1

Ошибки изъяты после того, как я прокомментировал строку «InitializeComponent()». Я считаю, что эта строка дублирует все другие строки, поскольку журналы, похоже, показывают две идентичные вещи, происходящие вместе перед ошибкой: Установка сервисного сервисаName ... Служба serviceName успешно установлена. Создание источника EventLog sourceName в журнале Application ... Установка службы serviceName ... Создание источника службы EventLogName в журнале Application ... Исключение произошло в обработчике событий OnAfterInstall System.ServiceProcess.ServiceInstaller. – goamn

+0

Вы действительно спасли мой день :) Спасибо за этот полезный комментарий. После того как я прокомментировал вызов InitializeComponent(), моя служба также начала отлично – Konstantin

0

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

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

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

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

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

Смежные вопросы