如何對Windows Service進行除錯
問題簡述
我們都知道在開發Windows Service時是無法直接F5進行偵錯,所以通常會將編譯好的檔案透過InstallUtil.exe安裝工具佈署至系統中,然後再利用Vistual Studio附加至執行緒偵錯功能來Trace Code。但由於筆者於客戶端開發時,並無足夠權限來自由安裝Windows Service,所以就必須想個辦法直接對Windows Service進行偵錯。
解決方案
我們可以改用Console來執行Windows Service原有功能,因此就可以如同開發Console程式般地隨意進行Debug作業;使用此方法的好處在於不需調整(破壞)Service原有程式,僅需在程式進入點微調即可輕易切換達成偵錯目的。
首先,先將專案輸出類型改為主控台應用程式
建立RunInteractive方法來執行Service中非公開的OnStart及OnStop方法
static void RunInteractive(ServiceBase[] servicesToRun)
{
// 利用Reflection取得非公開之 OnStart() 方法資訊
MethodInfo onStartMethod = typeof(ServiceBase).GetMethod("OnStart",
BindingFlags.Instance | BindingFlags.NonPublic);
// 執行 OnStart 方法
foreach (ServiceBase service in servicesToRun)
{
Console.Write("Starting {0}...", service.ServiceName);
onStartMethod.Invoke(service, new object[] { new string[] { } });
Console.Write("Started");
}
Console.WriteLine("Press any key to stop the services");
Console.ReadKey();
// 利用Reflection取得非公開之 OnStop() 方法資訊
MethodInfo onStopMethod = typeof(ServiceBase).GetMethod("OnStop",
BindingFlags.Instance | BindingFlags.NonPublic);
// 執行 OnStop 方法
foreach (ServiceBase service in servicesToRun)
{
Console.Write("Stopping {0}...", service.ServiceName);
onStopMethod.Invoke(service, null);
Console.WriteLine("Stopped");
}
}
最後在程式進入點,使用上述方法取代原有ServiceBase.Run()方法
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new MyService()
};
// 01-於VS中偵錯時請先註解此部分
// ServiceBase.Run(ServicesToRun);
// 02-使用RunInteractive來執行原有Service功能以進行偵錯
RunInteractive(ServicesToRun);
}
程式啟動後將在Console中執行原有Service功能
順利進入中斷點進行偵錯作業
參考資料
http://coding.abel.nu/2012/05/debugging-a-windows-service-project/
希望此篇文章可以幫助到需要的人
若內容有誤或有其他建議請不吝留言給筆者喔 !