2010-03-25 3 views
23

मैं सी # में लिखी गई सेवा को डीबग करना चाहता हूं और पुराने तरीके से बहुत लंबा तरीका है। मुझे सेवा को रोकना है, मेरा एप्लिकेशन शुरू करना है जो डीबग मोड (विजुअल स्टूडियो 2008) में सेवा का उपयोग करता है, सेवा शुरू करता है, सेवा प्रक्रिया से जुड़ा होता है और फिर सेवा को ट्रिगर करने के लिए मेरे Asp.Net एप्लिकेशन में नेविगेट करता है।इसे कंसोल ऐप में एक सी # सेवा को लपेटने के लिए

मूल रूप से पृष्ठभूमि में सेवा चल रही है, जो कार्य की प्रतीक्षा कर रही है। वेब एप्लिकेशन सेवा द्वारा उठाए जाने वाले कार्य को ट्रिगर करेगा।

मैं क्या करना चाहता हूं कि एक कंसोल एप्लिकेशन है जो मुझे डीबग करने के प्रयास में सेवा को चलाता है। क्या कोई साधारण डेमो है जिसके बारे में कोई जानता है?

धन्यवाद जैक

उत्तर

1

यहाँ एक सांत्वना अनुप्रयोग के रूप में अपने विंडोज़ सेवा चलाने के बारे में एक blog post है।

तुम भी बस एक नया कंसोल अनुप्रयोग आपकी सेवा तरीकों का परीक्षण करने, के रूप में एक ही तर्क का संदर्भ या अपनी सेवाओं 'तर्क पर यूनिट टेस्ट की स्थापना की है कि बना सकते हैं

1

मैं इकाई परीक्षण का इस्तेमाल किया है में मुश्किल सेटअप डिबग करने के लिए अतीत, बस एक यूनिट टेस्ट लिखें जो यूनिट परीक्षण में जो भी पैरामीटर और सेट डीबग ब्रेकपॉइंट्स के साथ सेवा सेवा को कॉल करता है।

testdriven.net या Jetbrains testrunner का उपयोग करना इसे आसान बनाता है।

2

मैं डिबग बनाता है के लिए या तो एक config सेटिंग है या एक निर्देश का उपयोग करते हैं:

#if DEBUG 
    Debugger.Break(); 
#endif 

या

if(Settings.DebugBreak) 
      Debugger.Break(); 

मैं डाल कि सेवा घटक के onStart विधि में। फिर आपको स्वचालित रूप से संकेत दिया जाता है और प्रक्रिया से जुड़ा होता है।

20

आप मुख्य प्रवेश बिंदु में कुछ इस तरह कर सकते हैं:

static void Main() 
{ 
#if DEBUG 
    Service1 s = new Service1(); 
    s.Init(); // Init() is pretty much any code you would have in OnStart(). 
#else 
    ServiceBase[] ServicesToRun; 
    ServicesToRun=new ServiceBase[] 
    { 
     new Service1() 
    }; 
    ServiceBase.Run(ServicesToRun); 
#endif 
} 

और अपने onStart इवेंट हैंडलर में:

protected override void OnStart(string[] args) 
{ 
    Init(); 
} 
+0

+1 - मेरे पास लिखी गई कुछ सेवाओं में लगभग एक ही कोड है। – 37Stars

15

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

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

3

TopShelf एक अन्य परियोजना है जो इस दृष्टिकोण के लिए बिल्कुल सही है। यह आपको एक सेवा के रूप में एक प्रक्रिया, या न्यूनतम विन्यास के साथ नियमित कंसोल अनुप्रयोग के रूप में चलाने की अनुमति देता है।

10

वैश्विक परिभाषाओं का उपयोग करने से बचने के लिए मैं आम तौर पर रन-टाइम पर परीक्षण करता हूं कि क्या मैं पर्यावरण के माध्यम से सेवा या नियमित आवेदन करता हूं। उपयोगकर्ता इंटरेक्टिव प्रॉपर्टी।

[MTAThread()] 
    private static void Main() 
    { 
     if (!Environment.UserInteractive) 
     { 
      ServiceBase[] aServicesToRun; 

      // More than one NT Service may run within the same process. To add 
      // another service to this process, change the following line to 
      // create a second service object. For example, 
      // 
      // ServicesToRun = New System.ServiceProcess.ServiceBase() {New ServiceMain, New MySecondUserService} 
      // 
      aServicesToRun = new ServiceBase[] {new ServiceMain()}; 

      Run(aServicesToRun); 
     } 
     else 
     { 
      var oService = new ServiceMain(); 
      oService.OnStart(null); 
     } 
    } 
+8

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

0

मैं इस का उपयोग करता है, तो मेरी प्रक्रिया या नहीं एक सेवा के रूप में चल रहा है की जाँच करने के।

public class ServiceDiagnostics 
{ 
    readonly bool _isUserService; 
    readonly bool _isLocalSystem; 
    readonly bool _isInteractive; 

    public ServiceDiagnostics() 
    { 
     var wi = WindowsIdentity.GetCurrent(); 
     var wp = new WindowsPrincipal(wi); 

     var serviceSid = new SecurityIdentifier(WellKnownSidType.ServiceSid, null); 
     var localSystemSid = new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null); 
     var interactiveSid = new SecurityIdentifier(WellKnownSidType.InteractiveSid, null); 

     this._isUserService = wp.IsInRole(serviceSid); 

     // Neither Interactive or Service was present in the current user's token, This implies 
     // that the process is running as a service, most likely running as LocalSystem. 
     this._isLocalSystem = wp.IsInRole(localSystemSid); 

     // This process has the Interactive SID in its token. This means that the process is 
     // running as a console process. 
     this._isInteractive = wp.IsInRole(interactiveSid); 
    } 

    public bool IsService 
    { 
     get { return this.IsUserService || this.IsLocalSystem || !this.IsInteractive; }  
    } 

    public bool IsConsole 
    { 
     get { return !this.IsService; } 
    } 

    /// <summary> 
    /// This process has the Service SID in its token. This means that the process is running 
    /// as a service running in a user account (not local system). 
    /// </summary> 
    public bool IsUserService 
    { 
     get { return this._isUserService; } 
    } 

    /// <summary> 
    /// Neither Interactive or Service was present in the current user's token, This implies 
    /// that the process is running as a service, most likely running as LocalSystem. 
    /// </summary> 
    public bool IsLocalSystem 
    { 
     get { return this._isLocalSystem; } 
    } 

    /// <summary> 
    /// This process has the Interactive SID in its token. This means that the process is 
    /// running as a console process. 
    /// </summary> 
    public bool IsInteractive 
    { 
     get { return this._isInteractive; } 
    } 
} 
2

आप नीचे दिए गए अनुसार प्रतिबिंब के माध्यम से सेवा विधियों को कॉल कर सकते हैं।

Environment.UserInteractive का उपयोग करके हम यह जान सकते हैं कि हम कंसोल ऐप के रूप में या सेवा के रूप में चल रहे हैं या नहीं।

ServiceBase[] ServicesToRun; 
ServicesToRun = new ServiceBase[] 
{ 
    new MyService() 
}; 

if (!Environment.UserInteractive) 
{ 
    // This is what normally happens when the service is run. 
    ServiceBase.Run(ServicesToRun); 
} 
else 
{ 
    // Here we call the services OnStart via reflection. 
    Type type = typeof(ServiceBase); 
    BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic; 
    MethodInfo method = type.GetMethod("OnStart", flags); 

    foreach (ServiceBase service in ServicesToRun) 
    { 
     Console.WriteLine("Running " + service.ServiceName + ".OnStart()"); 
     // Your Main method might not have (string[] args) but you could add that to be able to send arguments in. 
     method.Invoke(service, new object[] { args }); 
    } 

    Console.WriteLine("Finished running all OnStart Methods."); 

    foreach (ServiceBase service in ServicesToRun) 
    { 
     Console.WriteLine("Running " + service.ServiceName + ".OnStop()"); 
     service.Stop(); 
    } 
} 
संबंधित मुद्दे