是否有比通过Windows服务控制管理器启动服务,然后将调试器附加到线程更简单的方法来逐步遍历代码?这有点麻烦,我想知道是否有更直接的方法。
当前回答
这段YouTube视频由Fabio Scopel解释了如何调试一个Windows服务相当好…实际的方法从视频中的4:45开始…
下面是视频中解释的代码…在你的Program.cs文件中,添加Debug部分的东西…
namespace YourNamespace
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
#if DEBUG
Service1 myService = new Service1();
myService.OnDebug();
System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
#else
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new Service1()
};
ServiceBase.Run(ServicesToRun);
#endif
}
}
}
在你的Service1.cs文件中,添加OnDebug()方法…
public Service1()
{
InitializeComponent();
}
public void OnDebug()
{
OnStart(null);
}
protected override void OnStart(string[] args)
{
// your code to do something
}
protected override void OnStop()
{
}
它是如何工作的
基本上,你必须创建一个公共void OnDebug(),调用OnStart(string[] args),因为它是受保护的,不能在外部访问。void Main()程序添加了#if预处理器和#DEBUG。
如果项目在DEBUG模式下编译,Visual Studio定义DEBUG。这将允许调试部分(下面)在条件为真时执行
Service1 myService = new Service1();
myService.OnDebug();
System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
它将像控制台应用程序一样运行,一旦一切顺利,您可以更改模式Release和常规else部分将触发逻辑
其他回答
我认为这取决于你使用的操作系统,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.
希望这能有所帮助。
我也认为为正常执行和作为服务提供一个单独的“版本”是可行的,但真的需要为此目的专门提供一个单独的命令行开关吗?
你就不能这样做吗:
public static int Main(string[] args)
{
if (!Environment.UserInteractive)
{
// Startup as service.
}
else
{
// Startup as application
}
}
这将有“好处”,你可以通过双击启动你的应用程序(好吧,如果你真的需要的话),你可以在Visual Studio中点击F5(不需要修改项目设置,包括/控制台选项)。
严格来说,是环境。UserInteractive检查是否为当前窗口站设置了WSF_VISIBLE标志,但是除了作为(非交互式)服务运行之外,还有其他原因它将返回false吗?
第一行的Debugger.Break()怎么样?
当我几周前建立一个新的服务项目时,我发现了这个帖子。虽然有很多很好的建议,但我仍然没有找到我想要的解决方案:在不修改服务类的情况下调用服务类的OnStart和OnStop方法的可能性。
我想到的解决方案是利用环境。交互式选择运行模式,正如这篇文章的其他答案所建议的。
static void Main()
{
ServiceBase[] servicesToRun;
servicesToRun = new ServiceBase[]
{
new MyService()
};
if (Environment.UserInteractive)
{
RunInteractive(servicesToRun);
}
else
{
ServiceBase.Run(servicesToRun);
}
}
RunInteractive helper使用反射来调用受保护的OnStart和OnStop方法:
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 to stop the services and end the process...");
Console.ReadKey();
Console.WriteLine();
MethodInfo onStopMethod = typeof(ServiceBase).GetMethod("OnStop",
BindingFlags.Instance | BindingFlags.NonPublic);
foreach (ServiceBase service in servicesToRun)
{
Console.Write("Stopping {0}...", service.ServiceName);
onStopMethod.Invoke(service, null);
Console.WriteLine("Stopped");
}
Console.WriteLine("All services stopped.");
// Keep the console alive for a second to allow the user to see the message.
Thread.Sleep(1000);
}
这是所需的所有代码,但我还编写了带有解释的演练。
我能够轻松地调试一个windows服务从微软官方文档- https://learn.microsoft.com/en-us/dotnet/framework/windows-services/how-to-debug-windows-service-applications#how-to-run-a-windows-service-as-a-console-application。
它告诉运行windows服务作为控制台应用程序进行调试。
推荐文章
- 实体框架核心:在上一个操作完成之前,在此上下文中开始的第二个操作
- 如何为构造函数定制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 ?