roslyn compiler not copied to AspnetCompileMerge f

2020-03-09 18:38发布

问题:

I have a .NET MVC project that I'm trying to deploy using Jenkins.

I had been letting Jenkins run msbuild, then copying the resulting files out using RoboCopy. I wanted to switch to just use a publish profile. The publishing profile works fine on my local machine using Visual Studio, but on the Jenkins host it fails using msbuild.

The error it gives is

ASPNETCOMPILER : error ASPRUNTIME: Could not find a part of the path 'C:\Program Files (x86)\Jenkins\jobs\myProject\workspace\myProject\obj\Debug\AspnetCompileMerge\Source\bin\roslyn\csc.exe'. [C:\Program Files (x86)\Jenkins\jobs\myProject\workspace\myProject\calendar.csproj]

I'm using the Microsoft.Net.Compilers nuget package to pull in the C# compiler, because some of the collaborators on the project are still on Visual Studio 2013, but we're using C#6 language features in the project.

Thing is, the project built just fine using MSBuild on jenkins before I added the publish flag. It's only since adding the /p:DeployOnBuild=true;PublishProfile=MyProfile setting that it started failing... yet the publish step works fine from withing Visual Studio, and the roslyn compiler even gets copied to the obj\Debug\AspnetCompileMerge\Source\bin\ folder on my local machine. What gives?

Honestly, since msbuild14 is available on the Jenkins server, it probably doesn't even need the roslyn csc.exe file. Is there a way I can make msbuild ignore it?

My Publish Profile

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <WebPublishMethod>FileSystem</WebPublishMethod>
    <LastUsedBuildConfiguration>Debug</LastUsedBuildConfiguration>
    <LastUsedPlatform>Any CPU</LastUsedPlatform>
    <SiteUrlToLaunchAfterPublish />
    <LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
    <ExcludeApp_Data>False</ExcludeApp_Data>
    <publishUrl>\\myserver\someshare\mysite</publishUrl>
    <DeleteExistingFiles>True</DeleteExistingFiles>
    <PrecompileBeforePublish>True</PrecompileBeforePublish>
    <EnableUpdateable>True</EnableUpdateable>
    <DebugSymbols>False</DebugSymbols>
    <WDPMergeOption>DonotMerge</WDPMergeOption>
  </PropertyGroup>
</Project>

What I've Tried So Far

I've tried updating the compiler package.

Manually copying compiler

I added steps to my .csproj file to force-copy the missing compiler files to the AspnetCompileMerge directory (I'd already been copying them to the bin\roslyn directory to resolve another problem)

<Target Name="CopyRoslynFiles" AfterTargets="BeforeBuild">
  <ItemGroup>
    <RoslynFiles Include="$(SolutionDir)packages\Microsoft.Net.Compilers.1.1.1\tools\*" Exclude="$(SolutionDir)packages\Microsoft.Net.Compilers.1.1.1\tools\*.sys" />
  </ItemGroup>
  <MakeDir Directories="$(WebProjectOutputDir)\bin\roslyn" />
  <MakeDir Directories="$(WebProjectOutputDir)\obj\$(Configuration)\AspnetCompileMerge\Source\bin\roslyn" />
  <Copy SourceFiles="@(RoslynFiles)" DestinationFolder="$(WebProjectOutputDir)\bin\roslyn" SkipUnchangedFiles="true" Retries="$(CopyRetryCount)" RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)" />
  <Copy SourceFiles="@(RoslynFiles)" DestinationFolder="$(WebProjectOutputDir)\obj\$(Configuration)\AspnetCompileMerge\Source\bin\roslyn" SkipUnchangedFiles="true" Retries="$(CopyRetryCount)" RetryDelayMilliseconds="$(CopyRetryDelayMilliseconds)" />
</Target>

Turning off Updateability in the publish profile

Based on Wesley Rathburn's answer on a similar question, I tried making the precompiled site so it could not be updated in the publish profile:

<EnableUpdateable>False</EnableUpdateable>

Though this revealed some dead code that needed removed in my views, it didn't fix the error during the jenkins build.

Running MsBuild locally

I can successfully run the msbuild command on my local machine. It deploys to the server and everything. Here's the command I run in powershell:

&"C:\Program Files (x86)\MSBuild\14.0\Bin\MSBuild.exe" /p:Configuration=Debug "/p:DeployOnBuild=true;PublishProfile=MyProfile" myproject\myproject.csproj

Removing the statements that copy the compiler entirely

It occurred to me that maybe I didn't need the statements to copy the roslyn compiler to the bin folder anymore, since msbuild14 was available on Jenkins now (and I'm not sure it was when I first built the project). Sadly, same error occurs. It's looking for the roslyn\csc.exe file, even though there's no apparent need for it to do so!

回答1:

Just putting this here, because I spent two days trying to resolve this same issue (roslyn csc.exe not copied), but none of these answers solved my problem.

It turns out that Microsoft.CodeDom.Providers.DotNetCompilerPlatform 1.0.6 (and 1.0.7) is broken. Downgrade to 1.0.5.

I was getting the same errors as everyone else here, but I'm using VS 2017, and both local WebDeploy as well as AzureDeploy were broken (no csc.exe found). I tried all the suggestions that I could find on the internet (most of them redirect back to this SO post) but nothing worked until I downgraded to 1.0.5.

So I hope this is helpful to anyone who is struggling and has just recently upgrade to 1.0.6!

See: https://github.com/aspnet/RoslynCodeDomProvider/issues/13 and https://github.com/dotnet/roslyn/issues/21340



回答2:

So, the workaround I'm using for now (which I don't entirely like), is just to remove the dependencies on the Compilers and CodeDOM Compilers packages. I also had to clear out the references in the .csproj and web.config files. That involved removing those packages from a shared assembly as well.

This will break the project for people still using Visual Studio 2013, which I don't like, but it builds on my Jenkins host now, which I do like. If anyone has a better solution, I'd be happy to hear it.



回答3:

So yeah, I have this problem too with VS2017 & VS2019 and Microsoft.CodeDom.Providers.DotNetCompilerPlatform2.0.1 too. Did a lot of troubleshoooting msbuild and digging deep and trying to do my own workarounds and the changes in build file that just did nothing, but that didn't seem right at all. So I started looking in a different direction.

What I discovered was I couldn't build a .csproj directly and have either the nuget targets in Microsoft.CodeDom.Providers.DotNetCompilerPlatform get run by msbuild, or my own custom ones.

However using msbuild with the .sln with a target of myproj:Rebuild made everything work.