स्वचालित रूप से इंस्टॉल पर एक विंडोज सेवा शुरू करें


119

मेरे पास एक Windows सेवा है जिसे मैं InstallUtil.exe का उपयोग करके स्थापित करता हूं। हालांकि मैंने स्टार्टअप विधि को स्वचालित पर सेट किया है, सेवा स्थापित होने पर शुरू नहीं होती है, मुझे मैन्युअल रूप से सेवाओं को खोलना होगा और प्रारंभ पर क्लिक करना होगा। क्या कमांड लाइन के माध्यम से, या सेवा संहिता के माध्यम से इसे शुरू करने का कोई तरीका है?

जवाबों:


218

अपने इंस्टॉलर वर्ग में, 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
(एक प्रस्तावित संपादन से टिप्पणी): सेवा का उपयोग करने के लिए बेहतर है। Installer.ServiceName, अगर सर्विसनेम बदल जाता है तो यह कोड में इसे बदलने की आवश्यकता के बिना सही नाम का उपयोग करेगा।
मार्क Gravell

1
यह भी ServiceControllerएक का उपयोग बयान में लपेट करने के लिए चोट नहीं होगा ।
क्रिस

3
आप कैसे सेवा प्राप्त कर रहे हैं।
फिलिप रेगो

1
serviceInstaller को ServiceInstallerआपकी कक्षा में परिवर्तनशील माना जाता है । ऐसा वर्ग लागू करेगा System.Configuration.Install.Installer। अधिक जानकारी के लिए इस msdn गाइड देखें।
सर्जियो बसुरको

4
@PhilipRego संभवत: इवेंट हैंडलर द्वारा संदर्भित ऑब्जेक्ट है , जो कि कंस्ट्रक्टर में सामान्य रूप से त्वरित serviceInstallerहै । इसलिए आप बयान से पहले जोड़ सकते हैं । ServiceInstallersenderServiceInstaller()ServiceInstaller serviceInstaller = (ServiceInstaller)sender;using
खरगौश

28

थोड़ा सा रिफ्लेक्ट करने के बाद, यह एक पूर्ण विंडोज़ सर्विस इंस्टॉलर का एक उदाहरण है, जिसमें स्वत: शुरुआत होती है:

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: System.ServiceProcess.ServiceInstaller के OnAfterInstall इवेंट हैंडलर में एक अपवाद उत्पन्न हुआ। आंतरिक अपवाद System.InvalidOperationException को निम्न त्रुटि संदेश के साथ फेंक दिया गया था: कंप्यूटर पर सेवा सेवा शुरू नहीं कर सकता '।' .. आंतरिक अपवाद System.ComponentModel.Win32Exception को निम्न त्रुटि संदेश के साथ फेंका गया था: निष्पादन योग्य प्रोग्राम जो इस सेवा को कॉन्फ़िगर किया गया है। रन सेवा में लागू नहीं होता है।
गोमाँ

2
एक बार जब मैंने लाइन "InitializeComponent ()" की टिप्पणी की, तो त्रुटियां जब्त हो गईं। मेरा मानना ​​है कि यह रेखा अन्य सभी पंक्तियों को दोहरा रही है क्योंकि लॉग त्रुटि के पहले एक साथ दो समान चीजें दिखाते हैं: सेवा को स्थापित करना सेवा नाम ... सेवा सेवा नाम सफलतापूर्वक स्थापित किया गया है। EventLog स्रोत सेवा का नाम बनाना अनुप्रयोग में ... सेवा की स्थापना सेवानाम स्थापित करना ... LogLog स्रोत सेवा का नाम बनाना अनुप्रयोग में लॉग इन करें ... System.ServiceProcess.ServiceInstaller के OnAfterInstall ईवेंट हैंडलर में एक अपवाद उत्पन्न हुआ।
गोआम्न

आपने वास्तव में मेरा दिन बचाया :) इस उपयोगी टिप्पणी के लिए धन्यवाद। इसके बाद जब मैंने InitializeComponent () कॉल के बारे में टिप्पणी की, तो मेरी सेवा भी पूरी तरह से शुरू हो गई
Konstantin

7

निम्नलिखित के बारे में कैसे?

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

ठंडा। मैंने स्थापना के ठीक बाद अपनी स्थापना बैच फ़ाइल में इसे लिखा था।
एम। फवाद सुरोश

5

नियंत्रण सेवाओं के लिए प्रोग्रामेटिक विकल्प:

  • मूल कोड का उपयोग किया जा सकता है, "सेवा शुरू करना" । न्यूनतम निर्भरता के साथ अधिकतम नियंत्रण लेकिन सबसे अधिक काम।
  • WMI: Win32_Service ने aStartService विधि है। यह उन मामलों के लिए अच्छा है जहाँ आपको अन्य प्रसंस्करण (जैसे कि किस सेवा का चयन करना है) करने में सक्षम होना चाहिए।
  • PowerShell: पर अमल Start-Serviceके माध्यम से RunspaceInvokeया अपने स्वयं के बनाने के द्वारा Runspaceऔर उसके उपयोग करते हुए CreatePipelineनिष्पादित करने के लिए विधि। यह उन मामलों के लिए अच्छा है जहां आपको WMI की तुलना में बहुत आसान कोडिंग मॉडल के साथ अन्य प्रसंस्करण (जैसे कि किस सेवा का चयन करें) करने में सक्षम होना चाहिए, लेकिन PSH स्थापित होने पर निर्भर करता है।
  • एक .NET अनुप्रयोग का उपयोग कर सकते हैं ServiceController

4

आप सेवा शुरू करने के लिए निम्न कमांड लाइन का उपयोग कर सकते हैं:

net start *servicename*

2

ServiceController का उपयोग करेंकोड से अपनी सेवा शुरू करने के लिए का ।

अद्यतन: और कमांड लाइन से सेवा शुरू करने का अधिक सही तरीका "नेट" के बजाय "sc" ( सेवा नियंत्रक ) कमांड का उपयोग करना है।


6
क्यों "sc" एक "अधिक सही" तरीका है? "नेट स्टार्ट" (और स्टार्ट-सर्विस PSH cmdlet) में क्या गलत है?
रिचर्ड

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

स्वचालित स्टार्टअप का मतलब है कि विंडोज शुरू होने पर सेवा स्वचालित रूप से शुरू हो जाती है। जैसा कि दूसरों ने उल्लेख किया है, इसे कंसोल से शुरू करने के लिए आपको सर्विसकंट्रोलर का उपयोग करना चाहिए।


मैं ऐसा करने की इच्छा नहीं करता। मैं इसे कमांड लाइन से या विंडोज सर्विस क्लासेस के भीतर से जाना चाहता हूं।
मिकजट्विन

क्षमा करें, मेरा बुरा है, मैंने उस बिंदु को याद किया जहां आपने नियंत्रण कक्ष पर इसे शुरू करने की संभावना को स्पष्ट रूप से बाहर रखा था।
माइकल क्लेमेंट

0

सभी सेवाओं की एक सरणी प्राप्त करने के लिए आप ServiceController वर्ग की GetServicesविधि का उपयोग कर सकते हैं । फिर, प्रत्येक सेवा की संपत्ति की जांच करके अपनी सेवा का पता लगाएं । जब आपको अपनी सेवा मिल जाए, तो इसे शुरू करने के लिए विधि को कॉल करें ।ServiceNameStart

आपको Statusसंपत्ति को यह देखने के लिए भी देखना चाहिए कि शुरू होने से पहले यह किस स्थिति में है (यह चल रहा है, रोका जा सकता है, रोका जा सकता है, आदि ..)।


0

आपने अपने डिजाइनर को भ्रष्ट कर दिया। अपने इंस्टॉलर घटक को फिर से जोड़ें। इसमें एक सर्विसइन्स्टॉलर और एक सर्विसप्रोसेसर इनस्टॉलर होना चाहिए। सर्विस स्टार्टप मेथड के साथ सर्विसइन्स्टालर ऑटोमैटिक सेट अप टू स्टार्टअप जब प्रत्येक रिबूट के बाद और इनस्टॉल होगा।


0

बस एक नोट: आपने सेवा इंस्टॉलर और प्रोजेक्ट इंस्टॉलर को जोड़ने के लिए फ़ॉर्म इंटरफ़ेस का उपयोग करके अपनी सेवा को अलग तरीके से सेट किया होगा। उस स्थिति में, जहाँ यह कहता है service.staller.ServiceName "डिज़ाइनर से नाम" .ServiceName।

आपको इस मामले में निजी सदस्यों की भी आवश्यकता नहीं है।

सहायता के लिए धन्यवाद।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.