Cannot compile simple dynamic code after migration on .netstandard 2.0 (CodeDom throws System.PlatformNotSupportedException)
Asked Answered
J

2

18

Trying to compile this sample of code:

var c = new CSharpCodeProvider();
var cp = new CompilerParameters();
var className = $"CodeEvaler_{Guid.NewGuid().ToString("N")}";
// doesn't work with or without netstandard reference
var netstandard = Assembly.Load("netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51");
cp.ReferencedAssemblies.Add(netstandard.Location);
cp.CompilerOptions = "/t:library";
cp.GenerateInMemory = true;

var sb = new StringBuilder("");

sb.Append("namespace Jobs.Dynamic{ \n");
sb.Append($"public class {className} {{\n");
sb.Append($"public object RunSnippetCode()\n{{\n");
sb.Append("\nreturn null;\n");
sb.Append("\n}\n");
sb.Append("}");
sb.Append("}");

CompilerResults cr = c.CompileAssemblyFromSource(cp, sb.ToString());

Everything was ok before migration on .netstandard 2.0

A simple class has to be generated and it works if just copy the code and run it in Visual Studio. The class with one method that returns null. Now CompileAssemblyFromSource method throws

System.PlatformNotSupportedException: Operation is not supported on this platform. at Microsoft.CSharp.CSharpCodeGenerator.FromFileBatch(CompilerParameters options, String[] fileNames) at Microsoft.CSharp.CSharpCodeGenerator.System.CodeDom.Compiler.ICodeCompiler.CompileAssemblyFromSourceBatch(CompilerParameters options, String[] sources) at CnetContent.Jobs.DynamicCode..ctor(IEnumerable1 referencedAssemblies, IEnumerable1 usings, String methodArgs, String codeSnippet) at CnetContent.Jobs.Core.JobBase.EvalRunCondition(String& error)

I updated System.CodeDom and this library supports .netstandard 2.0, but this code still doesn't work. Could not find any cases with similar problems. Any ideas? Thank you in advance!

Jeep answered 4/4, 2018 at 15:55 Comment(8)
If something is "supported" by .NET Standard, that merely means the classes are available. They don't necessarily have a full implementation on all platforms (or even any platforms, if you're unlucky). Are you running this on Windows?Starlet
@jeroen-mostert, totally understand that implementation may be incomplete, but I am not doing anything special, just trying to compile almost empty class... Yes, I am running this on Windows.Jeep
Oh, there's also this. This may automagically slide Roslyn into the CodeDOM API, or you might consider going full Roslyn and not passing through CodeDOM at all. It's not about it being "special", it's about something having written up the necessary bindings to platform-specific assemblies -- CSharpCodeGenerator used to do creepy stuff like use a locally installed C# compiler, something which is not particularly portable (or reliable).Starlet
I've already considered changing CodeDom on Roslyn. Just last hope that someone has a very simple solution for this issue.Jeep
@AndreiBarbolin: any solution for your problem? I am facing same issue :(Actomyosin
@Amir, I replaced CodeDom with Roslyn. Roslyn gives additional information about compilation errors.Jeep
@AndreiBarbolin: my problem solved by using windows application project instead of console project. by the way thanks for your reply.Actomyosin
According to this link. These APIs no longer supported in core and .Net 5+ here is the link: learn.microsoft.com/en-us/dotnet/core/compatibility/…Solanum
N
17

I had the same problem with .NetCore 2, but with a bigger CodeDOM project. My solution I am right now building is generating the source from CodeDom and then passing it to Roslyn. (As Roslyn was mentioned in a comment, but only a .NET Framwork solution was posted)

Here is a good example how to use Roslyn - just add the

Microsoft.CodeAnalysis.CSharp NuGet package and System.Runtime.Loader NuGet package

and then use the code here (Or just follow the example): https://github.com/joelmartinez/dotnet-core-roslyn-sample/blob/master/Program.cs

Nominate answered 2/7, 2018 at 2:8 Comment(3)
This solution worked for me, the only problem is that I had to delete the CodeDOM package from the cs project and other unused packages to make it work.Kinky
Will CodeDom be supported by .Net Core one day?Backbencher
The only solution that works for me! God bless you!Moonshiner
E
3

In my case I was migrating a project from .NET Framework 4.7.2 to .NET Standard 2.0. In this project I have code to generate an assembly during runtime by using CSharpCodeProvider. Could compile the project but then during runtime my code threw an exception when generating an assembly from Dom. I got this error:

CS0012: The type 'System.Object' is defined in an assembly that is not referenced. You must add a reference to assembly 'netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'.

As a consequence the assembly was not created during runtime.

In order to fix that I have added .netstandard for the compiler as a referenced assembly like that:

var compilerParameters = new CompilerParameters();
var netstandard = Assembly.Load("netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51");
compilerParameters.ReferencedAssemblies.Add(netstandard.Location);

That did the trick for me.

Endothelioma answered 5/2, 2021 at 8:49 Comment(2)
Should have worked with "CompilerVersion", "v4.7.2" injected in CSharpCodeProvider ctor but it doesn't. Your answer works instead, thanks!!!Roman
I didn't notice my project was .NET core and had to switch to full framework. Then this worked.Modulator

© 2022 - 2024 — McMap. All rights reserved.