क्या विंडोज सर्विस कंट्रोल मैनेजर के माध्यम से सेवा शुरू करने और फिर डिबगर को थ्रेड में संलग्न करने की तुलना में कोड के माध्यम से कदम रखने का एक आसान तरीका है? यह बोझिल की तरह है और मैं सोच रहा हूं कि क्या अधिक सरल दृष्टिकोण है।
क्या विंडोज सर्विस कंट्रोल मैनेजर के माध्यम से सेवा शुरू करने और फिर डिबगर को थ्रेड में संलग्न करने की तुलना में कोड के माध्यम से कदम रखने का एक आसान तरीका है? यह बोझिल की तरह है और मैं सोच रहा हूं कि क्या अधिक सरल दृष्टिकोण है।
जवाबों:
अगर मैं जल्दी से इस सेवा को समाप्त करना चाहता हूं, तो मैं बस Debugger.Break()
वहां से हट जाता हूं । जब वह लाइन पहुँच जाती है, तो वह मुझे वापस वी.एस. जब आप कर रहे हैं उस लाइन को हटाने के लिए मत भूलना।
अद्यतन:#if DEBUG
प्रैग्मैस के विकल्प के रूप में , आप Conditional("DEBUG_SERVICE")
विशेषता का उपयोग भी कर सकते हैं ।
[Conditional("DEBUG_SERVICE")]
private static void DebugMode()
{
Debugger.Break();
}
अपने पर OnStart
, इस पद्धति को कॉल करें:
public override void OnStart()
{
DebugMode();
/* ... do the rest */
}
वहां, कोड केवल डीबग बिल्ड के दौरान सक्षम किया जाएगा। जबकि आपके पास, यह सेवा डिबगिंग के लिए एक अलग बिल्ड कॉन्फ़िगरेशन बनाने के लिए उपयोगी हो सकता है।
मुझे यह भी लगता है कि सामान्य निष्पादन के लिए एक अलग "संस्करण" होना और एक सेवा के रूप में जाने का रास्ता है, लेकिन क्या वास्तव में उस उद्देश्य के लिए एक अलग कमांड लाइन स्विच समर्पित करना आवश्यक है?
क्या आप ऐसा नहीं कर सकते:
public static int Main(string[] args)
{
if (!Environment.UserInteractive)
{
// Startup as service.
}
else
{
// Startup as application
}
}
इसका "लाभ" होगा, कि आप अपने ऐप को डबलक्लिक के माध्यम से शुरू कर सकते हैं (ठीक है, अगर आपको वास्तव में इसकी आवश्यकता है) और यह कि आप F5विजुअल स्टूडियो में हिट कर सकते हैं (उस /console
विकल्प को शामिल करने के लिए प्रोजेक्ट सेटिंग्स को संशोधित करने की आवश्यकता के बिना )।
तकनीकी रूप से, Environment.UserInteractive
यदि WSF_VISIBLE
ध्वज को वर्तमान विंडो स्टेशन के लिए सेट किया गया है , तो जांच करता है, लेकिन क्या कोई अन्य कारण है जहां वह false
(गैर-संवादात्मक) सेवा के रूप में चलाया जा रहा है?
System.Diagnostics.Debugger.IsAttached
इसके बजाय उपयोग कर सकते हैं Environment.UserInteractive
।
जब मैंने कुछ सप्ताह पहले एक नई सेवा परियोजना की स्थापना की तो मुझे यह पद मिला। हालांकि, कई शानदार सुझाव हैं, फिर भी मुझे वह समाधान नहीं मिला जो मैं चाहता था: सेवा वर्गों को कॉल करने की संभावना ' OnStart
और सेवा वर्गों में OnStop
बिना किसी संशोधन के तरीके।
समाधान मैं Environment.Interactive
चुनिंदा चल मोड का उपयोग करता हूं , जैसा कि इस पोस्ट के अन्य उत्तरों द्वारा सुझाया गया है।
static void Main()
{
ServiceBase[] servicesToRun;
servicesToRun = new ServiceBase[]
{
new MyService()
};
if (Environment.UserInteractive)
{
RunInteractive(servicesToRun);
}
else
{
ServiceBase.Run(servicesToRun);
}
}
RunInteractive
सहायक प्रतिबिंब का उपयोग करता है की रक्षा की कॉल करने के लिए OnStart
और OnStop
तरीके:
static void RunInteractive(ServiceBase[] servicesToRun)
{
Console.WriteLine("Services running in interactive mode.");
Console.WriteLine();
MethodInfo onStartMethod = typeof(ServiceBase).GetMethod("OnStart",
BindingFlags.Instance | BindingFlags.NonPublic);
foreach (ServiceBase service in servicesToRun)
{
Console.Write("Starting {0}...", service.ServiceName);
onStartMethod.Invoke(service, new object[] { new string[] { } });
Console.Write("Started");
}
Console.WriteLine();
Console.WriteLine();
Console.WriteLine(
"Press any key to stop the services and end the process...");
Console.ReadKey();
Console.WriteLine();
MethodInfo onStopMethod = typeof(ServiceBase).GetMethod("OnStop",
BindingFlags.Instance | BindingFlags.NonPublic);
foreach (ServiceBase service in servicesToRun)
{
Console.Write("Stopping {0}...", service.ServiceName);
onStopMethod.Invoke(service, null);
Console.WriteLine("Stopped");
}
Console.WriteLine("All services stopped.");
// Keep the console alive for a second to allow the user to see the message.
Thread.Sleep(1000);
}
यह सभी आवश्यक कोड है, लेकिन मैंने स्पष्टीकरण के साथ वॉकथ्रू भी लिखा ।
walk through
) यह सुनिश्चित करने के लिए है कि आप परियोजना के गुणों में जाते हैं और Console Application
संकलन करने और चलाने के लिए आउटपुट प्रकार को बदलने से पहले। इसे खोजो Project Properties -> Application -> Output type -> Console Application
। इसके अलावा, इसके लिए मेरे लिए ठीक से काम करने के लिए मैंने start
कमांड का उपयोग करके एप्लिकेशन को चलाने के लिए समाप्त कर दिया । Ex: C:\"my app name.exe" -service
मेरे लिए काम नहीं करेगा। इसके बजाय मैंने इस्तेमाल कियाC:\start /wait "" "my app name.exe" -service
कभी-कभी यह विश्लेषण करना महत्वपूर्ण है कि सेवा की शुरुआत के दौरान क्या हो रहा है । प्रक्रिया में संलग्न होने से यहां मदद नहीं मिलती है, क्योंकि आप डिबगर संलग्न करने के लिए पर्याप्त जल्दी नहीं हैं, जबकि सेवा शुरू हो रही है।
संक्षिप्त उत्तर है, मैं यह करने के लिए कोड की 4 पंक्तियों का उपयोग कर रहा हूं :
#if DEBUG
base.RequestAdditionalTime(600000); // 600*1000ms = 10 minutes timeout
Debugger.Launch(); // launch and attach debugger
#endif
इन्हें OnStart
सेवा की विधि में निम्नानुसार डाला गया है:
protected override void OnStart(string[] args)
{
#if DEBUG
base.RequestAdditionalTime(600000); // 10 minutes timeout for startup
Debugger.Launch(); // launch and attach debugger
#endif
MyInitOnstart(); // my individual initialization code for the service
// allow the base class to perform any work it needs to do
base.OnStart(args);
}
उन लोगों के लिए जिन्होंने इसे पहले नहीं किया है, मैंने नीचे विस्तृत संकेत शामिल किए हैं , क्योंकि आप आसानी से फंस सकते हैं। निम्न संकेत विंडोज 7x64 और विज़ुअल स्टूडियो 2010 टीम संस्करण को संदर्भित करते हैं , लेकिन अन्य वातावरणों के लिए भी मान्य होना चाहिए।
महत्वपूर्ण: "मैनुअल" मोड में सेवा को तैनात करें (या तो InstallUtil
वीएस कमांड प्रॉम्प्ट से उपयोगिता का उपयोग करें या आपके द्वारा तैयार किए गए सेवा इंस्टॉलर प्रोजेक्ट को चलाएं)। सेवा शुरू करने से पहले विज़ुअल स्टूडियो खोलें और सेवा के स्रोत कोड वाले समाधान को लोड करें - अतिरिक्त ब्रेकप्वाइंट सेट करें जैसा कि आपको विज़ुअल स्टूडियो में उनकी आवश्यकता है - फिर सेवा नियंत्रण कक्ष के माध्यम से सेवा शुरू करें ।
वजह से Debugger.Launch
कोड, यह एक संवाद का कारण होगा "एक माइक्रोसॉफ्ट .NET फ्रेमवर्क अपवाद में हुई बिना क्रिया Servicename.exe ।" उपस्थित होना। स्क्रीनशॉट में दिखाए अनुसार क्लिक करें : Yes, debug Servicename.exe
बाद में, विंडोज 7 यूएसी में escp तौर पर आप व्यवस्थापक क्रेडेंशियल दर्ज करने के लिए संकेत दे सकते हैं। उन्हें दर्ज करें और आगे बढ़ें Yes:
उसके बाद, प्रसिद्ध विज़ुअल स्टूडियो जस्ट-इन-टाइम डीबगर विंडो दिखाई देती है। यह आपसे पूछता है कि क्या आप डिले हुए डीबगर का उपयोग करके डिबग करना चाहते हैं। क्लिक करने से पहले Yes, यह चुनें कि आप एक नया उदाहरण (दूसरा विकल्प) नहीं खोलना चाहते - एक नया उदाहरण यहाँ मददगार नहीं होगा, क्योंकि स्रोत कोड प्रदर्शित नहीं होगा। इसलिए आप इसके बजाय पहले खोले गए विजुअल स्टूडियो उदाहरण का चयन करें:
आपके द्वारा क्लिक किएYes जाने के बाद , थोड़ी देर के बाद विजुअल स्टूडियो उस पंक्ति में पीले रंग के तीर को दिखाएगा जहाँ Debugger.Launch
कथन है और आप अपने कोड (विधि MyInitOnStart
, जिसमें आपका आरंभीकरण है) को डीबग करने में सक्षम हैं ।
दबाने पर F5तुरंत निष्पादन जारी रहता है, जब तक कि आपके द्वारा तैयार किए गए अगले ब्रेकपॉइंट तक नहीं पहुंच जाता।
संकेत: सेवा चालू रखने के लिए, डीबग का चयन करें -> सभी को अलग करें । यह आपको सेवा के साथ संचार करने वाले ग्राहक को सही ढंग से शुरू करने के बाद चलाने की अनुमति देता है और आप स्टार्टअप कोड को डीबग करना समाप्त कर देते हैं। यदि आप Shift+F5 (डिबगिंग रोकें) दबाते हैं , तो यह सेवा समाप्त कर देगा। ऐसा करने के बजाय, आपको इसे रोकने के लिए सेवा नियंत्रण कक्ष का उपयोग करना चाहिए ।
नोट है कि
यदि आप एक रिलीज़ बनाते हैं , तो डिबग कोड स्वचालित रूप से हटा दिया जाता है और सेवा सामान्य रूप से चलती है।
मैं उपयोग कर रहा हूं Debugger.Launch()
, जो डिबगर शुरू और संलग्न करता है । मैंने भी परीक्षण Debugger.Break()
किया है, जो काम नहीं किया , क्योंकि सेवा के शुरू होने पर अभी तक कोई डिबगर संलग्न नहीं है (जिसके कारण "त्रुटि 1067: प्रक्रिया अनपेक्षित रूप से समाप्त हो गई है" )।
RequestAdditionalTime
सेवा के स्टार्टअप के लिए एक लंबा समय निर्धारित करता है (यह स्वयं कोड में देरी नहीं कर रहा है, लेकिन तुरंत Debugger.Launch
बयान के साथ जारी रहेगा )। अन्यथा सेवा शुरू करने के लिए डिफ़ॉल्ट समय सीमा बहुत कम है और यदि आप base.Onstart(args)
डिबगर से बहुत जल्दी कॉल नहीं करते हैं तो सेवा शुरू करना विफल हो जाता है । व्यावहारिक रूप से, 10 मिनट का समय बचा जाता है कि आप संदेश देखते हैं " डिबगर शुरू होने के तुरंत बाद सेवा ने जवाब नहीं दिया ..." ।
एक बार जब आप इसकी अभ्यस्त हो जाते हैं, तो यह विधि बहुत आसान है क्योंकि इसके लिए आपको मौजूदा सेवा कोड में 4 लाइनों को जोड़ने की आवश्यकता होती है , जिससे आप नियंत्रण और डिबग प्राप्त कर सकते हैं।
base.RequestAdditionalTime(600000)
सेवा नियंत्रण को 10 मिनट के लिए सेवा समाप्त करने से रोक देगा यदि वह base.OnStart(args)
उस समय के भीतर नहीं बुलाता है )। इसके अलावा, मुझे याद है कि यदि आप थोड़ी देर के बाद व्यवस्थापक क्रेडेंशियल दर्ज नहीं करते हैं तो यूएसी गर्भपात भी कर देगा (मुझे नहीं पता कि कितने सेकंड में ठीक है, लेकिन मुझे लगता है कि आपको इसे एक मिनट के भीतर दर्ज करना होगा, अन्यथा यूएसी गर्भपात करें) , जो डिबग सत्र को समाप्त कर देगा।
आमतौर पर मैं जो करता हूं, वह सेवा के तर्क को एक अलग वर्ग में शामिल करता है और एक 'धावक' वर्ग से शुरू करता है। यह धावक वर्ग वास्तविक सेवा या सिर्फ एक सांत्वना अनुप्रयोग हो सकता है। तो आपके समाधान में (कम से कम) 3 परियोजनाएँ हैं:
/ConsoleRunner
/....
/ServiceRunner
/....
/ApplicationLogic
/....
फैबियो स्कोपेल का यह यूट्यूब वीडियो बताता है कि विंडोज सेवा को कैसे अच्छी तरह से डीबग करना है ... इसे करने की वास्तविक विधि वीडियो में 4:45 से शुरू होती है ...
यहाँ वीडियो में समझाया गया कोड है ... आपके Program.cs फ़ाइल में, डीबग अनुभाग के लिए सामान जोड़ें ...
namespace YourNamespace
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
#if DEBUG
Service1 myService = new Service1();
myService.OnDebug();
System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
#else
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new Service1()
};
ServiceBase.Run(ServicesToRun);
#endif
}
}
}
अपनी Service1.cs फ़ाइल में, OnDebug () विधि जोड़ें ...
public Service1()
{
InitializeComponent();
}
public void OnDebug()
{
OnStart(null);
}
protected override void OnStart(string[] args)
{
// your code to do something
}
protected override void OnStop()
{
}
यह काम किस प्रकार करता है
मूल रूप से आपको एक public void OnDebug()
कॉल करना होगा जो कि OnStart(string[] args)
संरक्षित है और बाहर सुलभ नहीं है। void Main()
इस कार्यक्रम के साथ जोड़ा जाता है #if
साथ पूर्वप्रक्रमक #DEBUG
।
दृश्य स्टूडियो परिभाषित करता है DEBUG
कि क्या परियोजना डिबग मोड में संकलित है। यह डिबग अनुभाग (नीचे) को निष्पादित करने की अनुमति देगा जब स्थिति सही हो।
Service1 myService = new Service1();
myService.OnDebug();
System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
और यह एक कंसोल एप्लिकेशन की तरह ही चलेगा, एक बार जब चीजें ठीक हो जाती हैं तो आप मोड को बदल सकते हैं Release
और नियमित else
अनुभाग तर्क को ट्रिगर करेगा
अपडेट करें
यह तरीका सबसे आसान है:
http://www.codeproject.com/KB/dotnet/DebugWinServices.aspx
मैं अपना मूल उत्तर पोस्टीरिटी के लिए नीचे छोड़ता हूं।
मेरी सेवाओं में एक वर्ग है जो टाइमर को एनकैप्सुलेट करता है क्योंकि मैं चाहता हूं कि सेवा नियमित अंतराल पर जांच करे कि क्या इसके लिए कोई काम करना है।
हम सर्विस स्टार्ट-अप के दौरान क्लास को नया बनाते हैं और StartEventLoop () कहते हैं। (इस क्लास को आसानी से कंसोल ऐप से भी इस्तेमाल किया जा सकता है।)
इस डिज़ाइन का अच्छा दुष्परिणाम यह है कि जिन तर्कों के साथ आपने टाइमर सेट किया है उनका उपयोग सेवा वास्तव में काम शुरू होने से पहले देरी के लिए किया जा सकता है, ताकि आपके पास डिबगर मैन्युअल रूप से संलग्न करने का समय हो।
ps डिबगर को मैन्युअल रूप से रनिंग प्रक्रिया में कैसे संलग्न किया जाए ...?
using System;
using System.Threading;
using System.Configuration;
public class ServiceEventHandler
{
Timer _timer;
public ServiceEventHandler()
{
// get configuration etc.
_timer = new Timer(
new TimerCallback(EventTimerCallback)
, null
, Timeout.Infinite
, Timeout.Infinite);
}
private void EventTimerCallback(object state)
{
// do something
}
public void StartEventLoop()
{
// wait a minute, then run every 30 minutes
_timer.Change(TimeSpan.Parse("00:01:00"), TimeSpan.Parse("00:30:00");
}
}
इसके अलावा, मैं निम्नलिखित (पहले के उत्तरों में पहले से ही उल्लेख किया गया था लेकिन सशर्त संकलक [#if] झंडे के साथ रिलीज रिलीज से बचने में मदद करने के लिए) करता था।
मैंने इसे इस तरह से करना बंद कर दिया क्योंकि कभी-कभी हम रिलीज़ में निर्माण करना भूल जाते हैं और क्लाइंट डेमो (शर्मनाक!) पर चलने वाले ऐप में डिबगर ब्रेक होता है।
#if DEBUG
if (!System.Diagnostics.Debugger.IsAttached)
{
System.Diagnostics.Debugger.Break();
}
#endif
// do something
पूरा करने के लिए अधिक से अधिक 30 मिनट लगते हैं?
static void Main()
{
#if DEBUG
// Run as interactive exe in debug mode to allow easy
// debugging.
var service = new MyService();
service.OnStart(null);
// Sleep the main thread indefinitely while the service code
// runs in .OnStart
Thread.Sleep(Timeout.Infinite);
#else
// Run normally as service in release mode.
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]{ new MyService() };
ServiceBase.Run(ServicesToRun);
#endif
}
OnStart
है protected
और आप पहुँच स्तर को संशोधित नहीं कर सकते हैं :(
मैं जो कुछ भी करता था वह कमांड लाइन स्विच होता था जो प्रोग्राम को सेवा के रूप में या एक नियमित अनुप्रयोग के रूप में शुरू करता था। फिर, अपने आईडीई में मैं स्विच सेट करूंगा ताकि मैं अपने कोड के माध्यम से कदम रख सकूं।
कुछ भाषाओं के साथ आप वास्तव में यह पता लगा सकते हैं कि यह IDE में चल रहा है या नहीं और यह स्विच अपने आप काम करता है।
आप किस भाषा का उपयोग कर रहे हैं?
TopShelf लाइब्रेरी का उपयोग करें ।
एक कंसोल एप्लिकेशन बनाएं फिर अपने मेन में सेटअप कॉन्फ़िगर करें
class Program
{
static void Main(string[] args)
{
HostFactory.Run(x =>
{
// setup service start and stop.
x.Service<Controller>(s =>
{
s.ConstructUsing(name => new Controller());
s.WhenStarted(controller => controller.Start());
s.WhenStopped(controller => controller.Stop());
});
// setup recovery here
x.EnableServiceRecovery(rc =>
{
rc.RestartService(delayInMinutes: 0);
rc.SetResetPeriod(days: 0);
});
x.RunAsLocalSystem();
});
}
}
public class Controller
{
public void Start()
{
}
public void Stop()
{
}
}
अपनी सेवा को डीबग करने के लिए, बस दृश्य स्टूडियो में F5 मारा।
सेवा स्थापित करने के लिए, cmd में टाइप करें "कंसोल। Exe स्थापित करें"
तब आप विंडो सेवा प्रबंधक में सेवा शुरू और बंद कर सकते हैं।
मुझे लगता है कि यह निर्भर करता है कि आप किस ओएस का उपयोग कर रहे हैं, विस्टा सत्रों के बीच अलगाव के कारण, सेवाओं से जुड़ना बहुत कठिन है।
मेरे द्वारा पूर्व में उपयोग किए गए दो विकल्प हैं:
उम्मीद है की यह मदद करेगा।
मैं अपनी सेवा के हर पहलू को डिबेट करने में सक्षम होना पसंद करता हूं, जिसमें ऑनस्टार्ट () में कोई भी इनिशियलाइज़ेशन शामिल है, जबकि अभी भी इसे एससीएम के ढांचे के भीतर पूर्ण सेवा व्यवहार के साथ निष्पादित किया जाता है ... कोई "कंसोल" या "ऐप" मोड नहीं।
मैं दूसरी परियोजना बनाकर, उसी परियोजना में, डिबगिंग के लिए उपयोग करता हूं। डिबग सेवा, जब सामान्य रूप से शुरू की जाती है (यानी सेवाओं एमएमसी प्लगइन में), सेवा होस्ट प्रक्रिया बनाती है। यह आपको डिबगर संलग्न करने के लिए एक प्रक्रिया देता है भले ही आपने अभी तक अपनी वास्तविक सेवा शुरू नहीं की हो। डिबगर को प्रक्रिया में संलग्न करने के बाद, अपनी वास्तविक सेवा शुरू करें और आप ऑनस्टार्ट () सहित सेवा जीवनचक्र में कहीं भी इसे तोड़ सकते हैं।
क्योंकि इसमें बहुत न्यूनतम कोड घुसपैठ की आवश्यकता होती है, डिबग सेवा को आसानी से आपकी सेवा सेटअप परियोजना में शामिल किया जा सकता है, और कोड की एक पंक्ति को टिप्पणी करके और एकल प्रोजेक्ट इंस्टॉलर को हटाकर आसानी से आपके उत्पादन रिलीज़ से हटा दिया जाता है।
विवरण:
1) यह मानते हुए कि आप लागू कर रहे हैं MyService
, भी बनाएँ MyServiceDebug
। दोनों को ServiceBase
सरणी में इस Program.cs
तरह जोड़ें :
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new MyService(),
new MyServiceDebug()
};
ServiceBase.Run(ServicesToRun);
}
2) सेवा परियोजना के लिए प्रोजेक्ट इंस्टॉलर में वास्तविक सेवा और डिबग सेवा जोड़ें:
जब आप सेवा प्रोजेक्ट आउटपुट को सेवा के लिए सेटअप प्रोजेक्ट में जोड़ते हैं तो दोनों सेवाएं (वास्तविक और डीबग) शामिल हो जाती हैं। स्थापना के बाद, दोनों सेवाएं service.msc MMC प्लगइन में दिखाई देंगी।
3) MMC में डिबग सेवा शुरू करें।
4) विजुअल स्टूडियो में, डिबगर को डीबग सेवा द्वारा शुरू की गई प्रक्रिया से जोड़ते हैं।
5) वास्तविक सेवा शुरू करें और डिबगिंग का आनंद लें।
जब मैं एक सेवा लिखता हूं तो मैं एक dll परियोजना में सभी सेवा तर्क रखता हूं और दो "मेजबान" बनाता हूं जो इस dll में कॉल करते हैं, एक विंडोज सेवा है और दूसरा एक कमांड लाइन एप्लिकेशन है।
मैं डिबगिंग के लिए कमांड लाइन एप्लिकेशन का उपयोग करता हूं और डिबगर को वास्तविक सेवा में केवल उन बगों के लिए संलग्न करता हूं जिन्हें मैं कमांड लाइन एप्लिकेशन में पुन: पेश नहीं कर सकता।
मैं आपको इस दृष्टिकोण का उपयोग करता हूं बस याद रखें कि आपको वास्तविक सेवा में चलते समय सभी कोड का परीक्षण करना होगा, जबकि कमांड लाइन टूल एक अच्छा डिबगिंग सहायता है यह एक अलग वातावरण है और यह वास्तव में एक वास्तविक सेवा की तरह व्यवहार नहीं करता है।
Windows सेवा को विकसित और डीबग करते समय मैं आमतौर पर / कंसोल स्टार्टअप पैरामीटर को जोड़कर और इसे चेक करके कंसोल एप्लिकेशन के रूप में चलाता हूं। जीवन को बहुत आसान बना देता है।
static void Main(string[] args) {
if (Console.In != StreamReader.Null) {
if (args.Length > 0 && args[0] == "/console") {
// Start your service work.
}
}
}
Windows सेवाओं को डीबग करने के लिए मैं GFlags और regedit द्वारा बनाई गई एक .reg फ़ाइल को संयोजित करता हूं।
या निम्नलिखित स्निपेट को सहेजें और वांछित निष्पादन योग्य नाम के साथ servicename.exe को बदलें।
debugon.reg:
Windows रजिस्ट्री संपादक संस्करण 5.00 [HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows NT \ CurrentVersion \ Image फ़ाइल निष्पादन विकल्प \ servicename.exe] "GlobalFlag" = "0x00000000" "डीबगर" = "vsjitdebugger.exe"
debugoff.reg:
Windows रजिस्ट्री संपादक संस्करण 5.00 [HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows NT \ CurrentVersion \ Image फ़ाइल निष्पादन विकल्प \ servicename.exe] "GlobalFlag" = "0x00000000"
रूटीन छोटे-सामान की प्रोग्रामिंग के लिए मैंने अपनी सेवा को आसानी से डीबग करने के लिए एक बहुत ही सरल ट्रिक की है:
सेवा के शुरू होने पर, मैं एक कमांड लाइन पैरामीटर "/ डिबग" के लिए जांच करता हूं। यदि इस पैरामीटर के साथ सेवा को कॉल किया जाता है, तो मैं सामान्य सेवा स्टार्टअप नहीं करता हूं, लेकिन इसके बजाय सभी श्रोताओं को शुरू करें और बस एक संदेशबॉक्स प्रदर्शित करें "प्रगति में डिबग, समाप्त करने के लिए ठीक दबाएं"।
इसलिए यदि मेरी सेवा सामान्य तरीके से शुरू की जाती है, तो यह सेवा के रूप में शुरू होगी, अगर इसे कमांड लाइन पैरामीटर / डीबग के साथ शुरू किया जाता है, तो यह एक सामान्य कार्यक्रम की तरह काम करेगा।
VS में मैं डिबगिंग पैरामीटर के रूप में सिर्फ / डिबग जोड़ूंगा और सीधे सेवा कार्यक्रम शुरू करूंगा।
इस तरह मैं सबसे छोटी तरह की समस्याओं के लिए आसानी से डिबग कर सकता हूं। बेशक, कुछ सामान को अभी भी सेवा के रूप में डिबग करना होगा, लेकिन 99% के लिए यह काफी अच्छा है।
मैं JOP के उत्तर पर भिन्नता का उपयोग करता हूं। कमांड लाइन मापदंडों का उपयोग करके आप आईडीई में प्रोजेक्ट गुणों के साथ या विंडोज सेवा प्रबंधक के माध्यम से डिबगिंग मोड सेट कर सकते हैं।
protected override void OnStart(string[] args)
{
if (args.Contains<string>("DEBUG_SERVICE"))
{
Debugger.Break();
}
...
}
मौजूदा विंडोज सर्विस प्रोग्राम पर परेशानी की शूटिंग के लिए, अन्य लोगों द्वारा सुझाए गए अनुसार 'डीबगर.ब्रिक ()' का उपयोग करें।
नए विंडोज सर्विस प्रोग्राम के लिए, मैं जेम्स माइकल हरे की विधि http://geekswithblogs.net/BlackRabbitCoder/archive/2011/03/01/c-toolbox-debug-able-self-installable -windows-service-template- का उपयोग करने का सुझाव दूंगा redux.aspx
बस अपना डिबगर लंच कहीं भी डाल दें और स्टार्टअप पर विजुअलस्टडियो संलग्न करें
#if DEBUG
Debugger.Launch();
#endif
इसके अलावा, आपको वीएस को प्रशासक के रूप में शुरू करने की आवश्यकता है और आपको अनुमति देने की आवश्यकता है, कि एक प्रक्रिया को एक अलग उपयोगकर्ता द्वारा डिबग किया जा सकता है (जैसा कि यहां बताया गया है ):
reg add "HKCR\AppID{E62A7A31-6025-408E-87F6-81AEB0DC9347}" /v AppIDFlags /t REG_DWORD /d 8 /f
नई सेवा ऐप बनाने के लिए Windows सेवा टेम्पलेट C # प्रोजेक्ट का उपयोग करें https://github.com/HarpyWar/windows-service-tplplate
कंसोल / सर्विस मोड का स्वतः पता लगाया जाता है, आपकी सेवा के ऑटो इंस्टॉलर / इंस्टॉलर और कई सबसे अधिक उपयोग की जाने वाली सुविधाएँ शामिल हैं।
यहां वह सरल विधि है जिसका उपयोग मैंने सेवा का परीक्षण करने के लिए किया, बिना किसी अतिरिक्त "डीबग" के तरीकों के साथ और एकीकृत वीएस यूनिट टेस्ट के साथ।
[TestMethod]
public void TestMyService()
{
MyService fs = new MyService();
var OnStart = fs.GetType().BaseType.GetMethod("OnStart", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
OnStart.Invoke(fs, new object[] { null });
}
// As an extension method
public static void Start(this ServiceBase service, List<string> parameters)
{
string[] par = parameters == null ? null : parameters.ToArray();
var OnStart = service.GetType().GetMethod("OnStart", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
OnStart.Invoke(service, new object[] { par });
}
static class Program
{
static void Main()
{
#if DEBUG
// TODO: Add code to start application here
// //If the mode is in debugging
// //create a new service instance
Service1 myService = new Service1();
// //call the start method - this will start the Timer.
myService.Start();
// //Set the Thread to sleep
Thread.Sleep(300000);
// //Call the Stop method-this will stop the Timer.
myService.Stop();
#else
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new Service1()
};
ServiceBase.Run(ServicesToRun);
#endif
}
}
डिबगिंग करने के लिए आपके पास दो विकल्प हैं।
कृपया इस विषय को देखें जो मैंने इस विषय के लिए बनाया था।
बस पेस्ट करें
Debugger.Break();
कोई भी जहाँ आप कोड में।
उदाहरण के लिए ,
internal static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
private static void Main()
{
Debugger.Break();
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new Service1()
};
ServiceBase.Run(ServicesToRun);
}
}
Debugger.Break();
जब आप अपना प्रोग्राम चलाएंगे तो यह हिट हो जाएगा ।
सबसे अच्छा विकल्प ' System.Diagnostics ' नामस्थान का उपयोग करना है ।
डिबग मोड और रिलीज़ मोड के लिए यदि ब्लॉक और डिबग स्टूडियो में रिलीज़ मोड के बीच स्विच करने के लिए नीचे दिखाया गया है, तो अपना कोड संलग्न करें,
#if DEBUG // for debug mode
**Debugger.Launch();** //debugger will hit here
foreach (var job in JobFactory.GetJobs())
{
//do something
}
#else // for release mode
**Debugger.Launch();** //debugger will hit here
// write code here to do something in Release mode.
#endif