发布网站,aspnet_compiler null引用异常

时间:2014-07-07 17:58:01

标签: msbuild aspnet-compiler

我无法通过命令行发布解决方案。它在各种项目上间歇性地失败,但每次都经常成功。我得到空引用错误和“运行该线程的应用程序域已被卸载”,这可能只是具有竞争条件的空引用。它似乎只在具有Web服务的项目上失败(原始.asmx和带有.svc或无文件激活的WCF)。它有时成功的事实使我认为这不是我们的代码的问题,尽管我们可以做一些改变来减轻根本原因(无论可能是什么)。

我尝试/检查的内容:

  • 我运行tfpt scorch来清理任何本地更改,包括构建输出但没有成功,所以我知道这不是源目录的问题。
  • 我清除了C:\Windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files的临时文件(我们是32位)并且似乎进一步但仍有问题。在另一个发布之后,目录仍然是空的,因此可能不相关。
  • 使用Process Monitor,我发现aspnet_compiler正在写信给%LocalAppData%\Temp\Temporary ASP.NET Files。清除这些文件似乎有时可行或者我很幸运,但随后又开始失败。我没有发现任何可能相关的内容。
  • 确保我有足够的内存,似乎没有什么区别。
  • 运行msbuild单线程,没有区别
  • 从命令行运行aspnet_compiler(从MSBuild日志输出获取命令),总是成功
  • 没有压缩文件夹
  • 我正在使用最新的稳定Visual Studio(VS 2013更新2),但这应该无关紧要,因为我从命令行运行,并且使用的可执行文件位于框架目录中。
  • 某些失败项目中没有App_Code文件夹

构建输出没有提供任何好的信息,所以我设置DebugDiag在崩溃时输出。结果如下:

DetailID = 1
    Count:    1
    Type:     System.NullReferenceException
    Message:  
    Stack:    
        System.Web.Compilation.DiskBuildResultCache.CacheBuildResult(System.String, System.Web.Compilation.BuildResult, Int64, System.DateTime)
        System.Web.Compilation.BuildManager.CacheBuildResultInternal(System.String, System.Web.Compilation.BuildResult, Int64, System.DateTime)
        System.Web.Compilation.WebDirectoryBatchCompiler.CacheAssemblyResults(System.Web.Compilation.AssemblyBuilder, System.CodeDom.Compiler.CompilerResults)
        System.Web.Compilation.WebDirectoryBatchCompiler.CompileAssemblyBuilder(System.Web.Compilation.AssemblyBuilder)
        System.Web.Compilation.WebDirectoryBatchCompiler.CompileAssemblyBuilderParallel(System.Collections.ICollection)
        System.Web.Compilation.WebDirectoryBatchCompiler.CompileNonDependentBuildProviders(System.Collections.ICollection)
        System.Web.Compilation.WebDirectoryBatchCompiler.Process()
        System.Web.Compilation.BuildManager.BatchCompileWebDirectoryInternal(System.Web.Hosting.VirtualDirectory, Boolean)
        System.Web.Compilation.BuildManager.BatchCompileWebDirectory(System.Web.Hosting.VirtualDirectory, System.Web.VirtualPath, Boolean)
        System.Web.Compilation.BuildManager.PrecompileWebDirectoriesRecursive(System.Web.Hosting.VirtualDirectory, Boolean)
        System.Web.Compilation.BuildManager.PrecompileAppInternal(System.Web.VirtualPath, System.Collections.Generic.IEnumerable`1<System.String>)
        System.Web.Compilation.BuildManager.PrecompileApp(System.Web.VirtualPath, System.Collections.Generic.IEnumerable`1<System.String>)
        System.Web.Compilation.BuildManager.PrecompileApp(System.Web.Compilation.ClientBuildManagerCallback, System.Collections.Generic.IEnumerable`1<System.String>)
        System.Web.Compilation.BuildManagerHost.PrecompileApp(System.Web.Compilation.ClientBuildManagerCallback, System.Collections.Generic.List`1<System.String>)
        [GCFrame]
        [GCFrame]
        [ContextTransitionFrame]
        [GCFrame]
        [GCFrame]
        [GCSafeCollectionFrame]
        [GCSafeCollectionFrame]
        [GCSafeCollectionFrame]
        [GCSafeCollectionFrame]
        [GCSafeCollectionFrame]
        [GCSafeCollectionFrame]
        [GCSafeCollectionFrame]
        [TPMethodFrame]
        *** WARNING: Unable to verify checksum for C:\Windows\assembly\NativeImages_v4.0.30319_32\System.Web\3d247ccfb800c38a29cf91c27a6339da\System.Web.ni.dll
        Module load completed but symbols could not be loaded for C:\Windows\assembly\NativeImages_v4.0.30319_32\System.Web\3d247ccfb800c38a29cf91c27a6339da\System.Web.ni.dll
        System.Web.Compilation.ClientBuildManager.PrecompileApplication(System.Web.Compilation.ClientBuildManagerCallback)
        *** ERROR: Module load completed but symbols could not be loaded for C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_compiler.exe
        [GCFrame]


DetailID = 2
    Count:    1
    Type:     System.NullReferenceException
    Message:  Object reference not set to an instance of an object.
    Stack:    
        [GCFrame]
        [GCFrame]
        [GCFrame]
        [GCSafeCollectionFrame]
        [GCSafeCollectionFrame]
        [GCSafeCollectionFrame]
        [GCSafeCollectionFrame]
        [GCSafeCollectionFrame]
        [GCSafeCollectionFrame]
        [GCSafeCollectionFrame]
        [TPMethodFrame]
        System.Web.Compilation.ClientBuildManager.PrecompileApplication(System.Web.Compilation.ClientBuildManagerCallback, Boolean)
        System.Web.Compilation.ClientBuildManager.PrecompileApplication(System.Web.Compilation.ClientBuildManagerCallback)
        System.Web.Compilation.Precompiler.Main(System.String[])
        [GCFrame]

我发现其他人有类似的问题,但他们要么没有答案,要么解决方案对我不起作用。还有更多想法吗?

修改 这是我正在使用的命令行:

"C:\Program Files (x86)\MSBuild\12.0\bin\MSBuild.exe" Solution.sln /t:Build /m:1 /p:Configuration=Prod /p:Platform="Mixed Platforms" /p:DeployOnBuild=true /p:PublishProfile=Prod /p:AutoParameterizationWebConfigConnectionStrings=false /v:diag > out.txt

以下是一些控制台输出(重定向到文件):

Target "AspNetPreCompile: (TargetId:3773)" in file "C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v12.0\Web\Transform\Microsoft.Web.Publishing.AspNetCompileMerge.targets" from project "C:\Source\Project\Project.csproj" (target "PipelineAspNetCompileMergePhase" depends on it):
Task "AspNetCompiler" (TaskId:2474)
  Task Parameter:PhysicalPath=C:\Source\Project\obj\x86\Release\AspnetCompileMerge\Source (TaskId:2474)
  Task Parameter:TargetPath=C:\Source\Project\obj\x86\Release\AspnetCompileMerge\TempBuildDir (TaskId:2474)
  Task Parameter:VirtualPath=/ (TaskId:2474)
  Task Parameter:Debug=False (TaskId:2474)
  Task Parameter:Updateable=False (TaskId:2474)
  Task Parameter:ToolPath=C:\Windows\Microsoft.NET\Framework\v4.0.30319 (TaskId:2474)

  C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_compiler.exe -v / -p C:\Source\Project\obj\x86\Release\AspnetCompileMerge\Source C:\Source\Project\obj\x86\Release\AspnetCompileMerge\TempBuildDir  (TaskId:2474)
  Microsoft (R) ASP.NET Compilation Tool version 4.0.30319.34209 (TaskId:2474)
  Utility to precompile an ASP.NET application (TaskId:2474)
  Copyright (C) Microsoft Corporation. All rights reserved. (TaskId:2474)
   (TaskId:2474)
ASPNETCOMPILER : error ASPRUNTIME: Object reference not set to an instance of an object. [C:\Source\Project\Project.csproj]
  The command exited with code 1. (TaskId:2474)

Done executing task "AspNetCompiler" -- FAILED. (TaskId:2474)
Done building target "AspNetPreCompile" in project "Project.csproj" -- FAILED.: (TargetId:3773)

正如您所看到的,msbuild诊断输出不是很有帮助。

编辑2: 试着看看我是否可以调试aspnet_compiler以便更多地了解这一点。我启动了gflags.exe以启用自动附加到调试器。我能够突破NullReferenceException,但我无法加载System.Web的符号。它来自C:\Windows\Microsoft.Net\assembly\GAC_32\System.Web\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Web.dll

从堆栈跟踪中,它在此方法中失败:

internal override void CacheBuildResult(string cacheKey, BuildResult result, long hashCode, DateTime utcStart)
{
  if (!result.CacheToDisk)
    return;
  if (HostingEnvironment.ShutdownInitiated)
  {
    BuildResultCompiledAssemblyBase compiledAssemblyBase = result as BuildResultCompiledAssemblyBase;
    if (compiledAssemblyBase == null)
      return;
    this.MarkAssemblyAndRelatedFilesForDeletion(compiledAssemblyBase.ResultAssembly.GetName().Name);
  }
  else
    new PreservationFileWriter(this.PrecompilationMode).SaveBuildResultToFile(this.GetPreservedDataFileName(cacheKey), result, hashCode);
}

因此,其中任何一个都可能为null并导致异常:resultHostingEnvironmentcompiledAssemblyBase

3 个答案:

答案 0 :(得分:2)

我知道这是一个旧帖子,但万一有人会发现这个有用:

这个问题的原因是McAfee防病毒

ASPNETCOMPILER(0,0): Error ASPRUNTIME: Object reference not set to an instance of an object

答案 1 :(得分:1)

如果我要解决这个问题,我会尝试尽可能地隔离它,所以这是计划。

我看到以下可能的原因:

  1. 建筑环境

  2. 构建程序

  3. 编译器错误

  4. 源代码/项目结构过于复杂

  5. 在像你这样的大多数复杂情况下,所有因素都会起作用,因此逐个尝试隔离可能有所帮助,或者至少可能会显示更容易修复和继续的其他/新错误。

    构建环境

    您可以尝试在其他计算机或其他计算机上构建相同的项目(说构建我的意思是解决您的任务 - 从命令行发布网站)。如果您有相同的问题 - 它什么也没有显示,但如果其他环境没问题(或至少其中一个环境) - 那么您肯定会遇到环境问题。

    它可以是任何东西 - .Net版本和/或修复,操作系统版本,命令行的PATH变量使用不正确的框架,本地项目的路径中的空格 - 无论如何,但是如果你可以使它在其他机器上运行,你会知道你需要研究构建过程而不是其他东西。

    您可以尝试构建任何示例项目,以确保您可以发布简单项目。

    构建程序

    看起来你已经在发布步骤中已经隔离了这个问题,但你可以尝试使用它一点 - 只进行编译而不发布,或者在现有二进制文件/发布文件夹等上运行发布目标 - 你需要尝试隔离特定步骤(如果有)失败,排除其他构建步骤的依赖性。

    最有可能这不会有帮助,因为我希望整个过程失败 - 但谁知道呢。

    编译器错误

    这一个与下一个密切相关。如果在您的情况下可以尝试在VS2012而不是VS2013上构建。

    源代码/项目结构过于复杂

    预先构建解决方案中的所有项目,并使用对结果DLL的引用而不是对项目的引用。如果一切正常 - 逐个返回项目源,这样您至少可以理解哪个项目导致编译器失败。

    当/如果你已经隔离了一个项目,那么你可以尝试将它的一部分编译为单独的DLL,在某些情况下你可能会意识到应该重写一些特定的代码结构/标记以满足编译器。

    如果问题出现在web项目或某些其他项目类型中,而这些项目根本无法编译为单个DLL,则可以尝试关闭&#34;项目的整个部分 - 比如,用网页排除几个文件夹并检查结果。

    希望这会有所帮助,但可以肯定的是,所有这些步骤都需要付出巨大努力来解决问题;但在大多数情况下,孤立的特定问题解决了问题的重要部分。

答案 2 :(得分:1)

删除-u选项应该有效,因为它对我有用。