是否有比通过Windows服务控制管理器启动服务,然后将调试器附加到线程更简单的方法来逐步遍历代码?这有点麻烦,我想知道是否有更直接的方法。
当前回答
只是粘贴
Debugger.Break();
代码中的任何地方。
例如,
internal static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
private static void Main()
{
Debugger.Break();
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new Service1()
};
ServiceBase.Run(ServicesToRun);
}
}
它会点击Debugger.Break();当你运行程序时。
其他回答
如果我想快速调试服务,我只需在那里放入一个Debugger.Break()。当到达这条线时,它会将我拉回到VS.当你完成时,不要忘记删除这条线。
更新:作为#if DEBUG pragmas的替代,你也可以使用Conditional("DEBUG_SERVICE")属性。
[Conditional("DEBUG_SERVICE")]
private static void DebugMode()
{
Debugger.Break();
}
在OnStart上,只需调用这个方法:
public override void OnStart()
{
DebugMode();
/* ... do the rest */
}
在那里,代码将只在调试构建期间启用。在此过程中,为服务调试创建一个单独的Build Configuration可能会很有用。
只需将调试器放置在任何地方,并在启动时附加Visualstudio即可
#if DEBUG
Debugger.Launch();
#endif
此外,你需要以管理员身份启动VS,并且你需要允许,一个进程可以由不同的用户自动调试(如下所述):
reg add "HKCR\AppID{E62A7A31-6025-408E-87F6-81AEB0DC9347}" /v AppIDFlags /t REG_DWORD /d 8 /f
为了调试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"
对于现有Windows服务程序的故障排除,请像其他人建议的那样使用'Debugger.Break()'。
对于新的Windows服务程序,我建议使用James Michael Hare的方法http://geekswithblogs.net/BlackRabbitCoder/archive/2011/03/01/c-toolbox-debug-able-self-installable-windows-service-template-redux.aspx
更新
这种方法是目前为止最简单的:
http://www.codeproject.com/KB/dotnet/DebugWinServices.aspx
我把最初的答案留给后人。
我的服务倾向于有一个封装定时器的类,因为我想让服务定期检查它是否有任何工作要做。
我们在服务启动期间更新类并调用StartEventLoop()。(这个类也可以很容易地从控制台应用程序中使用。)
这种设计的一个很好的副作用是,可以使用用来设置Timer的参数在服务实际开始工作之前有一个延迟,这样就有时间手动附加调试器。
p.s. .如何手动将调试器附加到正在运行的进程…?
using System;
using System.Threading;
using System.Configuration;
public class ServiceEventHandler
{
Timer _timer;
public ServiceEventHandler()
{
// get configuration etc.
_timer = new Timer(
new TimerCallback(EventTimerCallback)
, null
, Timeout.Infinite
, Timeout.Infinite);
}
private void EventTimerCallback(object state)
{
// do something
}
public void StartEventLoop()
{
// wait a minute, then run every 30 minutes
_timer.Change(TimeSpan.Parse("00:01:00"), TimeSpan.Parse("00:30:00");
}
}
我也曾经做过以下事情(在之前的回答中已经提到过,但是使用条件编译器[#if]标志来帮助避免它在发布构建中被触发)。
我不再这样做了,因为有时我们会忘记在发布中构建,并在客户端演示上运行的应用程序中出现调试器中断(尴尬!)
#if DEBUG
if (!System.Diagnostics.Debugger.IsAttached)
{
System.Diagnostics.Debugger.Break();
}
#endif
推荐文章
- 实体框架核心:在上一个操作完成之前,在此上下文中开始的第二个操作
- 如何为构造函数定制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 ?