更輕鬆地調試Windows服務

是否有更簡單的方法來單步執行代碼,而不是經過Windows服務控制管理器啓動服務,而後將調試器附加到線程? 這有點麻煩,我想知道是否有一個更簡單的方法。 工具


#1樓

幾周前,當我找到一個新的服務項目時,我找到了這個帖子。 雖然有不少很棒的建議,但我仍然沒有找到我想要的解決方案:能夠在OnStop服務類進行任何修改的狀況下調用服務類的OnStartOnStop方法。 spa

我提出的解決方案使用Environment.Interactive選擇運行模式,正如此帖的其餘答案所示。 操作系統

static void Main()
{
    ServiceBase[] servicesToRun;
    servicesToRun = new ServiceBase[] 
    {
        new MyService()
    };
    if (Environment.UserInteractive)
    {
        RunInteractive(servicesToRun);
    }
    else
    {
        ServiceBase.Run(servicesToRun);
    }
}

RunInteractive助手使用反射來調用受保護的OnStartOnStop方法: 命令行

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);
}

這是所需的全部代碼,但我還編寫了演練解釋。 線程


#2樓

您還能夠經過命令提示符(sc.exe)啓動該服務。 調試

就我的而言,我會在調試階段將代碼做爲獨立程序運行,而且當大多數錯誤被解決時,將更改成做爲服務運行。 code


#3樓

我之前作的是有一個命令行開關,它能夠做爲服務或常規應用程序啓動程序。 而後,在個人IDE中,我會設置開關,以便我能夠單步執行代碼。 進程

使用某些語言,您實際上能夠檢測它是否在IDE中運行,並自動執行此切換。 get

你用的是什麼語言? string


#4樓

我一般作的是將服務的邏輯封裝在一個單獨的類中,並從「runner」類開始。 此運行器類能夠是實際服務,也能夠只是控制檯應用程序。 因此你的解決方案有(至少)3個項目:

/ConsoleRunner
   /....
/ServiceRunner
   /....
/ApplicationLogic
   /....

#5樓

我認爲這取決於您使用的操做系統,由於會話之間的分離,Vista很難鏈接到服務。

我過去使用的兩個選項是:

  • 使用GFlags(在Windows調試工具中)爲進程設置永久調試器。 這存在於「映像文件執行選項」註冊表項中,很是有用。 我認爲您須要調整服務設置以啓用「與桌面交互」。 我將它用於全部類型的調試,而不單單是服務。
  • 另外一個選擇是將代碼分開一點,以便服務部分能夠與正常的應用程序啓動互換。 這樣,您可使用簡單的命令行標誌,並做爲進程(而不是服務)啓動,這使得調試更容易。

但願這能夠幫助。

相關文章
相關標籤/搜索