为什么ASP.NET编译器会在每个构建中重建所有二进制文件?

时间:2013-01-10 20:04:59

标签: c# asp.net .net aspnet-compiler

当我使用aspnet_compiler重新编译我的项目(asp.net,c#)时,即使没有更改代码,重建的二进制文件也会更改(与之前的版本相比)。

据我所知,这是因为构建每次构建时都会生成一个新的模块版本ID(guid)(以区分构建),另一个类似的问题是:Can i specify the module version id (MVID) when building a .net assembly?

以上链接的问题似乎表明没有办法重建项目,并且二进制文件与之前构建的相同的未更改代码匹配..好吧,很好,我理解 - 但为什么所有的二进制文件都在重建?

我认为,根据文档(http://msdn.microsoft.com/en-us/library/ms229863(v=vs.80).aspx),除非将-c指定为参数,否则aspnet_compiler应该只重建那些实际需要的二进制文件(由于代码更改)。我误解了或者错过了什么吗?

我正在使用的aspnet_compiler参数:

aspnet_compiler -f -u -fixednames -nologo -v / -p .\myproject\ .\mybuild\

请注意,此问题仅适用于WebSite项目,而不是Web应用程序项目(它们的编译方式不同)。 即使您创建一个没有任何功能的WebSite项目和页面,也会出现此问题,并且永远不会打开它或在构建之间以任何方式更改它。

反编译生成的二进制文件显示没有差异。比较两个“相同”构建的二进制文件,每次在同一部分二进制文件中显示出小的差异 - 我相信这可能与随机构建guid有关。我发现在构建之间没有办法避免这种变化。

2 个答案:

答案 0 :(得分:2)

查看Eric Lippert关于C#编译器如何进行多遍编译源代码的优秀answer。尽管功能相同,但是为什么您的构建与前一个版本不同,可能有很多原因。

  • 编译器会替换特殊语言功能,例如使用带有IL等效的块
  • 编译器会对您的代码进行许多优化,每次迭代可能会产生稍微不同的输出。
  • 编译器必须为匿名方法名称创建实体化名称,并且每次编译时它们都不同。
  • 还有更多理由可以通过拆卸器轻松解决问题

查看这些拆解器并对您的库或可执行文件进行反编译以获得更好的理解 http://ilspy.net/http://www.telerik.com/products/decompiler.aspx

答案 1 :(得分:0)

我发现在许多情况下使用aspnet_compiler尤其是在我的项目在同一解决方案中引用其他项目导致完全重建的情况下,这通常很难解释。 (虽然我调查的几次都有“变化”,即使它们没有真正起作用,如改变空白,评论等)

我在visual studio中的一些插件也遇到了问题,这些插件已经完成了操作制表和其他空白区域,实际项目文件等所做的一切。虽然这些更改对我们人类没有明显的改变,但编译器需要一看就知道“我看到了变化!REBUILD ALL THE THINGS!!!

不确定我的答案是否有任何帮助,但我会禁用你的插件,运行编译器,然后再次运行编译器,看看会发生什么......