将Windows服务作为控制台应用程序运行

时间:2011-03-01 16:19:01

标签: c# windows-services

我想调试Windows服务,但会弹出一条错误消息

  

无法从命令启动服务   行或调试器。一个Windows服务   必须使用安装   installutil.exe然后开始   服务器资源管理器,Windows服务   管理工具或NET启动   命令。

我真的不知道这个错误......

enter image description here

6 个答案:

答案 0 :(得分:35)

在运行Windows服务之前,必须首先使用installutil“安装”它。 EG:

C:\installutil -i c:\path\to\project\debug\service.exe

然后,您可以打开服务列表以启动它。 EG:

  1. 右键点击“我的电脑”
  2. 点击“管理”
  3. 打开'服务与应用'
  4. 点击“服务”
  5. 在列表中找到您的服务并右键单击它
  6. 点击“开始”
  7. 一旦启动,您可以进入Visual Studio,单击“Debug”,然后单击“Attach to Process”。

    另一种方法是将此行添加到服务中的OnStart()方法:

    System.Diagnostics.Debugger.Launch();
    

    当你这样做时,它会提示你选择一个Visual Studio实例来调试服务。

答案 1 :(得分:16)

您可以根据您是否处于DEBUG模式(通常在Visual Studio内部但不一定是)或RELEASE模式(当它在生产中作为服务运行时)来更改程序集的启动模式:

改变这个:

static class Program
{
    static void Main()
    {
        ServiceBase[] ServicesToRun;
        ServicesToRun = new ServiceBase[] 
        { 
            new MyService() 
        };
        ServiceBase.Run(ServicesToRun);
    }
}

到那个:

static class Program
{
    static void Main()
    {
        #if(!DEBUG)
            ServiceBase[] ServicesToRun;
            ServicesToRun = new ServiceBase[] 
            { 
                new MyService() 
            };
            ServiceBase.Run(ServicesToRun);
        #else
            MyService myServ = new MyService();
            myServ.Process();
            // here Process is my Service function
            // that will run when my service onstart is call
            // you need to call your own method or function name here instead of Process();
        #endif
    }
}

该技术取自this article,该文章的作者是Tejas Vaishnav。我在这里复制了代码片段,因为SO赞成完整的答案而不是可能在某个时间消失的链接。

答案 2 :(得分:2)

为防止发生此错误并允许服务在通常的服务控制器之外运行,您可以检查 if (Environment.UserInteractive) { var service = new WindowsService(); service.TestInConsole(args); return; } 标志。如果已设置,则可以使用输出到控制台运行服务,而不是让它运行到返回该错误的ServiceBase代码。

在使用ServiceBase运行服务的代码之前,将其添加到Program.Main()的开头:

protected

由于OnStart和OnStop方法在您的服务中为 public void TestInConsole(string[] args) { Console.WriteLine($"Service starting..."); this.OnStart(args); Console.WriteLine($"Service started. Press any key to stop."); Console.ReadKey(); Console.WriteLine($"Service stopping..."); this.OnStop(); Console.WriteLine($"Service stopped. Closing in 5 seconds."); System.Threading.Thread.Sleep(5000); } ,您需要向该类添加另一个方法,您可以从Main()运行并为您调用这些方法,例如:

{{1}}

最后,确保输出是项目属性中的控制台应用程序。

您现在可以像任何其他服务器一样运行服务可执行文件,它将作为控制台启动。如果从Visual Studio启动它,调试器将自动附加。如果您注册并将其作为服务启动,它将作为服务正常运行而无需任何更改。

我发现的唯一区别是,当作为控制台应用程序运行时,代码不会写入事件日志,您可能希望输出通常记录到控制台的任何内容。

此服务调试技术是docs.microsoft.com

中解释的技术之一

答案 3 :(得分:1)

请检查您是否处于“DEBUG”或“RELEASE”模式。当我尝试在“RELEASE”模式下调试服务时出现此错误。当我把它改为“DEBUG”时,一切都运转正常。

这是在您按照上述其他人的建议正确安装服务之后。

答案 4 :(得分:0)

有一个nuget软件包可以解决此问题:install-package WindowsService.Gui

Image of the runner GUI

软件包做什么?

通过在连接调试器的情况下运行播放/停止/暂停UI会有所帮助,而且还允许Windows服务环境安装和运行Windows服务。所有这些只需一行代码!什么是服务帮助者作为经常编写Windows服务的人,应对调试服务中的头痛可能令人沮丧。它通常涉及技巧,黑客和部分变通办法,以测试您的所有代码。 Windows服务开发人员没有“打F5”的经验。

Service Helper通过触发一个UI来解决此问题,如果连接了调试器,该调试器将(尽可能紧密地)模拟Windows Services Environment。

github项目在这里:https://github.com/wolfen351/windows-service-gui

如何使用?

在您的项目中获取Windows Service Helper的最简单方法是使用NuGet官方feed上的NuGet包ServiceProcess.Helpers。

只需对应用程序的“ Program.cs”中的典型代码进行一些更改:

using System.ServiceProcess;
using ServiceProcess.Helpers; //HERE

namespace DemoService
{
    static class Program
    {
    static void Main()
    {
        ServiceBase[] ServicesToRun;

        ServicesToRun = new ServiceBase[] 
            { 
                new Service1() 
            };

        //ServiceBase.Run(ServicesToRun);
        ServicesToRun.LoadServices(); //AND HERE
    }
    }
}

披露:我是这个项目的维护者

答案 5 :(得分:0)

另一个原因可能是解决方案配置处于Release模式而不是Debug模式enter image description here

enter image description here