如何在Visual Studio中调试Windows服务?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在Visual Studio中调试Windows服务?相关的知识,希望对你有一定的参考价值。

是否可以在Visual Studio中调试Windows服务?

我用的代码就像

System.Diagnostics.Debugger.Break();

但它给出了一些代码错误,如:

我收到两个事件错误:eventID 4096 VsJITDebugger和“服务没有及时响应启动或控制请求。”

答案

在服务OnStart方法中使用以下代码:

System.Diagnostics.Debugger.Launch();

从弹出消息中选择Visual Studio选项。

注意:要仅在调试模式下使用它,可以使用#if DEBUG编译器指令,如下所示。这将防止生产服务器上的发布模式中的意外或调试。

#if DEBUG
    System.Diagnostics.Debugger.Launch();
#endif
另一答案

我在Visual Studio项目中使用/Console参数Debug→Start Options→命令行参数:

public static class Program
{
    [STAThread]
    public static void Main(string[] args)
    {
         var runMode = args.Contains(@"/Console")
             ? WindowsService.RunMode.Console
             : WindowsService.RunMode.WindowsService;
         new WinodwsService().Run(runMode);
    }
}


public class WindowsService : ServiceBase
{
    public enum RunMode
    {
        Console,
        WindowsService
    }

    public void Run(RunMode runMode)
    {
        if (runMode.Equals(RunMode.Console))
        {
            this.StartService();
            Console.WriteLine("Press <ENTER> to stop service...");
            Console.ReadLine();

            this.StopService();
            Console.WriteLine("Press <ENTER> to exit.");
            Console.ReadLine();
        }
        else if (runMode.Equals(RunMode.WindowsService))
        {
            ServiceBase.Run(new[] { this });
        }
    }

    protected override void OnStart(string[] args)
    {
        StartService(args);
    }

    protected override void OnStop()
    {
        StopService();
    }

    /// <summary>
    /// Logic to Start Service
    /// Public accessibility for running as a console application in Visual Studio debugging experience
    /// </summary>
    public virtual void StartService(params string[] args){ ... }

    /// <summary>
    /// Logic to Stop Service
    /// Public accessibility for running as a console application in Visual Studio debugging experience
    /// </summary>
    public virtual void StopService() {....}
}
另一答案

不幸的是,如果您在Windows服务操作的最初阶段尝试调试某些内容,则“附加”到正在运行的进程将无法正常工作。我尝试在OnStart程序中使用Debugger.Break(),但是使用64位Visual Studio 2010编译的应用程序,break命令只会抛出这样的错误:

System error 1067 has occurred.

此时,您需要在注册表中为可执行文件设置“映像文件执行”选项。设置需要五分钟,而且效果非常好。这是一篇微软文章,详细信息如下:

How to: Launch the Debugger Automatically

另一答案

尝试使用Visual Studio自己的构建后事件命令行。

尝试在post-build中添加:

@echo off
sc query "ServiceName" > nul
if errorlevel 1060 goto install
goto stop

:delete
echo delete
sc delete "ServiceName" > nul
echo %errorlevel%
goto install

:install
echo install
sc create "ServiceName" displayname= "Service Display Name" binpath= "$(TargetPath)" start= auto > nul
echo %errorlevel%
goto start

:start
echo start
sc start "ServiceName" > nul
echo %errorlevel%
goto end

:stop
echo stop
sc stop "ServiceName" > nul
echo %errorlevel%
goto delete

:end

如果构建错误的消息如Error 1 The command "@echo off sc query "ServiceName" > nul等,则按Ctrl + C然后按Ctrl + V将错误消息放入记事本并查看消息的最后一句。

可能会说exited with code x。在这里查找一些常见错误的代码,看看如何解决它。

1072 -- Marked for deletion → Close all applications that maybe using the service including services.msc and Windows event log.
1058 -- Can't be started because disabled or has no enabled associated devices → just delete it.
1060 -- Doesn't exist → just delete it.
1062 -- Has not been started → just delete it.
1053 -- Didn't respond to start or control → see event log (if logged to event log). It may be the service itself throwing an exception.
1056 -- Service is already running → stop the service, and then delete.

有关错误代码here的更多信息。

如果构建错误与这样的消息,

Error    11    Could not copy "objx86DebugServiceName.exe" to "binDebugServiceName.exe". Exceeded retry count of 10. Failed.    ServiceName
Error    12    Unable to copy file "objx86DebugServiceName.exe" to "binDebugServiceName.exe". The process cannot access the file 'binDebugServiceName.exe' because it is being used by another process.    ServiceName

打开cmd,然后尝试先用taskkill /fi "services eq ServiceName" /f杀死它

如果一切顺利,F5应该足以调试它。

另一答案

我使用了一个名为ServiceProcess.Helpers的优秀Nuget包。

我引用......

它通过在连接调试器的情况下创建播放/停止/暂停UI来帮助调试Windows服务,但也允许Windows服务器环境安装和运行服务。

所有这一切都有一行代码。

http://windowsservicehelper.codeplex.com/

安装完成后,您需要做的就是将Windows服务项目设置为启动项目,然后单击调试器上的start。

另一答案

OnStart方法中,执行以下操作。

protected override void OnStart(string[] args)
{
    try
    {
        RequestAdditionalTime(600000);
        System.Diagnostics.Debugger.Launch(); // Put breakpoint here.

        .... Your code
    }
    catch (Exception ex)
    {
        .... Your exception code
    }
}

然后以管理员身份运行命令提示符并输入以下内容:

c:> sc create test-xyzService binPath= <ProjectPath>indebugservice.exe type= own start= demand

上面的代码行将在服务列表中创建test-xyzService。

要启动该服务,这将提示您附加到Visual Studio中的首次亮相。

c:> sc start text-xyzService

要停止服务:

c:> sc stop test-xyzService

要删除或卸载:

c:> sc delete text-xyzService
另一答案

我发现了这个问题,但我认为缺少一个简单明了的答案。

我不想将我的调试器附加到进程,但我仍然希望能够调用服务OnStartOnStop方法。我还希望它作为控制台应用程序运行,以便我可以将信息从NLog记录到控制台。

我发现这些精彩的指南可以做到这一点:

首先将项目Output type更改为Console Application

Enter image description here

将您的Program.cs更改为如下所示:

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    static void Main()
    {
        // Startup as service.
        ServiceBase[] ServicesToRun;
        ServicesToRun = new ServiceBase[]
        {
            new Service1()
        };

        if (Environment.UserInteractive)
        {
            RunInteractive(ServicesToRun);
        }
        else
        {
            ServiceBase.Run(ServicesToRun);
        }
    }
}

然后添加以下方法以允许以交互模式运行的服务。

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 t

以上是关于如何在Visual Studio中调试Windows服务?的主要内容,如果未能解决你的问题,请参考以下文章

Windows ServiceWindows Service在Visual Studio中安装调试

如何在 Microsoft Visual Studio 2019 中调试 nestjs 程序?

如何在 Visual Studio 代码中调试打字稿文件

如何在 Visual Studio 中调试单行函数?

译如何在 Visual Studio 中调试异步代码

如何在Visual Studio中调试Windows服务?