ฉันมีบริการ Windows ซึ่งฉันติดตั้งโดยใช้ InstallUtil.exe แม้ว่าฉันจะตั้งค่าวิธีการเริ่มต้นเป็นอัตโนมัติ แต่บริการไม่เริ่มทำงานเมื่อติดตั้งฉันต้องเปิดบริการด้วยตนเองและคลิกเริ่ม มีวิธีเริ่มต้นผ่านทางบรรทัดคำสั่งหรือผ่านรหัสของบริการหรือไม่?
ฉันมีบริการ Windows ซึ่งฉันติดตั้งโดยใช้ InstallUtil.exe แม้ว่าฉันจะตั้งค่าวิธีการเริ่มต้นเป็นอัตโนมัติ แต่บริการไม่เริ่มทำงานเมื่อติดตั้งฉันต้องเปิดบริการด้วยตนเองและคลิกเริ่ม มีวิธีเริ่มต้นผ่านทางบรรทัดคำสั่งหรือผ่านรหัสของบริการหรือไม่?
คำตอบ:
ในคลาส 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 บนโปรแกรมติดตั้งของคุณโปรแกรมจะติดตั้งจากนั้นเริ่มบริการโดยอัตโนมัติ
ServiceController
ในคำสั่งใช้
ServiceInstaller
ตัวแปรในคลาสของคุณ System.Configuration.Install.Installer
ระดับดังกล่าวจะดำเนินการ ดูคู่มือ msdnนี้สำหรับข้อมูลเพิ่มเติม
serviceInstaller
เป็นServiceInstaller
วัตถุที่อ้างถึงโดยsender
ในตัวจัดการเหตุการณ์ซึ่งโดยปกติจะสร้างอินสแตนซ์ในตัวServiceInstaller()
สร้าง ดังนั้นคุณอาจเพิ่มServiceInstaller serviceInstaller = (ServiceInstaller)sender;
ก่อนusing
คำสั่ง
หลังจากปรับโครงสร้างใหม่เล็กน้อยนี่คือตัวอย่างของโปรแกรมติดตั้งบริการ 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();
}
}
}
แล้วทำตามคำสั่งล่ะ
net start "<service name>"
net stop "<service name>"
ตัวเลือกแบบเป็นโปรแกรมสำหรับการควบคุมบริการ:
StartService
วิธีการ เหมาะสำหรับกรณีที่คุณต้องสามารถดำเนินการอื่น ๆ ได้ (เช่นเพื่อเลือกบริการใด)Start-Service
ผ่านRunspaceInvoke
หรือโดยการสร้างของคุณเองRunspace
และใช้CreatePipeline
วิธีการดำเนินการ นี่เป็นสิ่งที่ดีสำหรับกรณีที่คุณต้องสามารถดำเนินการประมวลผลอื่น ๆ (เช่นเพื่อเลือกบริการใด) ด้วยรูปแบบการเข้ารหัสที่ง่ายกว่า WMI มาก แต่ขึ้นอยู่กับ PSH ที่ติดตั้งServiceController
คุณสามารถใช้บรรทัดคำสั่งต่อไปนี้เพื่อเริ่มบริการ:
net start *servicename*
ใช้ServiceControllerเพื่อเริ่มบริการของคุณจากรหัส
อัปเดต:และวิธีที่ถูกต้องในการเริ่มบริการจากบรรทัดคำสั่งคือใช้คำสั่ง "sc" ( Service Controller ) แทน "net"
แม้จะปฏิบัติตามคำตอบที่ยอมรับอย่างตรงไปตรงมา แต่ฉันก็ยังไม่สามารถเริ่มบริการได้ - ฉันได้รับข้อความแจ้งข้อผิดพลาดระหว่างการติดตั้งแทนโดยระบุว่าไม่สามารถเริ่มบริการที่เพิ่งติดตั้งได้เนื่องจากไม่มีอยู่จริงแม้จะใช้ 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();
}
การเริ่มต้นอัตโนมัติหมายความว่าบริการจะเริ่มโดยอัตโนมัติเมื่อ Windows เริ่มทำงาน ดังที่คนอื่น ๆ กล่าวถึงในการเริ่มต้นจากคอนโซลคุณควรใช้ ServiceController
คุณสามารถใช้GetServices
เมธอดของ
คลาสServiceControllerเพื่อรับอาร์เรย์ของบริการทั้งหมด จากนั้นค้นหาบริการของคุณโดยตรวจสอบServiceName
คุณสมบัติของแต่ละบริการ เมื่อคุณพบบริการของคุณแล้วให้โทรหาStart
วิธีการเพื่อเริ่มใช้งาน
นอกจากนี้คุณควรตรวจสอบStatus
คุณสมบัติเพื่อดูว่ามีอยู่ในสถานะใดแล้วก่อนที่จะเริ่มการโทร (อาจกำลังทำงานหยุดชั่วคราวหยุดทำงาน ฯลฯ .. )
คุณทำให้นักออกแบบของคุณเสียหาย เพิ่มส่วนประกอบตัวติดตั้งของคุณอีกครั้ง ควรมี serviceInstaller และ serviceProcessInstaller serviceInstaller พร้อมคุณสมบัติ Startup Method ที่ตั้งค่าเป็น Automatic จะเริ่มทำงานเมื่อติดตั้งและหลังจากรีบูตแต่ละครั้ง
หมายเหตุ: คุณอาจตั้งค่าบริการของคุณแตกต่างกันโดยใช้อินเทอร์เฟซแบบฟอร์มเพื่อเพิ่มตัวติดตั้งบริการและตัวติดตั้งโครงการ ในกรณีนั้นให้แทนที่ตำแหน่งที่ระบุว่า serviceInstaller.ServiceName ด้วย "name from designer ".ServiceName
คุณไม่จำเป็นต้องมีสมาชิกส่วนตัวในกรณีนี้
ขอบคุณสำหรับความช่วยเหลือ
นี่คือขั้นตอนและรหัสที่ใช้สร้างProjectInstaller
ใน Visual Studio:
ProjectInstaller
ในตัวแก้ไขการออกแบบ (ควรเปิดโดยอัตโนมัติเมื่อสร้างตัวติดตั้ง) และตั้งค่าคุณสมบัติของการสร้างserviceProcessInstaller1
(เช่นบัญชี: LocalSystem) และserviceInstaller1
(เช่น StartType: Automatic)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();
}
}
}