เริ่มบริการ Windows โดยอัตโนมัติเมื่อติดตั้ง


119

ฉันมีบริการ Windows ซึ่งฉันติดตั้งโดยใช้ InstallUtil.exe แม้ว่าฉันจะตั้งค่าวิธีการเริ่มต้นเป็นอัตโนมัติ แต่บริการไม่เริ่มทำงานเมื่อติดตั้งฉันต้องเปิดบริการด้วยตนเองและคลิกเริ่ม มีวิธีเริ่มต้นผ่านทางบรรทัดคำสั่งหรือผ่านรหัสของบริการหรือไม่?

คำตอบ:


219

ในคลาส Installer ของคุณให้เพิ่มตัวจัดการสำหรับเหตุการณ์ AfterInstall จากนั้นคุณสามารถเรียก ServiceController ในตัวจัดการเหตุการณ์เพื่อเริ่มบริการ

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

ตอนนี้เมื่อคุณเรียกใช้ InstallUtil บนโปรแกรมติดตั้งของคุณโปรแกรมจะติดตั้งจากนั้นเริ่มบริการโดยอัตโนมัติ


40
(ความคิดเห็นจากการแก้ไขที่เสนอ): ควรใช้ serviceInstaller.ServiceName ดีกว่าถ้าชื่อบริการได้รับการเปลี่ยนแปลงจะใช้ชื่อที่ถูกต้องโดยไม่จำเป็นต้องเปลี่ยนในรหัส
Marc Gravell

1
นอกจากนี้ยังไม่เจ็บที่จะห่อServiceControllerในคำสั่งใช้
ChrisO

3
คุณได้รับ serviceInstaller อย่างไร?
Philip Rego

1
serviceInstaller ควรเป็นServiceInstallerตัวแปรในคลาสของคุณ System.Configuration.Install.Installerระดับดังกล่าวจะดำเนินการ ดูคู่มือ msdnนี้สำหรับข้อมูลเพิ่มเติม
Sergio Basurco

4
@PhilipRego สันนิษฐานว่าserviceInstallerเป็นServiceInstallerวัตถุที่อ้างถึงโดยsenderในตัวจัดการเหตุการณ์ซึ่งโดยปกติจะสร้างอินสแตนซ์ในตัวServiceInstaller()สร้าง ดังนั้นคุณอาจเพิ่มServiceInstaller serviceInstaller = (ServiceInstaller)sender;ก่อนusingคำสั่ง
khargoosh

28

หลังจากปรับโครงสร้างใหม่เล็กน้อยนี่คือตัวอย่างของโปรแกรมติดตั้งบริการ windows ที่สมบูรณ์พร้อมการเริ่มอัตโนมัติ

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
รหัสนี้ทำให้ฉันมีข้อผิดพลาดต่อไปนี้: มีข้อยกเว้นเกิดขึ้นระหว่างขั้นตอนการติดตั้ง System.InvalidOperationException: มีข้อยกเว้นเกิดขึ้นในตัวจัดการเหตุการณ์ OnAfterInstall ของ System.ServiceProcess.ServiceInstaller ข้อยกเว้นภายใน System.InvalidOperationException ถูกโยนทิ้งพร้อมกับข้อความแสดงข้อผิดพลาดต่อไปนี้: ไม่สามารถเริ่มบริการ serviceName บนคอมพิวเตอร์ '.' .. ข้อยกเว้นภายใน System.ComponentModel.Win32Exception ถูกส่งมาพร้อมกับข้อความแสดงข้อผิดพลาดต่อไปนี้: โปรแกรมปฏิบัติการที่บริการนี้ถูกกำหนดค่าให้ เรียกใช้ไม่ได้ใช้บริการ
goamn

2
ข้อผิดพลาดเกิดขึ้นเมื่อฉันแสดงความคิดเห็นในบรรทัด "InitializeComponent ()" ฉันเชื่อว่าบรรทัดนี้กำลังทำซ้ำบรรทัดอื่น ๆ ทั้งหมดเนื่องจากบันทึกดูเหมือนจะแสดงสิ่งที่เหมือนกันสองอย่างที่เกิดขึ้นพร้อมกันก่อนเกิดข้อผิดพลาด: การติดตั้ง service serviceName ... Service serviceName ได้รับการติดตั้งสำเร็จแล้ว การสร้าง EventLog ซอร์ส serviceName ในบันทึกแอ็พพลิเคชัน ... การติดตั้ง serviceName ... การสร้าง EventLog ซอร์ส serviceName ในแอปพลิเคชันบันทึก ... มีข้อยกเว้นเกิดขึ้นในตัวจัดการเหตุการณ์ OnAfterInstall ของ System.ServiceProcess.ServiceInstaller
goamn

คุณช่วยวันของฉันไว้จริงๆ :) ขอบคุณสำหรับความคิดเห็นที่เป็นประโยชน์นี้ หลังจากที่ฉันแสดงความคิดเห็นในการโทร InitializeComponent () แล้วบริการของฉันก็เริ่มต้นอย่างสมบูรณ์แบบเช่นกัน
Konstantin

7

แล้วทำตามคำสั่งล่ะ

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

เย็น. ฉันเขียนสิ่งนี้ในไฟล์แบตช์การติดตั้งของฉันทันทีหลังจากการติดตั้งเสร็จสิ้น
M. Fawad Surosh

5

ตัวเลือกแบบเป็นโปรแกรมสำหรับการควบคุมบริการ:

  • รหัสพื้นเมืองสามารถใช้"เริ่มต้นการให้บริการ" การควบคุมสูงสุดด้วยการอ้างอิงขั้นต่ำ แต่ทำงานได้มากที่สุด
  • WMI: Win32_ServiceมีStartServiceวิธีการ เหมาะสำหรับกรณีที่คุณต้องสามารถดำเนินการอื่น ๆ ได้ (เช่นเพื่อเลือกบริการใด)
  • PowerShell: ดำเนินการStart-Serviceผ่านRunspaceInvokeหรือโดยการสร้างของคุณเองRunspaceและใช้CreatePipelineวิธีการดำเนินการ นี่เป็นสิ่งที่ดีสำหรับกรณีที่คุณต้องสามารถดำเนินการประมวลผลอื่น ๆ (เช่นเพื่อเลือกบริการใด) ด้วยรูปแบบการเข้ารหัสที่ง่ายกว่า WMI มาก แต่ขึ้นอยู่กับ PSH ที่ติดตั้ง
  • แอปพลิเคชัน. NET สามารถใช้งานได้ ServiceController

4

คุณสามารถใช้บรรทัดคำสั่งต่อไปนี้เพื่อเริ่มบริการ:

net start *servicename*

2

ใช้ServiceControllerเพื่อเริ่มบริการของคุณจากรหัส

อัปเดต:และวิธีที่ถูกต้องในการเริ่มบริการจากบรรทัดคำสั่งคือใช้คำสั่ง "sc" ( Service Controller ) แทน "net"


6
เหตุใด "sc" จึงเป็นวิธีที่ "ถูกต้องกว่า" "net start" (และ cmdlet PSH start-service) มีอะไรผิดปกติ
Richard

1
เนื่องจากสามารถเรียก sc จากเครื่องระยะไกลได้จึงทำงานได้เสมอ
MacGyver

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

การเริ่มต้นอัตโนมัติหมายความว่าบริการจะเริ่มโดยอัตโนมัติเมื่อ Windows เริ่มทำงาน ดังที่คนอื่น ๆ กล่าวถึงในการเริ่มต้นจากคอนโซลคุณควรใช้ ServiceController


ฉันไม่ต้องการที่จะทำเช่นนี้ ฉันต้องการทำสิ่งนี้ในครั้งเดียวจากบรรทัดคำสั่งหรือจากภายในคลาส Windows Service
mickyjtwin

ขออภัยฉันไม่ดีฉันพลาดจุดที่คุณยกเว้นความเป็นไปได้ในการเริ่มต้นบนแผงควบคุมอย่างชัดเจน
Michael Klement

0

คุณสามารถใช้GetServicesเมธอดของ คลาสServiceControllerเพื่อรับอาร์เรย์ของบริการทั้งหมด จากนั้นค้นหาบริการของคุณโดยตรวจสอบServiceNameคุณสมบัติของแต่ละบริการ เมื่อคุณพบบริการของคุณแล้วให้โทรหาStartวิธีการเพื่อเริ่มใช้งาน

นอกจากนี้คุณควรตรวจสอบStatusคุณสมบัติเพื่อดูว่ามีอยู่ในสถานะใดแล้วก่อนที่จะเริ่มการโทร (อาจกำลังทำงานหยุดชั่วคราวหยุดทำงาน ฯลฯ .. )


0

คุณทำให้นักออกแบบของคุณเสียหาย เพิ่มส่วนประกอบตัวติดตั้งของคุณอีกครั้ง ควรมี serviceInstaller และ serviceProcessInstaller serviceInstaller พร้อมคุณสมบัติ Startup Method ที่ตั้งค่าเป็น Automatic จะเริ่มทำงานเมื่อติดตั้งและหลังจากรีบูตแต่ละครั้ง


0

หมายเหตุ: คุณอาจตั้งค่าบริการของคุณแตกต่างกันโดยใช้อินเทอร์เฟซแบบฟอร์มเพื่อเพิ่มตัวติดตั้งบริการและตัวติดตั้งโครงการ ในกรณีนั้นให้แทนที่ตำแหน่งที่ระบุว่า serviceInstaller.ServiceName ด้วย "name from designer ".ServiceName

คุณไม่จำเป็นต้องมีสมาชิกส่วนตัวในกรณีนี้

ขอบคุณสำหรับความช่วยเหลือ


0

นี่คือขั้นตอนและรหัสที่ใช้สร้างProjectInstallerใน Visual Studio:

  1. สร้างโครงการWindows Serviceใน Visual Studio
  2. สร้างโปรแกรมติดตั้งไปยังบริการ
  3. เปิดProjectInstallerในตัวแก้ไขการออกแบบ (ควรเปิดโดยอัตโนมัติเมื่อสร้างตัวติดตั้ง) และตั้งค่าคุณสมบัติของการสร้างserviceProcessInstaller1(เช่นบัญชี: LocalSystem) และserviceInstaller1(เช่น StartType: Automatic)
  4. เปิดProjectInstallerในตัวแก้ไขโค้ด (กดF7ในตัวแก้ไขการออกแบบ) และเพิ่มตัวจัดการเหตุการณ์ServiceInstaller.AfterInstall- ดูรหัสต่อไปนี้ จะเริ่มให้บริการหลังจากการติดตั้ง

คลาส ProjectInstaller:

using System.ServiceProcess;


[RunInstaller(true)]
public partial class ProjectInstaller : System.Configuration.Install.Installer
{
    public ProjectInstaller()
    {
        InitializeComponent(); //generated code including property settings from previous steps
        this.serviceInstaller1.AfterInstall += Autorun_AfterServiceInstall; //use your ServiceInstaller name if changed from serviceInstaller1
    }

    void Autorun_AfterServiceInstall(object sender, InstallEventArgs e)
    {
        ServiceInstaller serviceInstaller = (ServiceInstaller)sender;
        using (ServiceController sc = new ServiceController(serviceInstaller.ServiceName))
        {
            sc.Start();
        }
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.