CodeDomProvider.CompileAssemblyFromSource - Can't Find Roslyn (csc.exe)
Asked Answered
C

2

4

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?

Cordeelia answered 15/2, 2017 at 22:2 Comment(0)
B
1

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 https://mcmap.net/q/383600/-using-c-6-features-with-codedomprovider-roslyn.
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);
Bleb answered 16/2, 2017 at 1:54 Comment(1)
Ah yes. This is hacky but it looks like it might solve the problem.Cordeelia
B
0

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)
Buck answered 16/2, 2017 at 9:52 Comment(1)
I realise that I can do this, but that's beside the point. I want to keep all my binaries in the one folder. Why is Roslyn hard coded to only work if it's in one spot?Cordeelia

© 2022 - 2024 — McMap. All rights reserved.