We have a web application, that makes heavily use of dynamic code compilation. I have the task to add C#6 features and make use of the roslyn compiler.
Doing that was pretty simple. Just add the nuget package
- Microsoft.CodeDom.Providers.DotNetCompilerPlatform:2.0.0
to all projects that make use of the dynamic code compilation and change one line of code
private static System.CodeDom.Compiler.CodeDomProvider Compiler => compiler
?? (compiler =
new
Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider());
Everything works so far. After adding the nuget package to the unit tests that made use of the dynamic code compilation, they are working also (localy).
But when i query a new Build on VSTS/TFS Server some unit tests failed. After some research i found the problem:
System.IO.DirectoryNotFoundException: Could not find a part of the path 'D:\Agents\agent_work\1\a\roslyn\csc.exe'. at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost) at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share) at Microsoft.CodeDom.Providers.DotNetCompilerPlatform.Compiler.get_CompilerName() at Microsoft.CodeDom.Providers.DotNetCompilerPlatform.Compiler.FromFileBatch(CompilerParameters options, String[] fileNames) at Microsoft.CodeDom.Providers.DotNetCompilerPlatform.Compiler.FromSourceBatch(CompilerParameters options, String[] sources) at Microsoft.CodeDom.Providers.DotNetCompilerPlatform.Compiler.CompileAssemblyFromSourceBatch(CompilerParameters options, String[] sources) at System.CodeDom.Compiler.CodeDomProvider.CompileAssemblyFromSource(CompilerParameters options, String[] sources) at [...]
Well, the project root is the wrong place to look for the roslyn binaries.
In the app.config of the related unit tests:
<appSettings>
<add key="aspnet:RoslynCompilerLocation" value="roslyn" />
</appSettings>
<system.codedom>
<compilers>
<compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:1659;1699;1701" />
<compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:41008 /define:_MYTYPE=\"Web\" /optionInfer+" />
</compilers>
</system.codedom>
I tried also to the nuget package Microsoft.CodeDom.Providers.DotNetCompilerPlatform.BinFix
without success. I found a lot of information, how to fix the /bin/roslyn error, but nothing about that special combination of build server, unit tests and roslyn. Somebody has more information?
EDIT:
I tried the suggested solution from Jayendran. I found out that the variables $(CscToolPath) and $(WebProjectOutputDir) were empty like so:
<Target Name="CheckVariables" AfterTargets="AfterBuild" Condition="'$(OutDir)' != '$(OutputPath)'">
<Message Text="$(OutDir)" Importance="high"/>
<Message Text="$(OutputPath)" Importance="high"/>
<Message Text="$(CscToolPath)" Importance="high"/>
<Message Text="$(WebProjectOutputDir)" Importance="high"/>
</Target>
There was no output for $(CscToolPath) and $(WebProjectOutputDir).
EDIT2: As a workaround i edited the app.configs of the unit tests like so:
<appSettings>
<add key="aspnet:RoslynCompilerLocation" value="_PublishedWebsites\*OneOfTheWebApps*\bin\roslyn" />
</appSettings>
The unit tests can now find the binaries and it seems that this change has no effect on my local machine. Unit tests are now passing locally and on the build server. However that cannot be the solution to this problem.