Automatycznie uruchom usługę Windows podczas instalacji


119

Mam usługę Windows, którą instaluję przy użyciu programu InstallUtil.exe. Mimo że ustawiłem metodę uruchamiania na Automatyczną, usługa nie uruchamia się po zainstalowaniu, muszę ręcznie otworzyć usługi i kliknąć przycisk Start. Czy istnieje sposób, aby go uruchomić za pomocą wiersza poleceń lub kodu usługi?

Odpowiedzi:


218

W klasie Installer dodaj procedurę obsługi dla zdarzenia AfterInstall. Następnie możesz wywołać ServiceController w programie obsługi zdarzeń, aby uruchomić usługę.

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

Teraz, gdy uruchomisz InstallUtil na swoim instalatorze, zainstaluje on, a następnie uruchomi usługę automatycznie.


40
(komentarz z proponowanej edycji): Lepiej jest używać serviceInstaller.ServiceName, jeśli nazwa usługi zostanie zmieniona, użyje poprawnej nazwy bez konieczności zmiany jej w kodzie.
Marc Gravell

1
Nie zaszkodziłoby również zawinąć ServiceControllerw instrukcję using.
ChrisO

3
Jak otrzymujesz serviceInstaller?
Philip Rego

1
serviceInstaller powinien być ServiceInstallerzmienną w Twojej klasie. Taka klasa będzie realizować System.Configuration.Install.Installer. Więcej informacji znajdziesz w tym przewodniku po msdn .
Sergio Basurco

4
@PhilipRego Przypuszczalnie serviceInstallerjest to ServiceInstallerobiekt, do którego odwołuje się senderprogram obsługi zdarzeń, którego instancja jest zwykle tworzona w ServiceInstaller()konstruktorze. Dlatego możesz dodać ServiceInstaller serviceInstaller = (ServiceInstaller)sender;przed usingstwierdzeniem.
khargoosh

28

Po krótkiej refaktoryzacji, oto przykład kompletnego instalatora usługi Windows z automatycznym startem:

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
Ten kod dał mi następujący błąd / y: Wystąpił wyjątek podczas fazy instalacji. System.InvalidOperationException: wystąpił wyjątek w procedurze obsługi zdarzeń OnAfterInstall systemu System.ServiceProcess.ServiceInstaller. Wyjątek wewnętrzny System.InvalidOperationException został zgłoszony z następującym komunikatem o błędzie: Nie można uruchomić usługi nazwa_usługi na komputerze „.” .. Wyjątek wewnętrzny System.ComponentModel.Win32Exception został zgłoszony z następującym komunikatem o błędzie: Program wykonywalny, do którego skonfigurowano tę usługę run in nie implementuje usługi.
goamn

2
Błędy zajęły się po zakomentowaniu linii „InitializeComponent ()”. Uważam, że ten wiersz powiela wszystkie inne wiersze, ponieważ dzienniki wydają się pokazywać dwie identyczne rzeczy, które dzieją się razem przed wystąpieniem błędu: Instalowanie usługi nazwa_usługi… Usługa nazwa_usługi została pomyślnie zainstalowana. Tworzenie źródła EventLog nazwa_usługi w dzienniku Aplikacja ... Instalowanie usługi nazwa_usługi ... Tworzenie źródła EventLog nazwa_usługi w dzienniku Aplikacja ... Wystąpił wyjątek w procedurze obsługi zdarzenia OnAfterInstall System.ServiceProcess.ServiceInstaller.
goamn

Naprawdę uratowałeś mi dzień :) Dziękuję za przydatny komentarz. Po wykomentowaniu wywołania InitializeComponent () moja usługa również zaczęła się idealnie
Konstantin

7

A co z wykonywaniem poleceń?

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

Chłodny. Napisałem to w swoim pliku wsadowym instalacji zaraz po zakończeniu instalacji.
M. Fawad Surosh

5

Programowe opcje kontrolowania usług:

  • Można użyć kodu natywnego „Uruchamianie usługi” . Maksymalna kontrola przy minimalnych zależnościach, ale najwięcej pracy.
  • WMI: Win32_Service ma StartServicemetodę. Jest to dobre w przypadkach, w których musisz mieć możliwość wykonania innego przetwarzania (np. W celu wybrania usługi).
  • PowerShell: wykonaj Start-Serviceprzez RunspaceInvokelub tworząc własne Runspacei używając jego CreatePipelinemetody do wykonania. Jest to dobre w przypadkach, w których musisz mieć możliwość wykonania innego przetwarzania (np. Aby wybrać usługę) z dużo łatwiejszym modelem kodowania niż WMI, ale zależy to od zainstalowanego PSH.
  • Aplikacja .NET może używać ServiceController

4

Aby uruchomić usługę, możesz użyć następującego wiersza poleceń:

net start *servicename*

2

Użyj ServiceController, aby uruchomić usługę z kodu.

Aktualizacja: I bardziej poprawnym sposobem uruchamiania usługi z wiersza poleceń jest użycie polecenia „sc” ( Kontroler usług ) zamiast „net”.


6
Dlaczego „sc” jest „bardziej poprawnym” sposobem? Co jest nie tak z "net start" (i cmdletem start-service PSH)?
Richard

1
Ponieważ sc można wywołać ze zdalnej maszyny, więc zawsze działa.
MacGyver

1

Mimo że dokładnie zastosowałem się do zaakceptowanej odpowiedzi, nadal nie byłem w stanie uruchomić usługi - zamiast tego otrzymałem komunikat o błędzie podczas instalacji z informacją, że usługa, która została właśnie zainstalowana, nie może zostać uruchomiona, ponieważ nie istniała, pomimo użycia this.serviceInstaller.ServiceNameraczej niż dosłowne ...

W końcu znalazłem alternatywne rozwiązanie, które wykorzystuje wiersz poleceń:

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

Automatyczne uruchamianie oznacza, że ​​usługa jest uruchamiana automatycznie podczas uruchamiania systemu Windows. Jak wspominali inni, aby uruchomić go z konsoli, należy użyć ServiceController.


Nie chcę tego robić. Chcę to zrobić za jednym razem z wiersza poleceń lub z poziomu klas usługi Windows.
mickyjtwin

Przepraszam, moja wina, przegapiłem punkt, w którym wyraźnie wykluczyłeś możliwość uruchomienia go z panelu sterowania.
Michael Klement,

0

Możesz użyć GetServicesmetody klasy ServiceController, aby uzyskać tablicę wszystkich usług. Następnie znajdź swoją usługę, sprawdzając ServiceNamewłaściwość każdej usługi. Po znalezieniu usługi wywołaj Startmetodę, aby ją uruchomić.

Powinieneś również sprawdzić Statuswłaściwość, aby zobaczyć, w jakim stanie jest już przed wywołaniem startu (może być uruchomiona, wstrzymana, zatrzymana itp.).


0

Zepsułeś swojego projektanta. Ponownie dodaj składnik instalatora. Powinien mieć serviceInstaller i serviceProcessInstaller. ServiceInstaller z właściwością Startup Method ustawioną na Automatic będzie uruchamiana po zainstalowaniu i po każdym ponownym uruchomieniu.


0

Uwaga: usługa mogła zostać skonfigurowana inaczej przy użyciu interfejsu formularzy w celu dodania instalatora usługi i instalatora projektu. W takim przypadku zamień miejsce, w którym jest napisane serviceInstaller.ServiceName, na „nazwa od projektanta” .ServiceName.

W tym przypadku nie potrzebujesz również prywatnych członków.

Dzięki za pomoc.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.