2015-05-18 8 views
6

की सूचना दी मैंने एक छोटी सी सेवा लिखी, जो स्थानीय नेटवर्क सर्वर के रूप में कार्य करता है। सेवा लिखने के लिए, मैंने का पालन किया, ServiceBase कक्षा का उपयोग करके सेवा कैसे लिखें।सेवा कारण एससीएम त्रुटि "एक अमान्य वर्तमान स्थिति 0"

लेकिन जब मैं पंजीकरण और सेवा शुरू करता हूं, तो मुझे नीचे दिखाए गए त्रुटि संदेश मिलते हैं। मुझे शुरुआत में और सर्विस स्टॉप पर इन त्रुटि संदेशों में से दो मिलते हैं। (उदाहरण = सेवा का नाम)।

उदाहरण सेवा सभी प्रासंगिक भागों के साथ गलत वर्तमान स्थिति 0.

यहाँ मेरी सेवा का एक न्यूनतम नमूना सूचना दी है।

public enum ServiceState 
{ 
    SERVICE_STOPPED = 0x00000001, 
    SERVICE_START_PENDING = 0x00000002, 
    SERVICE_STOP_PENDING = 0x00000003, 
    SERVICE_RUNNING = 0x00000004, 
    SERVICE_CONTINUE_PENDING = 0x00000005, 
    SERVICE_PAUSE_PENDING = 0x00000006, 
    SERVICE_PAUSED = 0x00000007, 
} 

[StructLayout(LayoutKind.Sequential)] 
public struct ServiceStatus 
{ 
    public long dwServiceType; 
    public ServiceState dwCurrentState; 
    public long dwControlsAccepted; 
    public long dwWin32ExitCode; 
    public long dwServiceSpecificExitCode; 
    public long dwCheckPoint; 
    public long dwWaitHint; 
}; 

इस के बाद, सेवा कोड मैंने लिखा, प्रासंगिक भागों को कम किया:

namespace example 
{ 
    public partial class Service : ServiceBase 
    { 
     public Service() 
      : base() 
     { 
      this.ServiceName = "ExampleService"; 
      this.AutoLog = false; 
      this.CanStop = true; 
      this.CanShutdown = false; 
      this.CanPauseAndContinue = false; 
      this.CanHandlePowerEvent = false; 
      this.CanHandleSessionChangeEvent = false; 
     } 

     protected override void OnStart(string[] args) 
     { 
      try { 
       SetServiceState(ServiceState.SERVICE_START_PENDING, 100000); 
       // ... initialise and start... 
       SetServiceState(ServiceState.SERVICE_RUNNING); 
      } catch (System.Exception ex) { 
       SetServiceState(ServiceState.SERVICE_STOPPED); 
      } 
     } 

     protected override void OnStop() 
     { 
      SetServiceState(ServiceState.SERVICE_STOP_PENDING, 100000); 
      // ... stop service ... 
      SetServiceState(ServiceState.SERVICE_STOPPED); 
     } 

     private void SetServiceState(ServiceState state, int waitHint = 0) 
     { 
      ServiceStatus serviceStatus = new ServiceStatus(); 
      serviceStatus.dwCurrentState = state; 
      serviceStatus.dwWaitHint = waitHint; 
      SetServiceStatus(this.ServiceHandle, ref serviceStatus); 
     } 

     [DllImport("advapi32.dll", SetLastError=true)] 
     private static extern bool SetServiceStatus(IntPtr handle, ref ServiceStatus serviceStatus); 
    } 
} 

मुख्य प्रवेश बिंदु कोड एक enum और struct परिभाषा जो MSDN ट्यूटोरियल में प्रदान किया गया था के साथ शुरू होता इस के रूप में सरल है:

static void Main(string[] args) 
{ 
    ServiceBase.Run(new Service()); 
} 

आप देख सकते हैं, त्रुटि संदेश की संख्या SetServiceState कॉल की संख्या से मेल खाता है। अगर मैं ऐसी अतिरिक्त कॉल जोड़ता हूं, तो त्रुटि संदेशों की संख्या तदनुसार बढ़ जाती है।

तो मुझे लगता है कि पूरी समस्या कहीं भी है जिस तरह से मैं SetServiceStatus एपीआई कहता हूं, लेकिन मुझे वर्तमान में समस्या दिखाई नहीं दे रही है।

क्या आप समस्या को खोज सकते हैं?

वैसे भी सी # और .NET का उपयोग कर सेवा बनाने का यह सही तरीका है?

उत्तर

14

पहले:

यह सामान्य रूप से आवश्यक नहीं है SetServiceState विधि कॉल करने के। यदि आपकी सेवा में प्रारंभ करने के लिए वास्तव में लंबा समय लगता है (जहां आप एससीएम को बता सकते हैं कि आप अभी भी SERVICE_START_PENDING के साथ जीवित हैं और कुछ और सेकंड की आवश्यकता है) की आवश्यकता हो सकती है। आम तौर पर, आप OnStart में थ्रेड शुरू करते हैं और एएसपी वापस करते हैं।

मैंने पिछले वर्षों में सी # में कई सेवाएं लिखी हैं और इसकी आवश्यकता नहीं है।

लेकिन - मुझे एमएसडीएन नमूना कोड में एक बग मिली (मैंने आपके कोड का परीक्षण किया)।

ServiceStatus संरचना में int या (बेहतर इकाई) के साथ लंबे समय से प्रतिस्थापित करें। यदि आप यूंट का उपयोग करते हैं, तो आपको इसे SetServiceState विधि में भी बदलना होगा।

भी Should DWORD map to int or uint? देखें।

http://www.rsprog.de/samplewindowsservice/

[अपडेट 2018/01/20:

यदि आप एक छोटे परिचय में रुचि कैसे आप एक अतिरिक्त सेटअप के साथ सी # में एक Windows सेवा के साथ शुरू कर सकते हैं कर रहे हैं, तो आप अपने ब्लॉग प्रविष्टि की जांच कर सकते ]

मैंने इस बारे में एक नया लेख है, जो जो लाभ दिया है (कम से कम मेरे लिए) आत्म स्थापना विधि का उपयोग करता है बनाया है, कि यह दृश्य स्टूडियो

01 की स्थापना परियोजना विस्तार की जरूरत नहीं है

+0

बढ़िया, धन्यवाद, इस समस्या को हल किया गया। मुझे आमतौर पर पता है कि एमएसडीएन दस्तावेज कितना खराब है, लेकिन यहां मैंने अभी अनुमान लगाया है कि उदाहरण से यह संरचना परिभाषा सही है। आप भी सही हैं, मैन्युअल स्थिति अद्यतन वास्तव में आवश्यक नहीं हैं। मेरे कोड की स्टार्टअप ने पहले संस्करण में काफी समय लगाया, लेकिन मैंने सब कुछ थ्रेड में ले जाया, क्योंकि इन लंबी प्रक्रियाओं में से कुछ का परिणाम स्टार्टअप के लिए प्रासंगिक नहीं है। ग्रेट ब्लॉग एंट्री, केवल चरण-दर-चरण सूची के प्रारूपण ने मुझे लगभग सिरदर्द दिया ;-)। – Flovdis

+0

बढ़िया, यह मेरे लिए काम किया। यह गणना करना असंभव है कि एमएसडीएन में कितनी त्रुटियां हैं .... यह अनंत संख्या में से एक था ... – Fabiano

+0

बहुत बहुत धन्यवाद, रेनर - मैंने सेवा बनाने के लिए माइक्रोसॉफ्ट के नमूना कोड का उपयोग किया और तुरंत इस समस्या को तुरंत मारा। मैंने यहां अपने पृष्ठ पर एक टिप्पणी भी जोड़ दी है (https://technet.microsoft.com/en-us/library/cc756305(v=ws.10).aspx) यहां आपके समाधान की ओर इशारा करते हुए। – Rich

संबंधित मुद्दे