我最近在公司买了一台新电脑,不得不重新安装开发工具等。这台电脑运行的是 Windows XP(哎呀),我安装了 Visual Studio 2010 和 .NET Frameworks 2.0、3.5 和 4.0,每个都带有所有当前的服务包和补丁。Windows XP 本身也是最新的(如果可以这么说的话 :-)
我注意到一个反复出现的问题是以下对话框,它往往会弹出机器已经闲置的就一点点:
我怀疑崩溃是由于 .NET Framework 在后台执行系统程序集的 Ngen 编译,并且在到达某个特定程序集时崩溃。
我发现又提及在 MSDN 论坛上,有人建议将 Windows XP 的数据执行保护功能配置为“仅为基本 Windows 程序和服务启用 DEP”。然而,那是已经该设置在我的 PC 上有效。
我该如何进一步诊断?当我尝试附加到该进程时,它已经消失了。
还有其他建议或可能的解决方法吗?
更新:
我在命令提示符下运行了以下命令: ngen executequeueditems
..现在我可以可靠地重现问题,而不必等待空闲后台 ngen 执行。
因此,当ngen.exe
到达以下条目时:
Compiling assembly Microsoft.SqlServer.Management.MultiServerConnection, Version=10.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91 (CLR v2.0.50727) ...
WARNING: Cannot hardbind to mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 because dependency does not have a native image (check FusLogVw for reason)
Failed to generate native code for dependent image Microsoft.SqlServer.Management.MultiServerConnection, Version=10.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91 because of the following error: The remote procedure call failed. (Exception from HRESULT: 0x800706BE)
...结果是以下错误对话框:
然而,其他无法生成本机映像的程序集实际上并没有导致碰撞,只是一条错误信息。
因此,失败的具体程序集是:Microsoft.SqlServer.Management.MultiServerConnection。
我还能做什么?我并不特别关心此时是否可以 ngen;我只是想停止上面这个烦人的重复错误对话框。我已经尝试过了:
ngen uninstall Microsoft.SqlServer.Management.MultiServerConnection
,
...但它说“错误:未安装指定的程序集。”
有没有办法从 ngen 中删除程序集队列,那么 ngen 甚至不会尝试为其生成本机图像?
答案1
Sql Server 程序集的 nGen 失败因为之前尝试生成 .Net Framework 2.0 mscorlib 程序集失败。这与 .Net 4 完全无关,所以我建议您不要再查看它的 ngen 服务(2 和 4 使用它们自己的服务)。
至于为什么会失败——网上没有太多关于这方面的资料。我确实找到了MSDN 论坛上不过 - 其中有一些关于确认 mscorlib 是否已被正确 nGen 的内容 - 我会检查一下。
有趣的是,该线程中也提到了 Sql Server;尽管它是 2005 年的,但我认为您在此处讨论的第 10 版程序集是 Sql 2008。不过,可能会提供一些东西。
但最终如果这是我的机器我会:
卸载 .Net 2.0、3.0 和 3.5(如果你够勇敢,也可以卸载 4.0)
卸载包含导致 nGen 失败的程序集的任何 Sql Server 组件。
安装.Net 3.5 sp1redist;确保你也得到了热修复这也可供页面下方参考。
等待所有 nGeneration 完成后再继续。
如果您卸载了.Net 4,请现在重新安装它。
重新安装步骤2中删除的Sql Server组件。
是的,我知道,这有点像“关闭再打开”的答案 - 但我认为这比试图回避问题要好。如果 mscorlib 2.0 没有正确 nGen,那么坦白说,.Net 2.0 在当前状态下实际上不可用。而且由于这是一个尝试 nGen 的 SQL Server 组件 - 只有 nGen 的 mscorlib v2 才能使用它(nGen 的 mscorlib v4 则不行)。
答案2
mscorsvw.exe
可以看作是一个微软程序,并且仍然从 DEP 中获利,你可以检查它是否真的关闭了进程探索器。可以通过添加 DEP 列或检查进程的属性。
Visual Studio(至少对我来说)对于调试崩溃来说并不方便,你最好获取一个转储,以便我们可以尝试查看可能的原因。你可以使用安装默认调试器drwtsn32.exe -i
。或者如果你想学习,你可以使用数据库管理软件,它允许您更详细地分析崩溃的程序。不过,如果您对此不感兴趣的话,这还是挺有用的……
我怀疑崩溃是由于 .NET Framework 在后台执行系统程序集的 Ngen 编译,并且在到达某个特定程序集时崩溃。
ngen.exe
那么就不会崩溃了?你能确认它ngen.exe
正在运行吗?
你可以设置进程监控这样它只显示进程/线程的启动/停止,以便您可以看到运行了什么,只需让它运行一段时间,并在获得该调试窗口后再查阅。
答案3
“仅为必要的 Windows 程序和服务启用 DEP”。
由于 mscorsvw.exe 是一项服务,因此这实际上不会影响它。
我该如何进一步诊断?
查看 ngen 日志文件。它们可能位于各种文件夹中,例如 C:\Windows\Microsoft.NET\Framework\v4.0.30319 或您安装的任何框架版本。
答案4
Mscorsvw.exe 是与 Microsoft .NET 框架相关的进程。Mscorsvw 进程用于在后台预编译 .Net 框架程序集。
仅当在安装 .NET Framework 可再发行组件后需要编译最高优先级程序集并且安装了使用 .NET Framework 的应用程序以编译其程序集时,Mscorsvw.exe 进程才会在后台运行。
通常,mscorsvw.exe 进程将在 5 到 10 分钟内预编译高优先级程序集,然后当您的计算机空闲时,它将尝试处理低优先级程序集。
禁用或停止 mscorsvw.exe
- 在 Windows 资源管理器中导航到
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727
。- 在运行框中输入 cmd 并按 Enter 键打开命令提示符。
- 现在我们需要在命令中指定上述路径,然后输入
ngen.exe executequeueditems
并按回车键。- 现在等待该过程预编译所有程序集,几分钟后它将完成。
现在您会发现任务管理器中没有 mscorsvw.exe 进程在运行。
您还可以随时使用此命令查看是否有任何内容排队等待执行:
ngen queue status
并且 :
ngen display
要清除所有排队项目,请执行以下操作:
ngen /delete *
要找出导致问题的程序集,日志文件可能有助于回答以下问题:
C:\Windows\Microsoft.NET\Framework\<version>\ngen.log
C:\Windows\Microsoft.NET\Framework\<version>\ngen_service.log
另外需要注意的是,您不需要 .NET Frameworks 2.0 和 3.5,因为 4.0 可以替代它们全部。