2011-02-01 10 views
46

Ive ने प्रॉक्सी मॉनिटर नामक एक विंडोज सेवा बनाई और वर्तमान में उस चरण में जहां सेवा स्थापित है और जिस तरह से मैं इसे चाहता हूं अनइंस्टॉल कर रहा हूं।लगातार चलने के लिए विंडोज सेवा

तो मैं तो जैसे आवेदन निष्पादित करें:

C:\\Windows\\Vendor\\ProxyMonitor.exe /install 

सुंदर आत्म व्याख्यात्मक है, और फिर मैं services.msc गया और और सेवा शुरू करते हैं, लेकिन मैं निम्न संदेश मिलता है जब मैं इस कार्य करें:

स्थानीय कंप्यूटर पर प्रॉक्सी मॉनीटर सेवा शुरू हुई और फिर रुक गई। कुछ सेवाएं स्वचालित रूप रोक अगर वहाँ ऐसा करने के लिए कोई काम नहीं है उदाहरण के लिए, प्रदर्शन लॉग्स और चेतावनियों सेवाएं

मेरे कोड तो दिखाई देता है:

public static Main(string[] Args) 
{ 
    if (System.Environment.UserInteractive) 
    { 
     /* 
      * Here I have my install logic 
     */ 
    } 
    else 
    { 
     ServiceBase.Run(new ProxyMonitor()); 
    } 
} 

और फिर ProxyMonitor वर्ग के भीतर मेरे पास है:

public ProxyMonitor() 
{ 
} 

protected override void OnStart(string[] args) 
{ 
    base.OnStart(args); 
    ProxyEventLog.WriteEntry("ProxyMonitor Started"); 

    running = true; 
    while (running) 
    { 
     //Execution Loop 
    } 
} 

और onStop() मैं running परिवर्तनीय को false में बदलता हूं;

क्या मैं के रूप में मैं नेटवर्क मैं परिवर्तन आदि का पता लगाने की जरूरत है की निगरानी करने की आवश्यकता होगी, सेवा लगातार सक्रिय बनाने के लिए क्या करने की आवश्यकता होगी


अद्यतन: 1

protected override void OnStart(string[] args) 
{ 
    base.OnStart(args); 
    ProxyEventLog.WriteEntry("ProxyMonitor Started"); 

    Thread = new Thread(ThreadWorker); 
    Thread.Start(); 
} 

ThreadWorker के भीतर मेरे पास ProxyEventLogger.WriteEntry("Main thread entered") है जिसे निकाल दिया नहीं जाता है।

+0

'थ्रेड = नया थ्रेड (ThreadWorker)' अभ्यस्त काम –

+0

बिल्कुल ठीक काम करता है, ऐसा क्यों है विफल हो जाएगा आप सोचा? – RobertPitt

उत्तर

117

OnStart() कॉलबैक को समय-समय पर वापस लौटने की जरूरत है, इसलिए आप एक थ्रेड बंद करना चाहेंगे जहां आपका पूरा काम किया जाएगा। मैं अपनी कक्षा में निम्नलिखित क्षेत्रों को जोड़ने की सिफारिश करेंगे:

using System.Threading; 
private ManualResetEvent _shutdownEvent = new ManualResetEvent(false); 
private Thread _thread; 

_thread क्षेत्र System.Threading.Thread वस्तु आप OnStart() कॉलबैक में बनाने के लिए एक संदर्भ का आयोजन करेगा। _shutdownEvent फ़ील्ड में सिस्टम-स्तरीय ईवेंट निर्माण होता है जिसका उपयोग थ्रेड को सेवा बंद करने पर रोकने के लिए सिग्नल करने के लिए किया जाएगा।

OnStart() कॉलबैक में, अपना धागा बनाएं और शुरू करें।

protected override void OnStart(string[] args) 
{ 
    _thread = new Thread(WorkerThreadFunc); 
    _thread.Name = "My Worker Thread"; 
    _thread.IsBackground = true; 
    _thread.Start(); 
} 

इस काम के लिए आपको WorkerThreadFunc नामक फ़ंक्शन की आवश्यकता है। इसे System.Threading.ThreadStart प्रतिनिधि हस्ताक्षर से मेल खाना है।

private void WorkerThreadFunc() 
{ 
} 

आप इस समारोह में कुछ भी डाल नहीं है, धागा ऊपर तुरंत बंद शुरू हुई और फिर जाएगा, ताकि आप वहाँ कि मूल रूप से धागा जीवित रहता है, जबकि तुम अपना काम करो में कुछ तर्क पर रखना होगा। यह वह जगह है जहां _shutdownEvent काम में आता है।

private void WorkerThreadFunc() 
{ 
    while (!_shutdownEvent.WaitOne(0)) { 
     // Replace the Sleep() call with the work you need to do 
     Thread.Sleep(1000); 
    } 
} 

जबकि पाश ManualResetEvent की जाँच करता है देखने के लिए यह "सेट" है या नहीं। चूंकि हमने उपरोक्त false के साथ ऑब्जेक्ट प्रारंभ किया है, यह चेक गलत लौटाता है। लूप के अंदर, हम 1 सेकंड के लिए सोते हैं। आप इसे उस काम के साथ प्रतिस्थापित करना चाहते हैं जो आपको करने की ज़रूरत है - प्रॉक्सी सेटिंग्स की निगरानी करें, आदि

अंत में, OnStop() आपकी विंडोज सेवा के कॉलबैक में, आप धागे को चलना बंद करना चाहते हैं। _shutdownEvent का उपयोग करना आसान है।

protected override void OnStop() 
{ 
    _shutdownEvent.Set(); 
    if (!_thread.Join(3000)) { // give the thread 3 seconds to stop 
     _thread.Abort(); 
    } 
} 

उम्मीद है कि इससे मदद मिलती है।

+0

इसके लिए धन्यवाद, मैंने इसे सब समझा और अब यह अपेक्षित के रूप में चल रहा है :) – RobertPitt

+4

मदद करने में खुशी हुई। इसके लायक होने के लिए, मेरे पास कुछ विस्तृत एसओ ट्यूटोरियल हैं जो दिखाते हैं (1) इवेंट व्यूअर में अपना खुद का लॉग कैसे करें (http://stackoverflow.com/questions/593454/easiest-language-for- क्रिएटिंग -a-windows-service/593803 # 593803) और (2) InstallUtil.exe की आवश्यकता के बिना अपनी सेवा को कैसे इंस्टॉल/अनइंस्टॉल करें (http://stackoverflow.com/questions/1195478/how-to-make-a-net- windows-सेवा-स्टार्ट-सही के बाद स्थापना/1195621 # 1195621)। –

+0

हाँ आपकी मदद के लिए बहुत बहुत धन्यवाद, मैंने अपनी खोज में अपनी पहली लेख को जीत के लिए पहले पढ़ा था, अगर आप मेरा कोड देखना चाहते हैं तो मैंने इसे यहां पोस्ट किया है और किस चरण पर टिप्पणी की है। http://pastebin.com/t8QQzXC9 – RobertPitt

0

आप विंडोज सेवा के प्रकार के अपने समाधान में एक नई परियोजना क्यों नहीं बनाते? यह उन सभी संरचनाओं को स्थापित करता है जिन्हें आपको कार्यान्वित करने की आवश्यकता है, यहां तक ​​कि सेवा शुरू करने/रोकने की घटनाओं के लिए हैंडलर भी शामिल हैं।

+1

यह आंशिक रूप से एक प्रशिक्षण अनुभव है और मैं नीचे से किए गए तरीके से सीखना पसंद करूंगा। – RobertPitt

+0

मैं तर्क दूंगा कि प्रशिक्षण के लिए भी (विशेष रूप से प्रशिक्षण के लिए?) आप यह सीखने के लिए सबसे अच्छा करेंगे कि कैसे वीएस विंडोज सेवा के लिए मचान बनाता है और फिर आप सीख सकते हैं कि यह क्यों काम करता है और यह कैसे काम करता है। नीचे की ओर, जैसा कि आप खोज रहे हैं, उतना ही निराशाजनक है। –

+0

यह सच है, तथ्य यह है कि बिंदु तर्कसंगत है, लेकिन यह मामला यहां नहीं है। यह एप्लिकेशन 60% हासिल किया गया है और शायद मेरे अगले एप्लिकेशन पर मैं विंडोज सेवा टेम्पलेट पर शुरू करूंगा। – RobertPitt

6

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

संपादित करें:

कोशिश अपने OnStart में एक System.Diagnostics.Debugger.Launch() डाल देखो क्या हो रहा है (और ThreadWorker में एक ब्रेकपाइंट डाल) करने के लिए। मैं यह सुनिश्चित करने के लिए #if DEBUG में इसे लपेटने की अनुशंसा करता हूं कि यह तैनात नहीं किया गया है।

मैं सिर्फ यह भी महसूस किया है कि आप अपने Thread एक नाम देना नहीं है: निश्चित रूप से OnStart विधि में एक while पाश जोड़ने नहीं

Thread myThread = new Thread(ThreadWorker); 
myThread.Start(); 
+0

क्या कोई रिटर्न कोड होना चाहिए, जैसे 'वापसी 0' या' वापसी झूठी ', और एक धागा भी ठीक होगा? – RobertPitt

+0

नहीं; 'ऑनस्टार्ट' ईवेंट हैंडलर शून्य लौटाता है। जब तक यह उचित समय सीमा के भीतर निकलता है (लगभग एक मिनट, मुझे लगता है), सेवा नियंत्रक खुश होगा। –

+0

बीमार इसे जाने दो। – RobertPitt

2

। यह ओएस को यह कहता है कि सेवा शुरू नहीं हुई है क्योंकि यह OnStart विधि से सुरक्षित रूप से बाहर निकलने में सक्षम नहीं था। मैं आमतौर पर Timer बनाता हूं जो OnStart विधि में सक्षम है। फिर Ticks विधि में, मैं आवेदक चलाने के लिए आवश्यक विधि को कॉल करता हूं।

वैकल्पिक रूप से, आप निम्न कार्य कर सकते हैं:

// The main entry point for the process 
static void Main() 
{ 
    System.ServiceProcess.ServiceBase[] ServicesToRun; 
    ServicesToRun = new System.ServiceProcess.ServiceBase[] { new WinService1() }; 
    System.ServiceProcess.ServiceBase.Run(ServicesToRun); 
} 

विंडोज सेवाओं के बारे में अधिक जानकारी के लिए आप एक कंकाल उदाहरण here मिल सकती है।

1

नमूना कोड एक कंसोल ऐप का उपयोग करके प्रदर्शित किया गया। उम्मीद है कि इस में मदद मिलेगी ..

class Program 
{ 
    private static CancellationTokenSource _cancellationTokenSource; 
    private static ManualResetEvent _shutdownEvent = new ManualResetEvent(false); 
    private static Thread _serviceStartThread; 
    private static Thread _serviceStopThread; 

    private static int workcounter = 0; 
    static void Main(string[] args) 
    { 

     _cancellationTokenSource = new CancellationTokenSource(); 
     _serviceStartThread = new Thread(DoWork); 
     _serviceStopThread = new Thread(ScheduledStop); 
     StartService(); 
     StopService(); 
    } 

    private static void StartService() 
    { 
     _serviceStartThread.Start(); 

    } 

    private static void StopService() 
    { 
     _serviceStopThread.Start(); 
    } 


    /// <summary> 
    /// Triggers a cancellation event for stopping the service in a timely fashion. 
    /// </summary> 
    private static void ScheduledStop() 
    { 
     while (!_shutdownEvent.WaitOne(0)) 
     { 
      if (workcounter == 10) 
      { 
       _cancellationTokenSource.Cancel(); 
      } 
     } 
    } 

    /// <summary> 
    /// Represents a long running Task with cancellation option 
    /// </summary> 
    private static void DoWork() 
    { 

     while (!_shutdownEvent.WaitOne(0)) 
     { 
      if(!_cancellationTokenSource.Token.IsCancellationRequested) 
      { 
       workcounter += 1; 
       Console.Write(Environment.NewLine); 
       Console.Write("Running...counter: " + workcounter.ToString()); 
       Thread.Sleep(1000);//Not needed, just for demo.. 
      } 
      else 
      { 
       Console.Write(Environment.NewLine); 
       Console.Write("Recieved cancellation token,shutting down in 5 seconds.. counter: " + workcounter.ToString()); 
       _shutdownEvent.Set(); 
       Thread.Sleep(5000);//Not needed, just for demo.. 
      } 

     } 
    } 
}