是否有比通过Windows服务控制管理器启动服务,然后将调试器附加到线程更简单的方法来逐步遍历代码?这有点麻烦,我想知道是否有更直接的方法。
当前回答
使用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服务管理器中启动和停止服务。
其他回答
只需将调试器放置在任何地方,并在启动时附加Visualstudio即可
#if DEBUG
Debugger.Launch();
#endif
此外,你需要以管理员身份启动VS,并且你需要允许,一个进程可以由不同的用户自动调试(如下所述):
reg add "HKCR\AppID{E62A7A31-6025-408E-87F6-81AEB0DC9347}" /v AppIDFlags /t REG_DWORD /d 8 /f
更新
这种方法是目前为止最简单的:
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
我认为这取决于你使用的操作系统,Vista很难附加到服务,因为会话之间的分离。
我过去使用的两个选项是:
Use GFlags (in the Debugging Tools for Windows) to setup a permanent debugger for a process. This exists in the "Image File Execution Options" registry key and is incredibly useful. I think you'll need to tweak the Service settings to enable "Interact with Desktop". I use this for all types of debugging, not just services. The other option, is to separate the code a bit, so that the service part is interchangable with a normal app startup. That way, you can use a simple command line flag, and launch as a process (rather than a Service), which makes it much easier to debug.
希望这能有所帮助。
下面是我用来测试服务的简单方法,没有任何额外的“调试”方法,并带有集成的VS单元测试。
[TestMethod]
public void TestMyService()
{
MyService fs = new MyService();
var OnStart = fs.GetType().BaseType.GetMethod("OnStart", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
OnStart.Invoke(fs, new object[] { null });
}
// As an extension method
public static void Start(this ServiceBase service, List<string> parameters)
{
string[] par = parameters == null ? null : parameters.ToArray();
var OnStart = service.GetType().GetMethod("OnStart", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
OnStart.Invoke(service, new object[] { par });
}
为了调试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"
推荐文章
- 为什么我不能在c#中有抽象静态方法?
- Nuget连接尝试失败“无法为源加载服务索引”
- net HttpClient。如何POST字符串值?
- 我如何使一个方法的返回类型泛型?
- 何时处理CancellationTokenSource?
- 如何获取正在执行的程序集版本?
- AutoMapper vs valueinjector
- 为什么控制台不。Writeline,控制台。在Visual Studio Express中编写工作?
- 什么是.NET程序集?
- GIT克隆在windows中跨本地文件系统回购
- 字符串不能识别为有效的日期时间“格式dd/MM/yyyy”
- 函数应该返回空对象还是空对象?
- 如何转换日期时间?将日期时间
- 如何在c#中连接列表?
- 在c#中引用类型变量的“ref”的用途是什么?