स्थापना के ठीक बाद .NET विंडोज सेवा कैसे शुरू करें?


88

सेवा के अलावा। SartType = ServiceStartMode.Automatic मेरी सेवा स्थापना के बाद शुरू नहीं होती है

समाधान

इस कोड को मेरे ProjectInstaller पर डाला

protected override void OnAfterInstall(System.Collections.IDictionary savedState)
{
    base.OnAfterInstall(savedState);
    using (var serviceController = new ServiceController(this.serviceInstaller1.ServiceName, Environment.MachineName))
        serviceController.Start();
}

ScottTx और फ्रांसिस बी के लिए धन्यवाद।


यह स्थापना के ठीक बाद शुरू नहीं होता है या जब आप रिबूट करते हैं तो यह शुरू नहीं होता है?
क्रिस वान ओपस्टल

जवाबों:


21

आप यह सब InstallUtil प्रक्रिया से निकाल दी गई घटनाओं के जवाब में अपनी सेवा के निष्पादन योग्य के भीतर से कर सकते हैं। सेवा शुरू करने के लिए एक ServiceController वर्ग का उपयोग करने के लिए OnAfterInstall घटना को ओवरराइड करें।

http://msdn.microsoft.com/en-us/library/system.serviceprocess.serviceinstaller.aspx


3
यह एक अच्छा समाधान है, लेकिन फिर भी इंस्टॉलयूटिल उपयोगिता का उपयोग करने की आवश्यकता है। यदि आप पहले से ही InstallUtil को अपनी स्थापना के हिस्से के रूप में वितरित कर रहे हैं, तो यह सबसे अधिक समझ में आता है। लेकिन, यदि आप InstallUtil की पैकेजिंग को छोड़ना चाहते हैं, तो कमांड-लाइन समाधान का उपयोग करें।
मैट डेविस

181

मैंने यहाँ C # में एक Windows सेवा बनाने के लिए चरण-दर-चरण प्रक्रिया पोस्ट की है । ऐसा लगता है कि आप कम से कम इस बिंदु पर हैं, और अब आप सोच रहे हैं कि एक बार स्थापित होने के बाद सेवा कैसे शुरू करें। StartType संपत्ति को स्वचालित पर सेट करने से आपके सिस्टम को रिबूट करने के बाद सेवा स्वचालित रूप से शुरू हो जाएगी, लेकिन यह (जैसा कि आपने खोजा है) स्वचालित रूप से स्थापना के बाद आपकी सेवा शुरू नहीं करेगी।

मुझे याद नहीं है कि मैंने इसे मूल रूप से कहाँ पाया था (शायद मार्क ग्रेवेल?), लेकिन मुझे एक समाधान ऑनलाइन मिला जो आपको वास्तव में आपकी सेवा चलाने के द्वारा आपकी सेवा स्थापित करने और शुरू करने की अनुमति देता है। यहाँ चरण-दर-चरण है:

  1. Main()इस तरह अपनी सेवा के कार्य की संरचना :

    static void Main(string[] args)
    {
        if (args.Length == 0) {
            // Run your service normally.
            ServiceBase[] ServicesToRun = new ServiceBase[] {new YourService()};
            ServiceBase.Run(ServicesToRun);
        } else if (args.Length == 1) {
            switch (args[0]) {
                case "-install":
                    InstallService();
                    StartService();
                    break;
                case "-uninstall":
                    StopService();
                    UninstallService();
                    break;
                default:
                    throw new NotImplementedException();
            }
        }
    }
    
  2. यहाँ सहायक कोड है:

    using System.Collections;
    using System.Configuration.Install;
    using System.ServiceProcess;
    
    private static bool IsInstalled()
    {
        using (ServiceController controller = 
            new ServiceController("YourServiceName")) {
            try {
                ServiceControllerStatus status = controller.Status;
            } catch {
                return false;
            }
            return true;
        }
    }
    
    private static bool IsRunning()
    {
        using (ServiceController controller = 
            new ServiceController("YourServiceName")) {
            if (!IsInstalled()) return false;
            return (controller.Status == ServiceControllerStatus.Running);
        }
    }
    
    private static AssemblyInstaller GetInstaller()
    {
        AssemblyInstaller installer = new AssemblyInstaller(
            typeof(YourServiceType).Assembly, null);
        installer.UseNewContext = true;
        return installer;
    }
    
  3. सहायक कोड के साथ जारी ...

    private static void InstallService()
    {
        if (IsInstalled()) return;
    
        try {
            using (AssemblyInstaller installer = GetInstaller()) {
                IDictionary state = new Hashtable();
                try {
                    installer.Install(state);
                    installer.Commit(state);
                } catch {
                    try {
                        installer.Rollback(state);
                    } catch { }
                    throw;
                }
            }
        } catch {
            throw;
        }
    }
    
    private static void UninstallService()
    {
        if ( !IsInstalled() ) return;
        try {
            using ( AssemblyInstaller installer = GetInstaller() ) {
                IDictionary state = new Hashtable();
                try {
                    installer.Uninstall( state );
                } catch {
                    throw;
                }
            }
        } catch {
            throw;
        }
    }
    
    private static void StartService()
    {
        if ( !IsInstalled() ) return;
    
        using (ServiceController controller = 
            new ServiceController("YourServiceName")) {
            try {
                if ( controller.Status != ServiceControllerStatus.Running ) {
                    controller.Start();
                    controller.WaitForStatus( ServiceControllerStatus.Running, 
                        TimeSpan.FromSeconds( 10 ) );
                }
            } catch {
                throw;
            }
        }
    }
    
    private static void StopService()
    {
        if ( !IsInstalled() ) return;
        using ( ServiceController controller = 
            new ServiceController("YourServiceName")) {
            try {
                if ( controller.Status != ServiceControllerStatus.Stopped ) {
                    controller.Stop();
                    controller.WaitForStatus( ServiceControllerStatus.Stopped, 
                         TimeSpan.FromSeconds( 10 ) );
                }
            } catch {
                throw;
            }
        }
    }
    
  4. इस बिंदु पर, आप अपनी सेवा को लक्ष्य मशीन पर स्थापित करने के बाद, अपनी सेवा -installको स्थापित करने और शुरू करने के लिए कमांड लाइन तर्क के साथ कमांड लाइन (किसी भी साधारण एप्लिकेशन की तरह) से अपनी सेवा को चलाएं ।

मुझे लगता है कि मैंने सब कुछ कवर कर लिया है, लेकिन अगर आपको लगता है कि यह काम नहीं करता है, तो कृपया मुझे बताएं ताकि मैं जवाब को अपडेट कर सकूं।


12
ध्यान दें कि इस समाधान को InstallUtil.exe के उपयोग की आवश्यकता नहीं है, इसलिए आपको इसे अपने स्थापना कार्यक्रम के हिस्से के रूप में वितरित करने की आवश्यकता नहीं है।
मैट डेविस

3
खाली "कैच {थ्रो?}" क्लॉस के साथ क्या बात है? इसके अलावा, "रोलबैक ()" द्वारा विफलताओं को छिपाने के लिए शायद यह एक अच्छा विचार नहीं है क्योंकि यह स्थिति मूल रूप से एक अपरिभाषित स्थिति में सिस्टम को छोड़ देती है मुझे लगता है (आपने एक सेवा स्थापित करने का प्रयास किया, बीच में कहीं विफल हो गया और इसे पूर्ववत नहीं कर सका। )। आपको कम से कम उपयोगकर्ता को "दिखाना" चाहिए कि कुछ गड़बड़ है - या रोलबैक () फ़ंक्शन कंसोल के लिए कुछ संदेश लिखता है?
क्रिश्चियन.के।

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

4
मुझे त्रुटि मिल रही है त्रुटि: 'YourServiceType' नाम या नाम स्थान का प्रकार नहीं पाया जा सका (क्या आप किसी निर्देश या असेंबली संदर्भ का उपयोग कर रहे हैं?
योगेश

5
YourServiceTypeहै ProjectInstallerआप सेवा है जो शामिल है को जोड़ा गया ServiceInstallerऔरServiceProcessInstaller
बंसी

6

दृश्य स्टूडियो

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

ServiceController controller  = new ServiceController();
controller.MachineName = "";//The machine where the service is installed;
controller.ServiceName = "";//The name of your service installed in Windows Services;
controller.Start();

InstallShield या समझदार

यदि आप InstallShield या समझदार का उपयोग कर रहे हैं, तो ये एप्लिकेशन सेवा शुरू करने का विकल्प प्रदान करते हैं। समझदारी के साथ प्रति उदाहरण, आपको एक सेवा नियंत्रण कार्रवाई को जोड़ना होगा। इस क्रिया में, आप निर्दिष्ट करते हैं कि आप सेवा शुरू करना चाहते हैं या बंद करना चाहते हैं।

Wix

Wix का उपयोग करना आपको अपनी सेवा के घटक के तहत निम्नलिखित xml कोड जोड़ने की आवश्यकता है। उसके बारे में अधिक जानकारी के लिए, आप इस पृष्ठ को देख सकते हैं ।

<ServiceInstall 
    Id="ServiceInstaller"  
    Type="ownProcess"  
    Vital="yes"  
    Name=""  
    DisplayName=""  
    Description=""  
    Start="auto"  
    Account="LocalSystem"   
    ErrorControl="ignore"   
    Interactive="no">  
        <ServiceDependency Id="????"/> ///Add any dependancy to your service  
</ServiceInstall>

5

स्रोत के रूप में EXE या बैच (sc start) के घटक नाम का उपयोग करके MSI में 'ExecuteImmediate' अनुक्रम के अंत में एक कस्टम क्रिया जोड़ने की आवश्यकता है। मुझे नहीं लगता कि यह Visual Studio के साथ किया जा सकता है, आपको इसके लिए एक वास्तविक MSI संलेखन उपकरण का उपयोग करना पड़ सकता है।


4

स्थापना के ठीक बाद इसे शुरू करने के लिए, मैं एक बैच फ़ाइल स्थापित करता हूं जिसमें इंस्टॉलुटिल के बाद sc शुरुआत होती है

यह आदर्श नहीं है, लेकिन यह काम करता है ...।


4

इसे शुरू करने के लिए .NET ServiceController क्लास का उपयोग करें, या इसे शुरू करने के लिए कमांडलाइन कमांड जारी करें --- "नेट स्टार्ट सर्विसेनम"। किसी भी तरह से काम करता है।


4

ScottTx के उत्तर में जोड़ने के लिए, यदि आप इसे Microsoft तरीके से कर रहे हैं तो सेवा शुरू करने के लिए यहां वास्तविक कोड है (अर्थात, सेटअप प्रोजेक्ट आदि का उपयोग ...)

(VB.net कोड बहाना, लेकिन यह वही है जो मैं के साथ फंस गया हूं)

Private Sub ServiceInstaller1_AfterInstall(ByVal sender As System.Object, ByVal e As System.Configuration.Install.InstallEventArgs) Handles ServiceInstaller1.AfterInstall
    Dim sc As New ServiceController()
    sc.ServiceName = ServiceInstaller1.ServiceName

    If sc.Status = ServiceControllerStatus.Stopped Then
        Try
            ' Start the service, and wait until its status is "Running".
            sc.Start()
            sc.WaitForStatus(ServiceControllerStatus.Running)

            ' TODO: log status of service here: sc.Status
        Catch ex As Exception
            ' TODO: log an error here: "Could not start service: ex.Message"
            Throw
        End Try
    End If
End Sub

उपरोक्त ईवेंट हैंडलर बनाने के लिए, ProjectInstaller डिज़ाइनर पर जाएं जहाँ 2 नियंत्रक हैं। ServiceInstaller1 नियंत्रण पर क्लिक करें। इवेंट्स के अंतर्गत प्रॉपर्टीज़ विंडो पर जाएँ और आपको AfterInstall इवेंट मिलेगा।

नोट: उपरोक्त कोड को ServiceProcessInstaller1 के लिए AfterInstall इवेंट के अंतर्गत न डालें। यह काम नहीं करेगा, अनुभव से आ रहा है। :)


VB.net कोड बुरा नहीं है! हम में से उन लोगों के लिए जो कई भाषाओं में काम करते हैं, उन्हें सी से कोड को नहीं बदलना अच्छा है!
स्टीव रीड सीनियर

धन्यवाद, इससे मुझे यह पता लगाने में मदद मिली कि स्वचालित रूप से एक सेवा कैसे शुरू की जाए।
चार्ल्स ओवेन

0

सबसे आसान समाधान यहाँ पाया गया है कि विंडोज़-सेवा-विहीन-इंस्टालिटिल-एक्स द्वारा @ होएंग लॉन्ग

@echo OFF
echo Stopping old service version...
net stop "[YOUR SERVICE NAME]"
echo Uninstalling old service version...
sc delete "[YOUR SERVICE NAME]"

echo Installing service...
rem DO NOT remove the space after "binpath="!
sc create "[YOUR SERVICE NAME]" binpath= "[PATH_TO_YOUR_SERVICE_EXE]" start= auto
echo Starting server complete
pause
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.