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?

mickyjtwin
źródło

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.

codemonkey
źródło
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();
    }
}
}
Pedro Pereira
źródło
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>"
Hemant
źródło
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
Richard
źródło
4

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

net start *servicename*
AlexDrenea
źródło
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”.

arbiter
źródło
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();
    }
Matsu Q.
źródło
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.

Michael Klement
źródło
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.).

adrianbanks
źródło
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.

Guillaume Massé
źródło
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.

IanUniacke
źródło