如何在Visual Studio中debuggingWindows服务?
是否有可能在Visual Studio中debuggingWindows服务?
我使用类似的代码
System.Diagnostics.Debugger.Break();
但它给了一些代码错误
我得到了两个事件错误:事件ID 4096 VsJITDebugger和“该服务没有及时响应启动或控制请求。
在服务OnStart方法中使用以下代码:
System.Diagnostics.Debugger.Launch();
从popup消息中selectVisual Studio选项。
注意:要仅以debugging模式使用它,可以使用#if DEBUG编译器指令,如下所示。 这将防止在生产服务器上发生意外或debugging模式。
#if DEBUG System.Diagnostics.Debugger.Launch(); #endif
你也可以试试这个。
- 创build您的Windows服务并安装并启动…。 也就是说,Windows服务必须在您的系统中运行。
- 当您的服务正在运行时,请转到debugging菜单,单击附加进程 (或在旧的Visual Studio中的进程)
- find正在运行的服务,然后确保显示所有用户的 进程和所有会话中的显示进程被选中,如果没有,则select它。
- 点击附加button
- 点击OK
- 点击closures
- 设置一个断点到你想要的位置,然后等待执行。 只要你的代码达到那个点,它就会自动进行debugging。
- 记住,把你的断点放在可到达的地方 ,如果是onStart (),然后停止并重新启动服务
(经过大量的search,我在“如何在Visual Studio中debuggingWindows服务”中find了这个)
您应该将所有将从服务项目中执行的代码分离出来,然后创build一个可以正常运行和debugging的testing应用程序。
服务项目只是实现服务部分所需的shell。
要么如Lasse V. Karlsen所build议的那样,要么在您的服务中设置一个等待debugging器附加的循环。 最简单的是
while (!Debugger.IsAttached) { Thread.Sleep(1000); } ... continue with code
这样你就可以启动服务,在Visual Studio里select“附加到进程…”并附加到你的服务上,然后恢复正常的服务。
鉴于ServiceBase.OnStart
已经protected
可见性,我沿着reflection路线来实现debugging。
private static void Main(string[] args) { var serviceBases = new ServiceBase[] {new Service() /* ... */ }; #if DEBUG if (Environment.UserInteractive) { const BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic; foreach (var serviceBase in serviceBases) { var serviceType = serviceBase.GetType(); var methodInfo = serviceType.GetMethod("OnStart", bindingFlags); new Thread(service => methodInfo.Invoke(service, new object[] {args})).Start(serviceBase); } return; } #endif ServiceBase.Run(serviceBases); }
请注意, Thread
默认情况下是前台线程。 当人造服务线程正在运行时从Main
return
将不会终止进程。
你可以做一个控制台应用程序。 我使用这个main
function:
static void Main(string[] args) { ImportFileService ws = new ImportFileService(); ws.OnStart(args); while (true) { ConsoleKeyInfo key = System.Console.ReadKey(); if (key.Key == ConsoleKey.Escape) break; } ws.OnStop(); }
我的ImportFileService
类与我的Windows服务应用程序中的完全相同,除了inheritance者( ServiceBase
)。
你也可以尝试System.Diagnostics.Debugger.Launch()方法。 它有助于将debugging指针指向指定的位置,然后可以debugging您的代码。
在此步骤之前, 请使用Visual Studio命令提示符的命令行安装service.exe – installutil projectservice.exe
然后从控制面板 – >pipe理工具 – >计算机pipe理 – >服务和应用程序 – >服务 – >您的服务名称开始您的服务
我在Visual Studio项目Debug> Start Options> Command line arguments中使用了一个/ Console参数:
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服务操作开始时debugging某些东西,那么“附加”到正在运行的进程将不起作用。 我试着在OnStart过程中使用Debugger.Break(),但是对于一个64位,VS 10编译的应用程序,break命令只是抛出这样的错误:
System error 1067 has occurred.
在这一点上,你需要做的是在你的registry中为你的可执行文件设置一个“Image File Execution”选项。 它需要5分钟的时间来安装,它工作得很好。 这是一个链接到MS的细节是:
http://msdn.microsoft.com/en-us/library/a329t4ed(v=vs.100).aspx
我只是把这个代码添加到我的服务类,所以我可以间接调用OnStart,类似于OnStop。
public void MyOnStart(string[] args) { OnStart(args); }
是不是每个人都试过VS自己的post-build事件命令行 ?
尝试在构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 apps that maybe using the service including services.msc and windows event log. 1058 -- cant be started because disabled or has no enabled associated devices --> just delete it. 1060 -- doesnt exist --> just delete it. 1062 -- has not been started --> just delete it. 1053 -- didnt response to start or control --> see event log (if logged to event log). it maybe the service itself throw an exception 1056 -- service is already running --> stop the service then delete.
更多关于这里的错误代码
如果这样的消息生成错误
Error 11 Could not copy "obj\x86\Debug\ServiceName.exe" to "bin\Debug\ServiceName.exe". Exceeded retry count of 10. Failed. ServiceName Error 12 Unable to copy file "obj\x86\Debug\ServiceName.exe" to "bin\Debug\ServiceName.exe". The process cannot access the file 'bin\Debug\ServiceName.exe' because it is being used by another process. ServiceName
打开cmd,然后尝试先用taskkill /fi "services eq ServiceName" /f
来杀死它
如果一切正常, F5
应该足以进行debugging。
OnStart方法如下。
protected override void OnStart(string[] args) { try { RequestAdditionalTime(600000); System.Diagnostics.Debugger.Launch(); // put brake point here. ............. your code } catch (Exception ex) { ......... your exception code } }
然后以pipe理员身份运行命令提示符,并提出以下
c:\> sc create test-xyzService binPath= <ProjectPath>\bin\debug\service.exe type= own start= demand
上面一行将在服务列表中创buildtest-xyzService
要开始服务,这会提示你在VS上登场。
c:\> sc start text-xyzService
停止服务
c:\> sc stop test-xyzService
删除或卸载
c:\> sc delete text-xyzService
Microsoft文章解释了如何在这里debuggingWindows服务,以及如果通过附加到进程进行debugging,任何人都可能会错过的部分。
以下是我的工作代码。 我遵循了微软build议的方法。
将此代码添加到program.cs
static void Main(string[] args) { // if block will execute when launched through Visual studio if (Environment.UserInteractive) { ServiceMonitor serviceRequest = new ServiceMonitor(); serviceRequest.TestOnStartAndOnStop(args); } else // This block will execute when code is compiled as windows application { ServiceBase[] ServicesToRun; ServicesToRun = new ServiceBase[] { new ServiceMonitor() }; ServiceBase.Run(ServicesToRun); } }
将此代码添加到ServiceMonitor类。
internal void TestOnStartAndOnStop(string[] args) { this.OnStart(args); Console.ReadLine(); this.OnStop(); }
现在进入项目属性,select“应用程序”选项卡,在debugging时select输出types作为“控制台应用程序”,或者在debugging时重新编译和安装服务时select“Windows应用程序”。