如何卸载使用ngen生成的旧的.net本机映像而不匹配IL程序集?

时间:2013-10-15 14:58:40

标签: .net .net-4.0 .net-assembly ngen

我正在开发的应用程序上运行“ngen install ...”。但是在这些程序集被覆盖之前,没有在某些版本/方案(调试等)上运行“ngen uninstall ...”。现在,我在“C:\ Windows \ assembly \ NativeImages_v4.0.30319_64 \ AssemblyName \ hashkey”格式的文件夹中看到许多* .ni.exe和* .ni.dll。 (dll也是内部开发的。)

我正在使用.Net 4。

无论如何要卸载这些?我试过“ngen update”它似乎没有触及这些孤立的原生图像。当然我可以手动删除它们,但它会扰乱我的程序集所依赖的系统dll上的引用计数,或者对.net系统造成更糟糕的后果。

除了占用空间之外,这些较旧的程序集会损害启动延迟,因为程序集绑定程序试图将当前IL与每个本机程序集进行匹配。

还有更好的方法来查看本机映像缓存中的内容而不是使用命令行吗?

由于

2 个答案:

答案 0 :(得分:5)

虽然这个问题已经有了答案,但如果你想删除陈旧(旧)的ngen'ed程序集,还需要考虑一些事项。

  • 确保检查NGen是否认为已安装并在执行ngen display时使用相同的NGen(CLR版本,32位/ 64位)。使用ngen display yourasm.dll将不起作用(在文件名上),但ngen display AssemblyName将(内部程序集名称)。您可以使用部分名称。
  • 使用ngen uninstall时,请按照安装它们的相反顺序卸载它们。不会卸载依赖项,但如果在安装依赖程序集之前手动安装了依赖项,则需要首先卸载依赖程序集:

    • 如果A取决于B而C和B取决于C,那么你做了:

      ngen install B
      ngen install C
      ngen install A
      

      然后您只能通过执行以下操作卸载它们:

      ngen uninstall A  // removes A, if nothing is dependent on it
      ngen uninstall C  // removes C, it has no dependencies now
      ngen uninstall B  // removes B, it has no dependencies now
      
    • 如果您不确定依赖项,请检查ngen display asmname的输出,它将列出“ROOT”下的依赖项。首先必须删除那里的任何东西

    • 如果其他应用程序使用您的任何文件,则需要先卸载该文件
    • 如果发现使用以下命令检查c:\windows\assembly\NativeImages_v4.0.30319_64(以及*_32版本)是否有用,是否仍然安装:

      dir | findstr "AsmName"
      

      由于这里有这么多文件,它有助于查看仍然存在的内容。它还有助于找出它们属于哪个版本(32位,64位,MSIL)。它似乎没有帮助他们放在那里。

  • 我注意到c:\windows\assembly文件夹的Windows资源管理器视图没有显示ngen的程序集,但没有显示GAC中的程序集。但是,如果您的程序集也在GAC中,您可以通过右键单击然后选择“卸载”从GAC和NGen缓存中卸载它。

除了上述内容之外,还有很多过时的ngen'ed图像,不会影响性能。 CLR根据程序集名称(名称,版本,公钥令牌)和其他一些启发式(文件日期,内部创建日期,哈希)将文件存储在此处。它甚至不会触及你原来的ngen'ed图像。您可以使用Process Monitor来验证这一点(它只会尝试根据哈希等从一个位置加载ngen的图像)。但是我同意,不得不把它们放在一边是令人讨厌的。

答案 1 :(得分:1)

ngen uninstall AssemblyName应该有效。 AssemblyName可以是部分或完整的程序集名称。