Secara otomatis memulai Layanan Windows saat menginstal

119

Saya memiliki Layanan Windows yang saya instal menggunakan InstallUtil.exe. Meskipun saya telah mengatur Metode Startup ke Otomatis, layanan tidak dimulai saat diinstal, saya harus membuka layanan secara manual dan mengklik mulai. Apakah ada cara untuk memulainya baik melalui baris perintah, atau melalui kode Layanan?

mickyjtwin
sumber

Jawaban:

218

Di kelas Installer Anda, tambahkan handler untuk event AfterInstall. Anda kemudian dapat memanggil ServiceController di event handler untuk memulai layanan.

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

Sekarang ketika Anda menjalankan InstallUtil pada penginstal Anda, itu akan menginstal dan kemudian memulai layanan secara otomatis.

codemonkey
sumber
40
(komentar dari pengeditan yang diusulkan): Lebih baik menggunakan serviceInstaller.ServiceName, jika nama layanan diubah maka akan menggunakan nama yang benar tanpa perlu mengubahnya di kode.
Marc Gravell
1
Juga tidak ada ruginya untuk membungkus ServiceControllerdalam menggunakan pernyataan.
ChrisO
3
Bagaimana Anda mendapatkan serviceInstaller?
Philip Rego
1
serviceInstaller seharusnya menjadi ServiceInstallervariabel di kelas Anda. Kelas tersebut harus menerapkan System.Configuration.Install.Installer. Lihat panduan msdn ini untuk informasi lebih lanjut.
Sergio Basurco
4
@PhilipRego Agaknya serviceInstalleradalah ServiceInstallerobjek yang dirujuk oleh senderdalam event handler, yang biasanya dipakai dalam ServiceInstaller()konstruktor. Oleh karena itu Anda dapat menambahkan ServiceInstaller serviceInstaller = (ServiceInstaller)sender;sebelum usingpernyataan tersebut.
khargoosh
28

Setelah sedikit refactoring, ini adalah contoh penginstal layanan windows lengkap dengan start otomatis:

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
sumber
2
Kode ini memberi saya kesalahan berikut: Pengecualian terjadi selama fase Instal. System.InvalidOperationException: Pengecualian terjadi di event handler OnAfterInstall System.ServiceProcess.ServiceInstaller. Pengecualian dalam System.InvalidOperationException dilemparkan dengan pesan galat berikut: Tidak dapat memulai layanan serviceName di komputer '.' .. Pengecualian dalam System.ComponentModel.Win32Exception dilemparkan dengan pesan galat berikut: Program yang dapat dijalankan yang dikonfigurasi untuk layanan ini dijalankan tidak mengimplementasikan layanan.
goamn
2
Kesalahan disita setelah saya mengomentari baris "InitializeComponent ()". Saya yakin baris ini menduplikasi semua baris lain karena log tampaknya menunjukkan dua hal identik yang terjadi bersamaan sebelum kesalahan: Menginstal service serviceName ... Service serviceName telah berhasil diinstal. Membuat EventLog source serviceName di log Application ... Menginstal service serviceName ... Membuat serviceName sumber EventLog di log Aplikasi ... Pengecualian terjadi di event handler OnAfterInstall System.ServiceProcess.ServiceInstaller.
goamn
Anda benar-benar menyelamatkan hari saya :) Terima kasih atas komentar yang berguna ini. Setelah saya mengomentari panggilan InitializeComponent (), layanan saya juga dimulai dengan sempurna
Konstantin
7

Bagaimana jika mengikuti perintah?

net start "<service name>"
net stop "<service name>"
Hemant
sumber
Keren. Saya menulis ini di file batch instalasi saya tepat setelah instalasi selesai.
M. Fawad Surosh
5

Opsi terprogram untuk mengontrol layanan:

  • Kode asli dapat digunakan, "Memulai Layanan" . Kontrol maksimum dengan dependensi minimum tetapi sebagian besar berfungsi.
  • WMI: Win32_Service memiliki StartServicemetode. Ini bagus untuk kasus di mana Anda harus dapat melakukan pemrosesan lain (mis. Untuk memilih layanan mana).
  • PowerShell: jalankan Start-Servicemelalui RunspaceInvokeatau dengan membuat milik Anda sendiri Runspacedan menggunakan CreatePipelinemetodenya untuk mengeksekusi. Ini bagus untuk kasus di mana Anda perlu melakukan pemrosesan lain (misalnya untuk memilih layanan mana) dengan model pengkodean yang jauh lebih mudah daripada WMI, tetapi bergantung pada PSH yang diinstal.
  • Aplikasi .NET dapat digunakan ServiceController
Richard
sumber
4

Anda dapat menggunakan baris perintah berikut untuk memulai layanan:

net start *servicename*
AlexDrenea
sumber
2

Gunakan ServiceController untuk memulai layanan Anda dari kode.

Memperbarui: Dan cara yang lebih benar untuk memulai layanan dari baris perintah adalah dengan menggunakan perintah "sc" ( Service Controller ) daripada "net".

wasit
sumber
6
Mengapa "sc" merupakan cara yang "lebih tepat"? Apa yang salah dengan "net start" (dan cmdlet PSH start-service)?
Richard
1
Karena sc dapat dipanggil dari mesin jarak jauh, sehingga selalu berfungsi.
MacGyver
1

Meskipun mengikuti jawaban yang diterima dengan tepat, saya masih tidak dapat memulai layanan - Saya malah diberi pesan kegagalan selama instalasi yang menyatakan bahwa layanan yang baru saja diinstal tidak dapat dimulai, karena tidak ada, meskipun menggunakan this.serviceInstaller.ServiceNameagak daripada literal ...

Saya akhirnya menemukan solusi alternatif yang menggunakan baris perintah:

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.
sumber
0

Startup otomatis berarti bahwa layanan dimulai secara otomatis saat Windows dimulai. Seperti yang telah disebutkan orang lain, untuk memulainya dari konsol, Anda harus menggunakan ServiceController.

Michael Klement
sumber
Saya tidak ingin melakukan ini. Saya ingin melakukan ini sekaligus dari baris perintah, atau dari dalam kelas Layanan Windows.
mickyjtwin
Maaf, saya salah, saya melewatkan titik di mana Anda secara eksplisit mengecualikan kemungkinan memulainya melalui panel kontrol.
Michael Klement
0

Anda bisa menggunakan GetServicesmetode kelas ServiceController untuk mendapatkan larik dari semua layanan. Kemudian, temukan layanan Anda dengan memeriksa ServiceNameproperti masing-masing layanan. Ketika Anda telah menemukan layanan Anda, panggil Startmetode untuk memulainya.

Anda juga harus memeriksa Statusproperti untuk melihat keadaannya sebelum memanggil start (mungkin berjalan, dihentikan sementara, dihentikan, dll ..).

adrianbanks
sumber
0

Anda merusak desainer Anda. Tambahkan kembali Komponen Penginstal Anda. Ini harus memiliki serviceInstaller dan serviceProcessInstaller. ServiceInstaller dengan properti Metode Startup disetel ke Otomatis akan mulai saat diinstal dan setelah setiap boot ulang.

Guillaume Massé
sumber
0

Sekadar catatan: Anda mungkin telah menyiapkan layanan Anda secara berbeda menggunakan antarmuka formulir untuk menambahkan penginstal layanan dan penginstal proyek. Dalam hal ini, ganti di mana dikatakan serviceInstaller.ServiceName dengan "nama dari desainer" .ServiceName.

Anda juga tidak membutuhkan anggota pribadi dalam kasus ini.

Terima kasih untuk bantuannya.

IanUniacke
sumber