Tự động khởi động Dịch vụ Windows khi cài đặt


119

Tôi có một Dịch vụ Windows mà tôi cài đặt bằng InstallUtil.exe. Mặc dù tôi đã đặt Phương thức khởi động thành Tự động, dịch vụ không khởi động khi được cài đặt, tôi phải mở dịch vụ theo cách thủ công và nhấp vào bắt đầu. Có cách nào để khởi động nó qua dòng lệnh hoặc thông qua mã của Dịch vụ không?

Câu trả lời:


218

Trong lớp Trình cài đặt của bạn, hãy thêm một trình xử lý cho sự kiện AfterInstall. Sau đó, bạn có thể gọi ServiceController trong trình xử lý sự kiện để bắt đầu dịch vụ.

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

Bây giờ khi bạn chạy InstallUtil trên trình cài đặt của mình, nó sẽ cài đặt và sau đó tự động khởi động dịch vụ.


40
(nhận xét từ một chỉnh sửa được đề xuất): Tốt hơn nên sử dụng serviceInstaller.ServiceName, nếu tên dịch vụ được thay đổi, nó sẽ sử dụng tên chính xác mà không cần thay đổi trong mã.
Marc Gravell

1
Nó cũng không có hại gì để bao gồm ServiceControllermột câu lệnh sử dụng.
ChrisO

3
Bạn nhận được serviceInstaller như thế nào?
Philip Rego

1
serviceInstaller được cho là ServiceInstallerbiến trong lớp của bạn. Lớp như vậy sẽ thực hiện System.Configuration.Install.Installer. Xem hướng dẫn msdn này để biết thêm thông tin.
Sergio Basurco

4
@PhilipRego Có lẽ serviceInstallerServiceInstallerđối tượng được tham chiếu đến sendertrong trình xử lý sự kiện, thường được khởi tạo trong phương thức ServiceInstaller()khởi tạo. Do đó bạn có thể thêm vào ServiceInstaller serviceInstaller = (ServiceInstaller)sender;trước usingcâu lệnh.
khargoosh

28

Sau khi cấu trúc lại một chút, đây là ví dụ về trình cài đặt dịch vụ windows hoàn chỉnh với khởi động tự động:

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
Mã này đã cho tôi các lỗi sau: Đã xảy ra ngoại lệ trong giai đoạn Cài đặt. System.InvalidOperationException: Một ngoại lệ xảy ra trong trình xử lý sự kiện OnAfterInstall của System.ServiceProcess.ServiceInstaller. Ngoại lệ bên trong System.InvalidOperationException được ném với thông báo lỗi sau: Không thể khởi động dịch vụ serviceName trên máy tính '.' .. Ngoại lệ bên trong System.ComponentModel.Win32Exception được ném với thông báo lỗi sau: Chương trình thực thi mà dịch vụ này được định cấu hình chạy vào không thực hiện dịch vụ.
goamn

2
Các lỗi đã xảy ra khi tôi nhận xét ra dòng "InitializeComponent ()". Tôi tin rằng dòng này đang trùng lặp tất cả các dòng khác vì các bản ghi dường như hiển thị hai điều giống hệt nhau xảy ra cùng nhau trước khi xảy ra lỗi: Cài đặt serviceName ... Service serviceName đã được cài đặt thành công. Tạo dịch vụ nguồn EventLog Tên trong nhật ký Ứng dụng ... Cài đặt dịch vụ dịch vụ Tên ... Tạo dịch vụ nguồn EventLog Tên trong nhật ký Ứng dụng ... Đã xảy ra ngoại lệ trong trình xử lý sự kiện OnAfterInstall của System.ServiceProcess.ServiceInstaller.
goamn

Bạn thực sự đã cứu ngày của tôi :) Cảm ơn bạn vì nhận xét hữu ích này. Sau khi tôi nhận xét về cuộc gọi InitializeComponent (), dịch vụ của tôi cũng bắt đầu hoàn hảo
Konstantin

7

Làm thế nào về các lệnh sau?

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

Mát mẻ. Tôi đã viết điều này trong tệp lô cài đặt của mình ngay sau khi cài đặt xong.
M. Fawad Surosh

5

Các tùy chọn lập trình để kiểm soát các dịch vụ:

  • Có thể sử dụng mã gốc, "Bắt đầu Dịch vụ" . Kiểm soát tối đa với sự phụ thuộc tối thiểu nhưng hiệu quả nhất.
  • WMI: Win32_Service có một StartServicephương thức. Điều này tốt cho những trường hợp bạn cần có thể thực hiện các xử lý khác (ví dụ: chọn dịch vụ nào).
  • PowerShell: thực thi Start-Servicethông qua RunspaceInvokehoặc bằng cách tạo của riêng bạn Runspacevà sử dụng CreatePipelinephương thức của nó để thực thi. Điều này tốt cho các trường hợp bạn cần có thể thực hiện các xử lý khác (ví dụ: chọn dịch vụ) với mô hình mã hóa dễ dàng hơn nhiều so với WMI, nhưng phụ thuộc vào PSH được cài đặt.
  • Một ứng dụng .NET có thể sử dụng ServiceController

4

Bạn có thể sử dụng dòng lệnh sau để bắt đầu dịch vụ:

net start *servicename*

2

Sử dụng ServiceController để bắt đầu dịch vụ của bạn từ mã.

Cập nhật: Và cách chính xác hơn để bắt đầu dịch vụ từ dòng lệnh là sử dụng lệnh "sc" ( Service Controller ) thay vì "net".


6
Tại sao "sc" là một cách "đúng hơn"? Có gì sai với "net start" (và lệnh ghép ngắn PSH bắt đầu dịch vụ)?
Richard

1
Bởi vì sc có thể được gọi từ một máy từ xa, vì vậy nó luôn hoạt động.
MacGyver

1

Mặc dù sau câu trả lời được chấp nhận một cách chính xác, tôi vẫn không thể nhận được dịch vụ để start-- tôi đã thay cho một thông báo lỗi trong khi cài đặt nói rằng các dịch vụ vừa được cài đặt không thể bắt đầu, vì nó không tồn tại, mặc dù sử dụng this.serviceInstaller.ServiceNamekhá hơn một nghĩa đen ...

Cuối cùng tôi đã tìm thấy một giải pháp thay thế sử dụng dòng lệnh:

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

Khởi động tự động có nghĩa là dịch vụ được tự động khởi động khi Windows khởi động. Như những người khác đã đề cập, để khởi động nó từ bảng điều khiển, bạn nên sử dụng ServiceController.


Tôi không muốn làm điều này. Tôi đang tìm cách thực hiện việc này bằng một lần từ dòng lệnh hoặc từ bên trong các lớp Dịch vụ của Windows.
mickyjtwin

Xin lỗi, tôi không thành công, tôi đã bỏ lỡ điểm mà bạn đã loại trừ rõ ràng khả năng khởi động nó qua bảng điều khiển.
Michael Klement

0

Bạn có thể sử dụng GetServicesphương thức của lớp ServiceController để lấy một mảng tất cả các dịch vụ. Sau đó, tìm dịch vụ của bạn bằng cách kiểm tra thuộc ServiceNametính của từng dịch vụ. Khi bạn đã tìm thấy dịch vụ của mình, hãy gọi Startphương thức để bắt đầu nó.

Bạn cũng nên kiểm tra thuộc Statustính để xem nó đã ở trạng thái nào trước khi bắt đầu gọi (nó có thể đang chạy, tạm dừng, đã dừng, v.v.).


0

Bạn đã làm hỏng nhà thiết kế của mình. Thêm lại thành phần trình cài đặt của bạn. Nó phải có một serviceInstaller và một serviceProcessInstaller. ServiceInstaller với thuộc tính Phương pháp Khởi động được đặt thành Tự động sẽ khởi động khi được cài đặt và sau mỗi lần khởi động lại.


0

Chỉ cần lưu ý: Bạn có thể đã thiết lập dịch vụ của mình theo cách khác bằng cách sử dụng giao diện biểu mẫu để thêm trình cài đặt dịch vụ và trình cài đặt dự án. Trong trường hợp đó, hãy thay thế nơi có nội dung serviceInstaller.ServiceName bằng "tên từ nhà thiết kế" .ServiceName.

Bạn cũng không cần các thành viên riêng trong trường hợp này.

Cảm ơn đã giúp đỡ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.