4
votes

We recently upgraded from an old CodeDomProvider to the new Roslyn CodeDomProvider called Microsoft.CodeDom.Providers.DotNetCompilerPlatform. It works fine, but it looks for the csc.exe in the wrong place. The NuGet package puts the exe in the path:

[App Path]\bin\Debug\roslyn

But, when we compile, we get this error: Could not find a part of the path '[App Path]\bin\Debug\bin\roslyn\csc.exe'.

Notice that it is looking for the exe in the wrong place. It's looking for it inside the "bin" folder which is already in the bin\Debug folder. So, in order to make our code compile, we need to move the Roslyn compiler to: [App Path]\bin\Debug\bin\roslyn\csc.exe

Is there any way to tell the CodeDomProvider where the Roslyn compiler is located? Isn't this just a straight up bug in the Roslyn compiler code?

2

2 Answers

1
votes

I'd take a look at the NuGet package Microsoft.CodeDom.Providers.DotNetCompilerPlatform.BinFix. I haven't used it but it has 10K downloads because this is a problem a lot of people have run into, I think. I ran into this problem and I remember using reflection to workaround it, here's the snippet I wrote with a reference to the Stack Overflow answer I was basing it on, where _compiler is my CSharpCodeProvider:

// Little hack here, see http://stackoverflow.com/a/40311406/1676558.
object compilerSettings = typeof(CSharpCodeProvider)
    .GetField("_compilerSettings", BindingFlags.Instance | BindingFlags.NonPublic)
    .GetValue(_compiler);
FieldInfo compilerSettingsFullPathField = compilerSettings
    .GetType()
    .GetField("_compilerFullPath", BindingFlags.Instance | BindingFlags.NonPublic);
string desiredCompilerSettingsFullPath = ((string)compilerSettingsFullPathField
    .GetValue(compilerSettings))
    .Replace(@"bin\roslyn\", @"roslyn\");
compilerSettingsFullPathField.SetValue(compilerSettings, desiredCompilerSettingsFullPath);
0
votes

Change 'Post-build event command line' in 'Build Events' tab of your project settings to:

IF EXIST $(TargetDir)roslyn\csc.exe (MKDIR $(TargetDir)bin & MOVE /Y $(TargetDir)roslyn $(TargetDir)bin\roslyn)