یکی از سختترین چالشهای تهیه سرویسهای ویندوز، دیباگ آنها است. برای تست و دیباگ کدها در ویندوز سرویسها، راهکارها و ابزارهای متفاوتی ارائه شدهاند که در این مقاله قصد دارم یکی از آنها را معرفی کنم.
برای تست کدها در ویندوز سرویس، اولین راه پیشنهادی همیشه این بوده که سرویس را موقتا به Console Application تبدیل کنیم و با تهیه یک متد در سرویس و فراخوانی آن در متد Main برنامه کنسولی، بتوانیم به دیباگ برنامه بپردازیم. مثال:
تغییرات مورد نیاز در سرویس :
public Service1(string[] args)
{
this.args = args;
}
internal void TestStartupAndStop(string[] args)
{
this.OnStart(args);
Console.ReadLine();
this.OnStop();
}
protected override void OnStart(string[] args)
{
Console.WriteLine("Service Started");
//Do Somthing
}
تغییرات مورد نیاز در متد Main :
static void Main(string[] args)
{
if (Environment.UserInteractive)
{
Service1 service1 = new Service1(args);
service1.TestStartupAndStop(args);
}
else
{
// Put the body of your old Main method here.
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new Service1()
};
ServiceBase.Run(ServicesToRun);
}
}
برای کسب اطلاعات بیشتر در مورد این روش برای دیباگ، میتوانید به
این لینک مراجعه نمایید.
این راه حل کلی، عموما جوابگوی نیازها هست و تست و دیباگ را میتوانیم از همین طریق انجام دهیم. اما مشکلات زیادی هم دارد. به طور مثال یکی از مشکلات هنگام استفاده از این راه حل، تفاوت دسترسیها و کاربر اجرا کننده برنامه، در حالت کنسول و سرویس ویندوز است. به همین دلیل بسیار با این مشکل مواجه خواهید شد که هنگام دیباگ مشکلی وجود نداشته ولی بعد از نصب سرویس، برنامه بدرستی کار نکند. به طور مثال وقتی شما سرویس را به صورت Network Service ویا Local System نصب کنید، دسترسی برنامه به کلیدهای رجیستری , فایل سیستم و Environment تغییر میکند. در نتیجه اگر مانند روشی که در بالا ذکر شد دیباگ را انجام دهید، نمیتوانید مشکلات را شناسایی و رفع کنید. همینطور روش قبلی صرفا برای دیباگ نیازمند تغییر در سورس کد اصلی برنامه است که خود میتواند مشکلات یا محدودیتهایی را هنگام کار به صورت تیمی ایجاد کند.
برای دیباگ سرویس نصب شده چه باید کرد ؟
در این مطلب نمیخواهم وارد جزئیات نحوه نصب ویندوز سرویسها شوم؛ چراکه خودش مبحث گستردهایست. برای کسب اطلاعات بیشتر در مورد نحوهی نصب سرویسها میتوانید به
این لینک مراجعه نمایید.
برای اینکه بعد از نصب سرویس بتوانیم به دیباگ آن بپردازیم، مراحل زیر را طی کنید.
1- اول در ابتدای متد OnStart سرویس، تکه کد زیر را وارد نمایید و یک BreakPoint کنارش قرار دهید:
System.Diagnostics.Debugger.Launch(); // Start Debugger
البته پیشنهاد میکنم که این بخش را به صورت زیر وارد کنید تا فقط درصورتیکه سرویس شما در حالت Debug ساخته شده باشد، اجرا شود.
#if DEBUG
System.Diagnostics.Debugger.Launch(); // Start Debugger
#endif
2- سرویس را با استفاده از
installutil نصب کرده و استارت نمایید.
هنگام استارت سرویس، پنجره زیر نمایان میشود.
درصورتی که Yes را انتخاب نمایید، میتوانید در یک Solution جدید به دیباگ برنامه بپردازید و دیباگر به صورت خودکار کدهای مورد نیاز را برای شروع کار، برای شما بارگذاری خواهد کرد. اما در پروژههای بزرگتر به دلیل وابستگیهای سرویس به کتابخانههای متعدد، امکان دیباگ کامل را هنوز در اختیار نداریم و دیباگ ما در اینجا، محدود به خود سرویس است. برای اینکه بتوانیم دیباگ را کامل در Solution اصلی برنامه انجام دهید، قبل پاسخ دادن به پنجره بالا یک مرحله دیگر از کار باقی مانده است.
3- در Solution اصلی برنامه خود، کلیدهای Ctrl+Alt+P را فشار دهید؛ یا از طریق منوی Debug > Attach to process، پنجره Attack to Process را باز نمایید.
همانطور که در تصویر مشاهده میکنید، ID پروسه را در هر دو عکس برایتان مشخص کردهام (هایلایت زرد) که به راحتی میتوانید پروسه سرویستان را از این طریق پیدا کنید.
کافیست روی کلید Attach کلیک نمایید تا در Solution اصلی برنامه بتوانید به صورت کامل به دیباگ سرویس نصب شده بپردازید. پس از اتچ کردن پروسه به Solution خود، پنجره اول (Visual Studio Just-In Time debugger) را ببندید یا گزینه No را انتخاب نمایید.
نکته: برای استفاده از این روش باید Visual Studio به صورت Administrator اجرا شده باشد.