[Windows Service] 如何對Windows Service進行除錯

如何對Windows Service進行除錯

問題簡述

我們都知道在開發Windows Service時是無法直接F5進行偵錯,所以通常會將編譯好的檔案透過InstallUtil.exe安裝工具佈署至系統中,然後再利用Vistual Studio附加至執行緒偵錯功能來Trace Code。但由於筆者於客戶端開發時,並無足夠權限來自由安裝Windows Service,所以就必須想個辦法直接對Windows Service進行偵錯。

 

解決方案

我們可以改用Console來執行Windows Service原有功能,因此就可以如同開發Console程式般地隨意進行Debug作業;使用此方法的好處在於不需調整(破壞)Service原有程式,僅需在程式進入點微調即可輕易切換達成偵錯目的。

首先,先將專案輸出類型改為主控台應用程式

image

建立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功能

image

順利進入中斷點進行偵錯作業

image

 

參考資料

http://coding.abel.nu/2012/05/debugging-a-windows-service-project/

http://blog.miniasp.com/post/2009/04/05/How-to-debugging-Windows-Service-and-Setup-Project-Custom-Action.aspx


希望此篇文章可以幫助到需要的人

若內容有誤或有其他建議請不吝留言給筆者喔 !