如何使用 C# 中的 Windows 服务跟踪给定进程是不是引发异常
Posted
技术标签:
【中文标题】如何使用 C# 中的 Windows 服务跟踪给定进程是不是引发异常【英文标题】:how to track if a given process throws exception, using windows service in C#如何使用 C# 中的 Windows 服务跟踪给定进程是否引发异常 【发布时间】:2011-01-12 10:28:24 【问题描述】:我的进程有时会在启动后抛出 dllnotfound 之类的异常。我有一个监控服务负责维护流程的一致状态。
如何使用 Windows 服务跟踪我的进程状态。
是否有 Windows 服务的开源实现来维护/跟踪 Windows 中的进程状态。
【问题讨论】:
【参考方案1】:这是不可能的,异常首先是线程本地的,如果未处理,则对于进程是次要的。未处理的异常将终止进程。您可以从这样一个死进程中拾取的唯一弹片是进程退出代码。应设置为 0xe0434f4e,即非托管异常的异常代码。没有其他相关信息可用,除非在记录状态的进程中有未处理的异常处理程序。那个状态很不靠谱,这个过程严重心脏病发作。
保持多个进程同步并在它们可能死于异常时正常运行是非常困难的。只有死亡才能被可靠地检测到,避免做更多的事情。
【讨论】:
是的,但如果找不到 dll,进程会弹出一个消息框并等待用户关闭它。同时进程的状态是running,是否可以让进程不弹出消息框而死掉。 真的很重要吗?除非有人将 DLL 放在正确的位置,否则它永远不会正常工作。有人会在他们点击 OK 10 次左右后。 Anyhoo,也许 SetErrorMode() 来抑制消息框。 dllnotfoundexception 只是一个例子,我不希望进程卡住并且监视器认为它仍在运行,如果进程遇到异常它应该就死了,所以监视器可以重新启动一个新实例过程。整个过程/监视器无需用户干预即可运行。没有人可以点击确定:( 你需要一个更好的例子。但是,每当进程决定放置一个消息框时,都会有人点击它。如果不希望这样做,那么您应该真的考虑不要使用多个进程。【参考方案2】:编辑:所以实际的问题不是进程正在死亡,而是进程卡在等待用户点击调试或取消的异常处理程序对话框中。该问题的解决方案是禁用 .net JIT 调试对话框,此处的说明 http://weblogs.asp.net/fmarguerie/archive/2004/08/27/how-to-turn-off-disable-the-net-jit-debugging-dialog.aspx
我最初提出的解决方案如下
不是窗口服务,但这是一个非常容易编写的 .NET 程序。
使用System.Diagnostics.Process 获取您要检查的进程的进程对象。如果要打开现有进程,可以使用GetProcessByName
。如果您从 C# 创建流程,那么您将已经拥有流程对象。
然后你可以WaitForExit
对Process
对象设置或不设置超时。或测试HasExited
属性,或注册Exited
回调。进程退出后,您可以检查ExitCode
属性以了解进程是否返回错误值。
【讨论】:
是的,我从 c# 开始了这个过程。当进程抛出异常时,它的状态正在运行,我每 10 秒检查一次 hasexited() 属性,但状态没有退出。该进程抛出 dllnotfound 异常并询问我想启动调试器的天气。 你有目标进程的代码吗?如果您想对异常之前执行任何操作,则需要在目标进程中执行代码,它会导致进程退出。 更改目标进程代码将是我最后的手段,是否有一些设置会阻止窗口在进程抛出异常(如 dllnotfound)时弹出消息框。如果我能想办法在出现错误时自动关闭弹出框,进程就会终止,否则它会继续运行 @Kazoom:您可以禁用调试器msdn.microsoft.com/en-us/library/5hs4b7a6(VS.80).aspx,但此更改将影响所有进程,而不仅仅是您关心的进程。 谢谢没用,但似乎我找到了另一个类似的解决方案bit.ly/9lj4vG【参考方案3】:让您的进程将事件和异常写入系统的应用程序日志,并让您的监视器定期检查条目以查找与您的进程相关的事件,并且您可以检查系统事件中的服务启动和停止事件。
如果进程本身是一个windows服务,你可以使用`System.ServiceProcess.ServiceController'来检查它的状态。
【讨论】:
【参考方案4】:暂时有效
http://weblogs.asp.net/fmarguerie/archive/2004/08/27/how-to-turn-off-disable-the-net-jit-debugging-dialog.aspx
【讨论】:
【参考方案5】:对于 DllNotFoundException 和其他在启动时发生的情况,您可以让应用程序指示它何时完成启动。例如,让它将时间戳写入文件。您的监视器可以将应用程序启动的时间与文件中的时间进行比较。
【讨论】:
【参考方案6】:您可以做的一件事是监控进程的 CPU 使用率。我假设抛出异常时您的进程消失了。因此,该进程的 CPU 使用率应该为 0,因为它不再可用。因此,如果 CPU 使用率在一段时间内保持为零,您可以放心地假设该进程已引发异常。这种方法不是万无一失的,因为您的决定是基于 CPU 使用率,而合法进程在给定时间段内的 CPU 使用率可能为零。您可以将此检查合并到您的监控服务中,或者您可以编写一个简单的 VB 脚本来从外部检查进程 CPU 使用情况。
【讨论】:
以上是关于如何使用 C# 中的 Windows 服务跟踪给定进程是不是引发异常的主要内容,如果未能解决你的问题,请参考以下文章
在退出之前跟踪 - 并正确结束 - C# - C++/CLI - C++ Windows 窗体应用程序中的本机和托管线程
通过 Git 远程跟踪分支的给定名称如何找到哪个本地分支跟踪它?
如何在基于 C# 的复杂 Windows 服务中找到内存使用率高的原因?