无法将预编译的合并webapp部署到azure

s5a0g9ez  于 2021-06-20  发布在  Kudu
关注(0)|答案(2)|浏览(348)

我正在尝试将asp.net web应用程序部署到azure。它是web表单、mvc和webapi的混合体,并且有大量的aspx/ascx文件,因此它们确实需要进行预编译,否则每次部署都会使站点在一段时间内变得迟钝。
我正在尝试通过scm与github的集成来部署,通过kudu,使用预编译视图,所有视图都合并到一个程序集。
请注意:
deploy可以在禁用预编译的情况下正常工作。
在visualstudio中部署工作正常
如果我从azure日志中复制msbuild命令,替换相关路径,并在我的windows8.1计算机上本地运行它,则构建工作正常。
我已将高级预编译设置设置为:
不允许预编译站点可自定义
不发出调试信息
将所有页面和控件输出合并到单个程序集=appviews.dll
这是azure的.deployment文件

[config]
project = WebSite/WebSite.csproj
SCM_BUILD_ARGS=/p:Configuration=Release;PublishProfile=azure-prod /v:n

你注意到我发的是冗长的 /v 至“正常”以获取更多诊断信息。
下面是我在部署日志末尾得到的信息:

AspNetPreCompile:
  D:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_compiler.exe -v \ -p D:\home\site\repository\WebSite\obj\Release\AspnetCompileMerge\Source -c D:\home\site\repository\WebSite\obj\Release\AspnetCompileMerge\TempBuildDir 
GenerateAssemblyInfoFromExistingAssembleInfo:
  Creating directory "obj\Release\AssemblyInfo".
  D:\Windows\Microsoft.NET\Framework\v4.0.30319\Csc.exe /out:obj\Release\AssemblyInfo\AssemblyInfo.dll /target:library Properties\AssemblyInfo.cs
AspNetMerge:
  Running aspnet_merge.exe.
  D:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools\aspnet_merge.exe D:\home\site\repository\WebSite\obj\Release\AspnetCompileMerge\TempBuildDir -w AppViews.dll -copyattrs obj\Release\AssemblyInfo\AssemblyInfo.dll -a  
aspnet_merge : error 1003: The directory 'D:\home\site\repository\WebSite\obj\Release\AspnetCompileMerge\TempBuildDir' does not exist. [D:\home\site\repository\WebSite\WebSite.csproj]
Done Building Project "D:\home\site\repository\WebSite\WebSite.csproj" (Build;pipelinePreDeployCopyAllFilesToOneFolder target(s)) -- FAILED.

Build FAILED.

它看起来像是aspnet\u compiler.exe在运行,但并没有执行它应该执行的操作,这就是为什么tempbuildir目录(应该是编译器的输出)没有及时存在于aspnetmerge目标中的原因。与我的系统相比,这个目录确实存在,包含标记aspx/ascx/etc.文件、静态内容、一个precompiledapp.config文件以及bin目录中的一堆东西。
aspnet\u compiler.exe具有 -errorstack 但我不清楚如何让msbuild通过 .deployment 文件,或者即使那个应用程序真的抛出了一个错误。
我可以直接通过visualstudio进行部署,但是我真的很想利用scm集成,这样我就可以直接推到prod分支并让它走了。有什么建议吗?

mitkmikd

mitkmikd1#

我的回答是https://github.com/projectkudu/kudu/issues/1341,但是把我的答案抄在这里以防有人登陆这里。。。
回到以前,我们发现aspnet\u compiler.exe在azure网站中无法工作,因为它是如何处理配置文件文件夹的。我们当时做了一个改变,这有点像黑客,但让我们走了:我们把它变成了一个禁止行动,通过指向 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\aspnet_compiler.exe 我们自己的傀儡( D:\Program Files (x86)\aspnet_compiler\KuduAspNetCompiler.exe ).
但现在尝试一下,它似乎能正常工作今天,可能是由于在azure网站托管环境的改进。因此,我们将尝试摆脱这个黑客和做一个完整的测试通过,以确保它不会造成任何重大倒退。如果一切顺利,我们可以将其投入生产,这将使这些场景成为可能。
短期内,您可以通过使用构建脚本来解决此问题:
从复制aspnet\u compiler.exe D:\Windows\Microsoft.NET\Framework\v4.0.30319 你自己的网站文件,但用不同的名称(例如。 aspnet_compiler2.exe )
说服msbuild使用这个

bogh5gae

bogh5gae2#

注意:projectkudu上的这个github问题最终会使这个解决方案过时,但同时,这个问题作为backlog归档,现在就可以工作了。
谢谢谢谢大卫艾博。有了这些信息,我可以引导我的构建在短期内工作。
首先,我使用位于的诊断控制台从azure示例下载了aspnet\u compiler.exe https://{WEBSITE_NAME}.scm.azurewebsites.net/DebugConsole 并将其添加到我自己的存储库中。这样,32/64位之间就没有任何区别了,我把它改名为 azure_aspnet_compiler.exe 在我的存储库中。
其次,aspnetcompiler任务没有提供更改工具名称的选项。它是硬编码的,但是作为一个虚拟财产,所以它是可重写的。因此,我必须创建自己的任务类,并将其打包到自己的程序集中,该程序集是在发布模式下构建的,也包含在我的存储库中。

public class AzureAspNetCompiler : Microsoft.Build.Tasks.AspNetCompiler
{
    private string _toolName = "aspnet_compiler.exe";

    protected override string ToolName
    {
        get { return _toolName; }
    }

    public string CustomToolName // Because ToolName cannot have a setter
    {
        get { return _toolName; }
        set { _toolName = value; }
    }
}

接下来我需要更换 AspNetPreCompile 任务,但我不知道如何直接执行。但是这个任务什么也做不了,所以为什么不紧跟着它跑呢?
我把这个加到了我的头上 Website.csproj 导入包含 AzureAspNetCompiler 班级。请注意,路径是相对于 Website.csproj 我正在编辑的文件。

<UsingTask TaskName="AzureBuildTargets.AzureAspNetCompiler"
           AssemblyFile="..\DeploymentTools\AzureBuildTargets.dll" />

然后我在它的正下方添加了这个,它基本上窃取了的msbuild目标定义 AspNetPreCompileC:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0\Web\Transform\Microsoft.Web.Publishing.AspNetCompileMerge.targets ,去掉了它顶部附近的一些属性设置内容(因为原始任务无论如何都会为我们完成) ToolPath 以及 CustomToolName 属性底部的值(重命名) AzureAspNetCompiler 元素。

<PropertyGroup>
        <!--Relative to solution root apparently-->
        <LocalRepoDeploymentTools>.\DeploymentTools</LocalRepoDeploymentTools>
        <AzureAspnetCompilerPath>$([System.IO.Path]::GetFullPath($(LocalRepoDeploymentTools)))</AzureAspnetCompilerPath>
</PropertyGroup>

<Target Name="NoReallyAspNetPreCompile" AfterTargets="AspNetPreCompile">

<AzureAspNetCompiler
  PhysicalPath="$(_PreAspnetCompileMergeSingleTargetFolderFullPath)"
  TargetPath="$(_PostAspnetCompileMergeSingleTargetFolderFullPath)"
  VirtualPath="$(_AspNetCompilerVirtualPath)"
  Force="$(_AspNetCompilerForce)"
  Debug="$(DebugSymbols)"
  Updateable="$(EnableUpdateable)"
  KeyFile="$(_AspNetCompileMergeKeyFile)"
  KeyContainer="$(_AspNetCompileMergeKeyContainer)"
  DelaySign="$(DelaySign)"
  AllowPartiallyTrustedCallers="$(AllowPartiallyTrustedCallers)"
  FixedNames="$(_AspNetCompilerFixedNames)"
  Clean="$(Clean)"
  MetabasePath="$(_AspNetCompilerMetabasePath)"
  ToolPath="$(AzureAspnetCompilerPath)"
  CustomToolName="azure_aspnet_compiler.exe"
    />

<!--
    Removing APP_DATA is done here so that the output groups reflect the fact that App_data is
    not present
    -->
<RemoveDir Condition="'$(DeleteAppDataFolder)' == 'true' And Exists('$(_PostAspnetCompileMergeSingleTargetFolderFullPath)\App_Data')"
           Directories="$(_PostAspnetCompileMergeSingleTargetFolderFullPath)\App_Data" />

<CollectFilesinFolder Condition="'$(UseMerge)' != 'true'"
  RootPath="$(_PostAspnetCompileMergeSingleTargetFolderFullPath)" >
  <Output TaskParameter="Result" ItemName="_AspnetCompileMergePrecompiledOutputNoMetadata" />
</CollectFilesinFolder>

<ItemGroup Condition="'$(UseMerge)' != 'true'">
  <FileWrites Include="$(_PostAspnetCompileMergeSingleTargetFolderFullPath)\**"/>
</ItemGroup>

有了这个,一切都如我所愿。

相关问题