উইন্ডোজ সার্ভিস কন্ট্রোল ম্যানেজারের মাধ্যমে পরিষেবাটি শুরু করার পরে ডিবাগারটিকে থ্রেডে সংযুক্ত করার চেয়ে কি কোডের মাধ্যমে পদক্ষেপ নেওয়ার সহজ উপায় আছে? এটি এক ধরণের জটিল এবং আমি ভাবছি যে আরও সহজ সরল পদ্ধতি আছে কিনা।
উইন্ডোজ সার্ভিস কন্ট্রোল ম্যানেজারের মাধ্যমে পরিষেবাটি শুরু করার পরে ডিবাগারটিকে থ্রেডে সংযুক্ত করার চেয়ে কি কোডের মাধ্যমে পদক্ষেপ নেওয়ার সহজ উপায় আছে? এটি এক ধরণের জটিল এবং আমি ভাবছি যে আরও সহজ সরল পদ্ধতি আছে কিনা।
উত্তর:
আমি যদি দ্রুত পরিষেবাটি ডিবাগ করতে চাই তবে আমি কেবল একটি এ ড্রপ করব 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
কমান্ডটি ব্যবহার করে অ্যাপ্লিকেশনটি চালাতে পেরেছি । প্রাক্তন: 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
একটি ডায়ালগের কারণ ঘটবে "একটি আনহানডেল মাইক্রোসফ্ট। নেট ফ্রেমওয়ার্ক ব্যতিক্রম সার্ভিসনেম.এক্সেতে ঘটেছে " " প্রদর্শিত. স্ক্রিনশটে প্রদর্শিত হিসাবে ক্লিক করুন : Yes, debug Servicename.exe
এরপরে উইন্ডোজ 7 ইউএসি-তে আপনাকে অ্যাডমিন শংসাপত্রগুলি প্রবেশ করতে অনুরোধ জানাতে পারে। এগুলি প্রবেশ করুন এবং এর সাথে এগিয়ে যান Yes:
এর পরে, সুপরিচিত ভিজ্যুয়াল স্টুডিও জাস্ট-ইন-টাইম ডিবাগার উইন্ডোটি উপস্থিত হবে। এটি আপনাকে জিজ্ঞাসা করে যে আপনি যদি নির্বাচিত ডিবাগারটি ব্যবহার করে ডিবাগ করতে চান। ক্লিক করার আগে Yes, নির্বাচন যে আপনার একটি নতুন দৃষ্টান্ত খুলতে চাই না (2nd বিকল্প) - একটি নতুন দৃষ্টান্ত এখানে সহায়ক হবে না, কারণ সোর্স কোড প্রদর্শিত নাও হতে হবে। সুতরাং আপনি এর পরিবর্তে ভিজ্যুয়াল স্টুডিও উদাহরণটি নির্বাচন করেছেন:
আপনি ক্লিক করারYes পরে , কিছুক্ষণ পরে ভিজ্যুয়াল স্টুডিওটি Debugger.Launch
বিবৃতিটি লাইনটিতে ডানদিকে হলুদ তীরটি প্রদর্শন করবে এবং আপনি আপনার কোডটি ডিবাগ করতে সক্ষম হবেন (পদ্ধতি MyInitOnStart
, যা আপনার সূচনাটি ধারণ করে)।
F5আপনার প্রস্তুত পরবর্তী ব্রেকপয়েন্টটি পৌঁছানো অবধি অবধি চাপ কার্যকর করা অব্যাহত থাকে ।
ইঙ্গিত: পরিষেবাটি চলমান রাখতে, ডিবাগ -> সমস্ত বিচ্ছিন্ন নির্বাচন করুন । এটি সঠিকভাবে শুরু হওয়ার পরে এবং আপনি স্টার্টআপ কোডটি ডিবাগিং শেষ করার পরে পরিষেবাটির সাথে যোগাযোগ করার কোনও ক্লায়েন্ট চালানোর অনুমতি দেয়। আপনি যদি Shift+F5 টিপুন (ডিবাগিং বন্ধ করুন), এটি পরিষেবাটি শেষ করবে। এটি না করে এটি বন্ধ করার জন্য আপনার পরিষেবা নিয়ন্ত্রণ প্যানেলটি ব্যবহার করা উচিত ।
নোট যে
আপনি যদি একটি রিলিজ তৈরি করেন তবে ডিবাগ কোডটি স্বয়ংক্রিয়ভাবে সরানো হবে এবং পরিষেবাটি সাধারণত চলমান runs
আমি ব্যবহার করছি Debugger.Launch()
, যা একটি ডিবাগার শুরু করে এবং সংযুক্ত করে । আমি এটিও পরীক্ষা করে দেখেছি Debugger.Break()
, যা কার্যকর হয়নি , কারণ পরিষেবাটি আরম্ভ করার সময় এখনও কোনও ডিবাগার সংযুক্ত নেই ( "ত্রুটি 1067: প্রক্রিয়াটি অপ্রত্যাশিতভাবে শেষ হয়ে গেছে।" )।
RequestAdditionalTime
পরিষেবাটি শুরু করার জন্য দীর্ঘ সময়সীমা নির্ধারণ করে (এটি কোডটি নিজেই বিলম্ব করছে না , তবে অবিলম্বে Debugger.Launch
বিবৃতি দিয়ে চালিয়ে যাবে )। অন্যথায় পরিষেবাটি শুরু করার জন্য ডিফল্ট সময়সীমা খুব কম এবং আপনি base.Onstart(args)
ডিবাগার থেকে দ্রুত কল না করলে পরিষেবাটি ব্যর্থ হয় । ব্যবহারিকভাবে, 10 মিনিটের সময়সীমা এড়ানো যায় যে আপনি ডিবাগারটি শুরু হওয়ার সাথে সাথে "পরিষেবাটি সাড়া দেয়নি ..." বার্তাটি দেখে see
একবার আপনি এটির অভ্যস্ত হয়ে উঠলে, এই পদ্ধতিটি খুব সহজ কারণ এটির জন্য আপনাকে একটি বিদ্যমান সার্ভিস কোডে 4 টি লাইন যুক্ত করতে হবে, এটি আপনাকে দ্রুত নিয়ন্ত্রণ এবং ডিবাগ করার অনুমতি দেয়।
base.RequestAdditionalTime(600000)
পরিষেবা নিয়ন্ত্রণটি 10 মিনিটের জন্য পরিষেবাটি যদি base.OnStart(args)
সেই সময়সীমের মধ্যে কল না করে তবে এটি বন্ধ করতে বাধা দেবে )। এগুলি ছাড়াও, আমি মনে রাখি যে আপনি কিছুক্ষণ পরে অ্যাডমিন শংসাপত্রগুলি প্রবেশ না করালে ইউএসিও বাতিল হয়ে যাবে (ঠিক কত সেকেন্ড ঠিক জানি না তবে আমি মনে করি আপনাকে এটি এক মিনিটের মধ্যে প্রবেশ করতে হবে, অন্যথায় ইউএসি অবরুদ্ধ হয়) , যা ডিবাগ সেশনটি শেষ করে দেবে।
আমি সাধারণত যা করি তা হ'ল পরিষেবার লজিককে আলাদা ক্লাসে সজ্জিত করা এবং এটি একটি 'রানার' ক্লাস থেকে শুরু করা। এই রানার শ্রেণিটি আসল পরিষেবা বা কেবল একটি কনসোল অ্যাপ্লিকেশন হতে পারে। সুতরাং আপনার সমাধানটিতে (কমপক্ষে) 3 টি প্রকল্প রয়েছে:
/ConsoleRunner
/....
/ServiceRunner
/....
/ApplicationLogic
/....
ফ্যাবিও স্কোপেলের এই ইউটিউব ভিডিও ব্যাখ্যা করে যে কীভাবে একটি উইন্ডোজ পরিষেবাটি বেশ সুন্দরভাবে ডিবাগ করা যায় ... ভিডিওটি 4:45 এ শুরু করার এটির আসল পদ্ধতিটি ...
ভিডিওতে কোডটি এখানে ব্যাখ্যা করা হয়েছে ... আপনার প্রোগ্রাম.সি ফাইলগুলিতে, ডিবাগ বিভাগের জন্য স্টাফ যুক্ত করুন ...
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
}
}
}
আপনার সার্ভিস 1 সিএস ফাইলগুলিতে অনডিবগ () পদ্ধতি যুক্ত করুন ...
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
প্রকল্পটি ডিবাগ মোডে সংকলিত থাকলে ভিজ্যুয়াল স্টুডিও সংজ্ঞা দেয় the শর্তটি সত্য হলে এটি ডিবাগ বিভাগকে (নীচে) সম্পাদন করতে দেবে
Service1 myService = new Service1();
myService.OnDebug();
System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
এবং এটি ঠিক একটি কনসোল অ্যাপ্লিকেশনটির মতো চলবে, একবার জিনিস ঠিক হয়ে গেলে আপনি মোড পরিবর্তন করতে পারবেন Release
এবং নিয়মিত else
বিভাগটি যুক্তিটিকে ট্রিগার করবে
হালনাগাদ
এই পদ্ধতিটি এখন পর্যন্ত সবচেয়ে সহজ:
http://www.codeproject.com/KB/dotnet/DebugWinServices.aspx
আমি উত্তরসূত্রের জন্য নীচে আমার মূল উত্তরটি রেখেছি।
আমার পরিষেবাগুলিতে এমন একটি ক্লাস থাকে যা একটি টাইমারকে ঘিরে রাখে আমি চাই পরিষেবাটি নিয়মিত বিরতিতে পরীক্ষা করার জন্য এটির কোনও কাজ আছে কিনা want
আমরা ক্লাসটি নতুন করি এবং সার্ভিস স্টার্ট-আপ চলাকালীন স্টার্টইভেন্টলুপ () কল করি। (এই ক্লাসটি সহজেই কনসোল অ্যাপ থেকেও ব্যবহার করা যেতে পারে))
এই নকশার দুর্দান্ত পার্শ্ব-প্রতিক্রিয়াটি হ'ল আপনি যে আর্গুমেন্টগুলির সাহায্যে টাইমারটি সেট করেছেন সেগুলি পরিষেবাটি কার্যত কাজ শুরু করার আগেই বিলম্ব হতে পারে, যাতে আপনার নিজের হাতে ডিবাগার সংযুক্ত করার সময় থাকতে পারে।
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 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
এবং আপনি অ্যাক্সেসের স্তরটি পরিবর্তন করতে পারবেন না :(
আমি যা করতাম তা ছিল একটি কমান্ড লাইন সুইচ যা কোনও পরিষেবা হিসাবে বা নিয়মিত অ্যাপ্লিকেশন হিসাবে প্রোগ্রামটি শুরু করে। তারপরে, আমার আইডিইতে আমি স্যুইচটি সেট করব যাতে আমি আমার কোডটি দিয়ে যেতে পারি।
কিছু ভাষার সাহায্যে আপনি সনাক্ত করতে পারবেন এটি আইডিইতে চলছে কিনা এবং স্বয়ংক্রিয়ভাবে এই স্যুইচটি সম্পাদন করে।
আপনি কোন ভাষা ব্যবহার করছেন?
টপশেল্ফটি ব্যবহার করুন লাইব্রেরি ।
একটি কনসোল অ্যাপ্লিকেশন তৈরি করুন তারপরে আপনার মেইনে সেটআপ কনফিগার করুন
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 চাপুন।
পরিষেবাটি ইনস্টল করতে, সিএমডি টাইপ করুন "কনসোল.এক্সই ইনস্টল"
তারপরে আপনি উইন্ডোজ পরিষেবা পরিচালকের মধ্যে পরিষেবা শুরু এবং বন্ধ করতে পারেন।
আমি মনে করি এটি ওএস আপনি কী ব্যবহার করছেন তার উপর নির্ভর করে, সেশনগুলির মধ্যে পৃথকীকরণের কারণে ভিস্তার পরিষেবাদিগুলির সাথে সংযুক্ত করা আরও শক্ত।
আমি অতীতে দুটি বিকল্প ব্যবহার করেছি:
আশাকরি এটা সাহায্য করবে.
আমি এসসিএম-এর কাঠামোর মধ্যে পুরো পরিষেবা আচরণের সাথে এটি চালিত করার সময়, অন স্টার্ট () এর যে কোনও সূচনা সহ আমার পরিষেবার প্রতিটি দিকই ডিবাগ করতে সক্ষম হতে চাই ... কোনও "কনসোল" বা "অ্যাপ" মোড নেই।
আমি একই প্রকল্পে, ডিবাগিংয়ের জন্য ব্যবহার করতে একটি দ্বিতীয় পরিষেবা তৈরি করে এটি করি। ডিবাগ পরিষেবা, যখন যথারীতি শুরু হয় (যেমন পরিষেবাগুলিতে এমএমসি প্লাগইনে থাকে), পরিষেবা হোস্ট প্রক্রিয়া তৈরি করে। এটি আপনাকে ডিবাগারটি সংযুক্ত করার জন্য একটি প্রক্রিয়া দেয় যদিও আপনি এখনও আপনার আসল পরিষেবাটি শুরু করেননি। প্রক্রিয়াটিতে ডিবাগার সংযুক্ত করার পরে, আপনার আসল পরিষেবাটি শুরু করুন এবং আপনি পরিষেবা স্টাফের মধ্যে অন স্টার্ট () সহ যে কোনও জায়গায় এটি ভেঙে ফেলতে পারেন।
যেহেতু এটি খুব ন্যূনতম কোড অনুপ্রবেশের প্রয়োজন, ডিবাগ পরিষেবাটি সহজেই আপনার পরিষেবা সেটআপ প্রকল্পে অন্তর্ভুক্ত করা যেতে পারে এবং কোনও একক লাইনের কোড মন্তব্য করে এবং একটি একক প্রকল্প ইনস্টলারকে মুছে ফেলে সহজেই আপনার উত্পাদন প্রকাশ থেকে সরানো হয়।
বিবরণ:
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 এমএমসি প্লাগইনে উপস্থিত হবে।
3) এমএমসিতে ডিবাগ পরিষেবা শুরু করুন।
4) ভিজ্যুয়াল স্টুডিওতে, ডিবাগ পরিষেবাটি শুরু হওয়া প্রক্রিয়াটিতে ডিবাগারটি সংযুক্ত করুন।
5) আসল পরিষেবাটি শুরু করুন এবং ডিবাগিং উপভোগ করুন।
আমি যখন কোনও পরিষেবা লিখি তখন আমি সমস্ত পরিষেবা যুক্তিটিকে একটি ডেল প্রকল্পে রাখি এবং দুটি "হোস্ট" তৈরি করি যা এই ডেলটিতে কল করে, একটি হ'ল উইন্ডোজ পরিষেবা এবং অন্যটি হ'ল কমান্ড লাইন অ্যাপ্লিকেশন।
আমি ডিবাগিংয়ের জন্য কমান্ড লাইন অ্যাপ্লিকেশনটি ব্যবহার করি এবং কমান্ড লাইন অ্যাপ্লিকেশনটিতে আমি যে বাগগুলি পুনরুত্পাদন করতে পারি না তার জন্য ডিবাগটিকে সত্যিকারের পরিষেবার সাথে সংযুক্ত করি।
আমি আপনি এই পদ্ধতির ব্যবহারটি কেবল মনে রাখবেন যে সত্যিকারের পরিষেবাতে চলার সময় আপনাকে সমস্ত কোড পরীক্ষা করতে হবে, যখন কমান্ড লাইন সরঞ্জামটি একটি দুর্দান্ত ডিবাগিং সহায়তা এটি ভিন্ন পরিবেশ এবং এটি সত্যিকারের পরিষেবার মতো আচরণ করে না।
উইন্ডোজ পরিষেবাটি বিকাশ ও ডিবাগ করার সময় আমি সাধারণত একটি কনসোল প্রারম্ভিক পরামিতি যুক্ত করে এটি পরীক্ষা করে কনসোল অ্যাপ্লিকেশন হিসাবে চালিত করি। জীবনকে অনেক সহজ করে তোলে।
static void Main(string[] args) {
if (Console.In != StreamReader.Null) {
if (args.Length > 0 && args[0] == "/console") {
// Start your service work.
}
}
}
উইন্ডোজ পরিষেবাদি ডিবাগ করার জন্য আমি জিএফ্লেগ এবং রেজিডিট দ্বারা তৈরি একটি .reg ফাইল একত্রিত করি।
অথবা নিম্নলিখিত স্নিপেটগুলি সংরক্ষণ করুন এবং পছন্দসই এক্সিকিউটেবল নামের সাথে servicename.exe প্রতিস্থাপন করুন।
debugon.reg:
উইন্ডোজ রেজিস্ট্রি এডিটর সংস্করণ 5.00 [এইচকেই_লোকাল_ম্যাচিন \ সফটওয়্যার \ মাইক্রোসফ্ট, উইন্ডোজ এনটি V কারেন্টভিশন File চিত্র ফাইল এক্সিকিউশন বিকল্পসমূহ ic সার্ভিসনেম.এক্সই] "GlobalFlag" = "0x00000000" "ডিবাগার" = "vsjitdebugger.exe"
debugoff.reg:
উইন্ডোজ রেজিস্ট্রি এডিটর সংস্করণ 5.00 [এইচকেই_লোকাল_ম্যাচিন \ সফটওয়্যার \ মাইক্রোসফ্ট, উইন্ডোজ এনটি V কারেন্টভিশন File চিত্র ফাইল এক্সিকিউশন বিকল্পসমূহ ic সার্ভিসনেম.এক্সই] "GlobalFlag" = "0x00000000"
রুটিন ছোট ছোট স্টাফ প্রোগ্রামিংয়ের জন্য আমি সহজেই আমার পরিষেবাটি ডিবাগ করার জন্য খুব সহজ কৌশল করেছি:
পরিষেবাটি শুরু করার পরে, আমি একটি কমান্ড লাইন প্যারামিটার "/ ডিবাগ" পরীক্ষা করি। যদি এই প্যারামিটারটির সাথে পরিষেবাটি কল করা হয়, আমি সাধারন পরিষেবা শুরু করি না, পরিবর্তে সমস্ত শ্রোতা শুরু করি এবং একটি বার্তাবক্স প্রদর্শন করি "ডিবাগ প্রগতিতে চলছে, ঠিক আছে টিপুন" টিপুন।
সুতরাং আমার পরিষেবাটি যদি স্বাভাবিকভাবে শুরু করা হয় তবে এটি পরিষেবা হিসাবে শুরু হবে, যদি এটি কমান্ড লাইন প্যারামিটার / ডিবাগ দিয়ে শুরু করা হয় তবে এটি একটি সাধারণ প্রোগ্রামের মতো কাজ করবে।
ভিএস-এ আমি কেবল ডিবাগিং প্যারামিটার হিসাবে যুক্ত / ডিবাগ করব এবং সরাসরি পরিষেবা প্রোগ্রাম শুরু করব।
এইভাবে আমি খুব ছোট ধরণের সমস্যার জন্য সহজেই ডিবাগ করতে পারি। অবশ্যই, কিছু স্টাফ এখনও পরিষেবা হিসাবে ডিবাগ করা প্রয়োজন, কিন্তু 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
একটি নতুন পরিষেবা অ্যাপ তৈরি করতে উইন্ডোজ পরিষেবা টেম্পলেট সি # প্রকল্পটি ব্যবহার করুন https://github.com/HarpyWar/windows-service-template
কনসোল / পরিষেবা মোড স্বয়ংক্রিয়ভাবে সনাক্ত করা হয়েছে, আপনার পরিষেবার অটো ইনস্টলার / ডাইনস্টলার এবং বেশ কয়েকটি সর্বাধিক ব্যবহৃত বৈশিষ্ট্য অন্তর্ভুক্ত রয়েছে।
কোনও অতিরিক্ত "ডিবাগ" পদ্ধতি ছাড়াই এবং সংহত ভিএস ইউনিট টেস্ট সহ আমি পরিষেবাটি যা পরীক্ষার জন্য ব্যবহৃত হয়েছিল তা এখানে সহজ পদ্ধতি।
[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();
আপনি আপনার প্রোগ্রামটি চালানোর সময় এটি হিট হবে ।
' সিস্টেম.ডায়াগনস্টিকস ' নামস্থানটি ব্যবহার করা সবচেয়ে ভাল বিকল্প ।
ভিজ্যুয়াল স্টুডিওতে ডিবাগ এবং রিলিজ মোডের মধ্যে স্যুইচ করতে নীচে প্রদর্শিত হিসাবে ডিবাগ মোড এবং রিলিজ মোডের জন্য অবরুদ্ধ হলে আপনার কোডটি এটিকে বন্ধ করুন,
#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