I\'m building/packing a web application in a build server, and it fails with the following message:
ASPNETCOMPILER error ASPCONFIG: The CodeDom provider t
In my case I had added an angular website to my solution which caused this error.
Resolved the error with following steps.
On the menu bar, choose Build > Configuration Manager.
In the Project contexts table, exclude the angular website (which contained node_modules)
In the Build column for the project, clear the check box.
Choose the Close button, and then rebuild the solution.
In my case, on a new machine, installed VS2017 and opened an asp.net core 1.1 web application from source control. The error showed up. I installed node.js and the project compiled.
In my scenario, I have to ship a Perl interpreter with my ASP.Net website (don't ask why I need Perl, and I'm sorry I do in advance!), and that included .c files that caused the aspnet_compiler.exe to error out, as others have mentioned being their problem. The perl directory is in my bin folder, and is required at runtime.
The trouble I found was when you attrib +H
the folder, it indeed was skipped by aspnet_compiler, but then wouldn't be in my publish output folder. So I had to hack it even more by hiding the folder, compile views, unhide folder, and then copy folder to the right location. This involved modifying the original AspNetPreCompile
task. See below:
<!-- 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>
DO NOT modify the original .targets file, copy this into your .csproj file as a child to the <project>
node.
Key takeaways:
Use Exec
command to attrib +H Directory
before running aspnet_compiler.exe via the AspNetCompiler task, and attrib -H Directory
afterwards.
Create an ItemGroup
to suck in all the files that still need to be copied.
Run the Copy
task, utilizing that ItemGroup
to put the files where they need to be in order for the rest of the publish task to include them. We get to use all of the variables that Microsoft made when authoring this Task, so we can use those here too.
Pro to modifying the original task: very little changes about the normal behavior, so it should still just work.
Possible con to modifying the original task: Microsoft might change this task in the future, making our copy out of date.
If you don't have my weird requirements, the simpler solution to hiding a folder is as follows:
<Target Name="Test" BeforeTargets="AspNetPreCompile">
<Exec Command="attrib +H Directory" />
</Target>
<Target Name="Test" AfterTargets="AspNetPreCompile">
<Exec Command="attrib -H Directory" />
</Target>
Answer inspired by the comment twamley made in Arthur Nunes answer.
Try doing the folowing.
Setting RequireTargetFramework to 4.0.
Link:ASPNETCOMPILER error ASPCONFIG: Could not load file or assembly 'Microsoft.VisualBasic.Activities.Compiler' or one of its dependencies
I solved it with deleting node modules folder then running npm i from git bash and not from VS2019 built in terminal.
This post gave me an important clue: apparently ASP.NET precompilation scans the project and output files and tries to compile every source file it finds in its way, despite its language (see here).
In the case, my web app depends on a project which includes some unmanaged dll along a ".h" file. These files are copied to the output directory ("Copy if newer") so I can pinvoke it at runtime.
It seems ASP.NET precompilation finds the ".h" and tries to compile it, even though there is no need of it. And, as I see it, it fails because my build server does not has the tools for the job (it looks like CppCodeProvider
comes with the .NET 2.0 SDK).
When I changed the project not to copy those files to the output directory, the build ran fine. I also tested copying the files, but with "PrecompileBeforePublish" set to false in the publish profile, and it also worked.
Now I have some options, but I don't like any of them:
Disable "PrecompileBeforePublish". I believe the main disadvantage of that is the app users experience will be slower on the first site access.
Try to exclude files from the output folder and add them again after pre-compilation. That seems a lot of work for something I shouldn't be worrying in first place.
Try to tell "aspnet_compiler.exe" to exclude the offending files/folder when executing. I don't know how to do it using the publish profile, because I only have control over "PrecompileBeforePublish". Also, it seems "aspnet_compiler.exe" does not offer that option (here and here).
I think for now I'll disable "PrecompileBeforePublish", because it seems a fast path with few caveats. But I believe there should be a better way to handle it, excluding folders or file types from precompilation using the publish profile.