我的方案,我需要装运Perl解释器与我的ASP.Net网站(不要问我为什么需要Perl和我很抱歉,我提前做的!),那包含导致aspnet_compiler.exe出错的.c文件,正如其他人提到的那样是他们的问题。 perl目录位于我的bin文件夹中,并且在运行时是必需的。
我发现的麻烦是当你attrib +H
该文件夹,它确实被aspnet_compiler跳过,但是不会在我的发布输出文件夹中。所以我不得不通过隐藏文件夹,编译视图,取消隐藏文件夹,然后将文件夹复制到正确的位置来进一步破解它。这涉及修改原始的AspNetPreCompile
任务。请看下图:
<!-- Overwrite AspNetPreCompile task because it was trying to compile .c files found in the Perl directory. This prevents that but still copies Perl to publish file. -->
<!-- Taken from: C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\Microsoft\VisualStudio\v15.0\Web\Transform -->
<Target Name="AspNetPreCompile" DependsOnTargets="$(AspNetPreCompileDependsOn)" Condition="'$(AspNetPreCompile)' != 'false'">
<PropertyGroup Condition="'$(UseMetabasePath)' == 'true'" >
<_PreAspnetCompileMergeSingleTargetFolderFullPath></_PreAspnetCompileMergeSingleTargetFolderFullPath>
<_AspNetCompilerVirtualPath></_AspNetCompilerVirtualPath>
</PropertyGroup>
<PropertyGroup Condition="'$(UseMetabasePath)' != 'true'" >
<_PreAspnetCompileMergeSingleTargetFolderFullPath>$([System.IO.Path]::GetFullPath($(_PreAspnetCompileMergeSingleTargetFolder)))</_PreAspnetCompileMergeSingleTargetFolderFullPath>
</PropertyGroup>
<PropertyGroup>
<_PostAspnetCompileMergeSingleTargetFolderFullPath>$([System.IO.Path]::GetFullPath($(_PostAspnetCompileMergeSingleTargetFolder)))</_PostAspnetCompileMergeSingleTargetFolderFullPath>
</PropertyGroup>
<!-- Modification #1. -->
<Exec Command="attrib +H "$(IntermediateOutputPath)AspnetCompileMerge\Source\bin\perl"" />
<AspNetCompiler
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="$(AspnetCompilerPath)"
/>
<!-- Modification #2. -->
<Exec Command="attrib -H "$(IntermediateOutputPath)AspnetCompileMerge\Source\bin\perl"" />
<!--
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>
<!-- Modification #3. -->
<ItemGroup>
<Perl Include="$(IntermediateOutputPath)AspnetCompileMerge\Source\bin\perl\**\*.*" />
</ItemGroup>
<!-- Modification #4. -->
<Copy SourceFiles="@(Perl)" DestinationFolder="$(_PostAspnetCompileMergeSingleTargetFolderFullPath)\bin\perl\%(RecursiveDir)"></Copy>
</Target>
不修改原文件.targets,作为一个孩子复制到您的.csproj文件,这给<project>
节点。
关键要点:
使用Exec
命令attrib +H Directory
通过AspNetCompiler任务运行aspnet_compiler.exe之前和之后attrib -H Directory
。
创建一个ItemGroup
吸收所有仍需要复制的文件。
运行Copy
任务,利用ItemGroup
将文件放在需要的位置,以便发布任务的其余部分包含它们。我们可以使用Microsoft在创作此任务时所做的所有变量,因此我们也可以在这里使用这些变量。
修改原始任务的专业版:对正常行为的改动非常小,所以它应该仍然可以正常工作。
可能会修改原始任务:Microsoft可能会在将来更改此任务,使我们的副本过期。
如果没有我奇怪的要求,简单的解决方案,以隐藏的文件夹如下:
<Target Name="Test" BeforeTargets="AspNetPreCompile">
<Exec Command="attrib +H Directory" />
</Target>
<Target Name="Test" AfterTargets="AspNetPreCompile">
<Exec Command="attrib -H Directory" />
</Target>
答案由亚瑟·努涅斯答案提出的意见twamley启发。
我的天啊! - 非常感谢你这篇文章 - 你可能救了我几天的挫折,因为这正是我们发生的事情。你有没有找到一种方法来忽略文件夹? (尽管我的第一选择是从回购中删除违规文件。) – Edward
不,爱德华,我必须保持“预编译前发布”禁用。然而,在这个问题发生后不久我就停止了关于这个项目的工作,所以也许答案仍然在某处=] –
@爱德华我也遇到了这个问题。到目前为止,我运行aspnet_compiler.exe之前,在我的构建脚本中使用hidden属性('attrib + H c:\ path \ to \ problem \ directory')标记了我的没有编译必需的文件夹,然后重置隐藏的属性当它完成。 – twamley