是否有比通过Windows服务控制管理器启动服务,然后将调试器附加到线程更简单的方法来逐步遍历代码?这有点麻烦,我想知道是否有更直接的方法。
当前回答
为了调试Windows服务,我结合了GFlags和一个由regedit创建的.reg文件。
运行GFlags,指定ex -name和vsjitdebugger 运行regedit并转到GFlags设置选项的位置 从文件菜单中选择“导出密钥” 将该文件保存在扩展名为.reg的某处 任何时候你想调试服务:双击.reg文件 如果要停止调试,请双击第二个.reg文件
或者保存以下代码片段并用所需的可执行名称替换servicename.exe。
debugon.reg:
Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\servicename.exe] "GlobalFlag"="0x00000000" "Debugger"="vsjitdebugger.exe"
debugoff.reg:
Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\servicename.exe] "GlobalFlag"="0x00000000"
其他回答
#if DEBUG
System.Diagnostics.Debugger.Break();
#endif
使用TopShelf库。
创建一个控制台应用程序,然后在Main中配置安装
class Program
{
static void Main(string[] args)
{
HostFactory.Run(x =>
{
// setup service start and stop.
x.Service<Controller>(s =>
{
s.ConstructUsing(name => new Controller());
s.WhenStarted(controller => controller.Start());
s.WhenStopped(controller => controller.Stop());
});
// setup recovery here
x.EnableServiceRecovery(rc =>
{
rc.RestartService(delayInMinutes: 0);
rc.SetResetPeriod(days: 0);
});
x.RunAsLocalSystem();
});
}
}
public class Controller
{
public void Start()
{
}
public void Stop()
{
}
}
要调试您的服务,只需在visual studio中按F5。
要安装服务,键入cmd "console.exe install"
然后,您可以在windows服务管理器中启动和停止服务。
我使用了JOP的答案的变体。使用命令行参数,您可以在IDE中使用项目属性或通过Windows服务管理器设置调试模式。
protected override void OnStart(string[] args)
{
if (args.Contains<string>("DEBUG_SERVICE"))
{
Debugger.Break();
}
...
}
有时,分析在服务启动期间发生了什么是很重要的。附加到流程在这里没有帮助,因为在服务启动时附加调试器的速度不够快。
简单的回答是,我使用以下4行代码来做到这一点:
#if DEBUG
base.RequestAdditionalTime(600000); // 600*1000ms = 10 minutes timeout
Debugger.Launch(); // launch and attach debugger
#endif
这些被插入到服务的OnStart方法中,如下所示:
protected override void OnStart(string[] args)
{
#if DEBUG
base.RequestAdditionalTime(600000); // 10 minutes timeout for startup
Debugger.Launch(); // launch and attach debugger
#endif
MyInitOnstart(); // my individual initialization code for the service
// allow the base class to perform any work it needs to do
base.OnStart(args);
}
对于那些以前没有做过的人,我在下面列出了详细的提示,因为你很容易陷入困境。以下提示适用于Windows 7x64和Visual Studio 2010 Team Edition,但也适用于其他(更新的)环境。
重要提示:以“手动”模式部署服务(在VS命令提示符中使用InstallUtil实用程序或运行您准备好的服务安装程序项目)。在启动服务之前打开Visual Studio并加载包含服务源代码的解决方案——在Visual Studio中根据需要设置额外的断点——然后通过服务控制面板启动服务。
因为调试器。启动代码,这将导致一个对话框“一个未处理的Microsoft . net Framework异常发生在Servicename.exe.”出现。单击“是”,调试Servicename.exe,如下图所示:
之后,Windows UAC可能会提示您输入管理凭据。输入它们并继续执行Yes:
之后,著名的Visual Studio即时调试器窗口出现。它询问您是否要使用已删除的调试器进行调试。在单击Yes之前,选择不想打开新实例(第二个选项)——在这里,新实例没有帮助,因为不会显示源代码。所以你选择之前打开的Visual Studio实例:
单击Yes后,过一会儿Visual Studio将在调试器所在的行中显示黄色箭头。启动语句,您可以调试您的代码(方法MyInitOnStart,其中包含初始化)。
按F5继续立即执行,直到到达您准备的下一个断点。
提示:要保持服务运行,请选择Debug -> Detach all。这允许您在服务正确启动并完成调试启动代码之后运行与服务通信的客户机。如果您按下Shift+F5(停止调试),这将终止服务。您应该使用服务控制面板来停止它,而不是这样做。
请注意,
If you build a Release, then the debug code is automatically removed and the service runs normally. I am using Debugger.Launch(), which starts and attaches a debugger. I have tested Debugger.Break() as well, which did not work, because there is no debugger attached on start up of the service yet (causing the "Error 1067: The process terminated unexpectedly."). RequestAdditionalTime sets a longer timeout for the startup of the service (it is not delaying the code itself, but will immediately continue with the Debugger.Launch statement). Otherwise the default timeout for starting the service is too short and starting the service fails if you don't call base.Onstart(args) quickly enough from the debugger. Practically, a timeout of 10 minutes avoids that you see the message "the service did not respond..." immediately after the debugger is started. Once you get used to it, this method is very easy because it just requires you to add 4 lines to an existing service code, allowing you quickly to gain control and debug.
第一行的Debugger.Break()怎么样?
推荐文章
- 实体框架核心:在上一个操作完成之前,在此上下文中开始的第二个操作
- 如何为构造函数定制Visual Studio的私有字段生成快捷方式?
- 为什么Visual Studio 2015/2017/2019测试运行器没有发现我的xUnit v2测试
- 如何使用JSON确保字符串是有效的JSON。网
- AppSettings从.config文件中获取值
- 通过HttpClient向REST API发布一个空体
- 如何检查IEnumerable是否为空或空?
- 自动化invokerrequired代码模式
- 我如何找到哪个程序正在使用端口80在Windows?
- 在Windows中有像GREP这样的模式匹配实用程序吗?
- 没有ListBox。SelectionMode="None",是否有其他方法禁用列表框中的选择?
- 在c#代码中设置WPF文本框的背景颜色
- 在c#中,什么是单子?
- c#和Java中的泛型有什么不同?和模板在c++ ?
- 如何在Windows命令提示符下运行.sh ?